게임에서 대화 트리 시스템을 구현하는 가장 좋은 방법은 무엇입니까? NPC가 플레이어에게 다양한 응답 세트를 제공하기를 원합니다. 일부는 플레이어에 아이템이 있거나 이전 이벤트가 발생한 경우에만 나타날 수 있습니다.
게임에서 대화 트리 시스템을 구현하는 가장 좋은 방법은 무엇입니까? NPC가 플레이어에게 다양한 응답 세트를 제공하기를 원합니다. 일부는 플레이어에 아이템이 있거나 이전 이벤트가 발생한 경우에만 나타날 수 있습니다.
답변:
대화 상자 트리는 XML을 사용하여 수행해야합니다. 좀 더 복잡한 작업을 수행해야하는 경우 스크립트 파일을 참조하여 응답 및 응답 조건을 중첩 된 트리에 저장합니다.
특히 톤이 많은 대화가있는 RPG를 구성하는 경우 스크립트와 대화 상자를 별도로 유지해야합니다. 그런 다음 simpleXML과 같은 라이브러리를 사용하여 XML 파일을 읽을 수 있습니다.
예를 들어 SO와 비슷한 질문이 있습니다 : https://stackoverflow.com/questions/372915/game-logic-in-xml-files
루아 또는 루비와 같은 스크립팅 언어를 포함하고 그 안에 대화 대화 상자를 코딩하는 방법을 살펴볼 것입니다.
따라서 대화 스크립트는 다음과 같습니다.
switch showDialog "Why don't you just leave me along!", "Okay", "But I found your dog!"
case 1:
showDialog "And stay gone!"
case 2:
if playerHasObject "dog"
showDialog "Thank you!"
else
showDialog "Liar!"
이것은 또한 AI 및 런타임 동안 조정하는 데 유용한 기타 간단한 것들을 코딩하는 데 효과적입니다. 디버그 (또는 이스터 에그)로 실행할 때 호출 할 수있는 편집기를 응용 프로그램에 내장 할 수도 있습니다.
Stendhal 게임에서는 유한 상태 머신을 사용하여 NPC를 구현합니다.
다음 다이어그램은 퀘스트 작성 방법 튜토리얼 의 작은 예를 보여줍니다 .
처음에 NPC는 유휴 상태이며 걸어 다닐 수 있습니다. 플레이어는 "hi"라고 말하여 대화를 시작할 수 있으며 NPC는 ATTENDING 상태로 이동합니다. 이 상태에서는 그의 "직업"에 관한 질문에 대답하고 일부 게임 "도움말"을 제공합니다. 플레이어는 퀘스트를 요청할 수 있으며 NPC는 QUEST_OFFERED 상태로 이동하여 플레이어가 수락 ( "yes")하거나 거부 ( "no")하기를 기다립니다.
전환에 첨부 할 수있는 조건 세트를 정의했습니다 . 예를 들어 퀘스트 완료는 PlayerHasItemWithHimCondition 이 충족 된 경우에만 가능합니다 .
전환이 실행 된 후 NPC는 일부 텍스트를 말하거나 동작을 실행할 수 있습니다. 조건과 유사하게 플레이어에게 퀘스트 보상을주는 데 사용되는 EquipItemAction 과 같은 재사용 가능한 액션 세트를 정의했습니다 .
AndCondition , OrCondition 및 NotCondition을 사용하여 여러 조건을 결합 할 수 있습니다 . 일반적으로 퀘스트 완료시 수행해야 할 작업이 많으므로 MultipleActions 클래스도 있습니다.
Stendhal의 실제 구현은 다른 (인간) 언어로 쉽게 번역 할 수 없기 때문에 일반적인 개념이 좋습니다.
번역을 추가하려고해도 위에서 언급 한대로 논리에 XML을 사용할 수 있다고 생각합니다 . 이러한 유형의 복잡성을 경험할 때는 자체 대화 도구를 작성해야합니다. 대화 텍스트는 표시하려는 언어에 따라 바꿀 수있는 데이터베이스의 키로 저장됩니다.
예를 들어 다음을 수행 할 수 있습니다.
<dialogue id="101" condition="!npc.carsFixed">
<message>Localize.FixMyCar</message>
<choices>
<choice condition="hero.carFixingSkill > 5" priority="7" id="Localize.Sure">
<command>hero.carFixingSkills += 1</command>
<command>npc.carFixed = true</command>
<command>hero.playSmokeAnimation()</command>
<command>nextDialogue = 104</command>
</choice>
<choice condition="hero.carFixingSkill <= 5" id="Localize.CantFix">
<command>nextDialogue = 105</command>
</choice>
<choice id="Localize.FixYourself">
<command>npc.likesHero -= 1</command>
</choice>
</choices>
</dialogue>
그런 다음 퀘스트 텍스트 렌더러가 "Localize.FixMyCar"를 적절하게 번역 된 텍스트로 바꿉니다.
도구는 플레이어가 편집 가능한 원시 XML과 함께 선택 가능한 언어로 볼 수있는 것을 표시합니다.
마찬가지로 참조한 예제 에서 다음과 같은 것을 사용할 수 있습니다 .
npc.add(ConversationStates.ATTENDING,
ConversationPhrases.QUEST_MESSAGES,
null,
ConversationStates.QUEST_OFFERED,
Localization[ "BringMeABeer" ],
null);
키가 충분히 서술 적이라면 완전한 텍스트를 가지고 있지 않아도 문제가되지 않습니다.
이와 같은 것도 유용 할 수 있습니다.
Localization[ "<Location>.<NPC_name>.<Dialogue_text_key>" ];
LUA 스크립트 또는 XML 파일을 사용하여 캐릭터를 데이터로 구동하십시오. NPC와 상호 작용할 때 NPC에 첨부 된 파일을 가져 와서 읽은 다음 트리거 된 게임 변수를 조정하고 유효한 응답을 생성하십시오.
이 방법을 통해 얻을 수있는 가장 큰 장점은 대화 상자를 쉽게 조작하고 새 문자를 추가하는 등의 작업을 수행 할 수 있다는 것입니다. 또한 모든 경우를 처리 할 때 특별한 로직을 사용하여 코드베이스를 정리하지 않아도됩니다.
매우 깊은 대화 상자 트리가 있으면 ChatMapper를 사용 하십시오 . 그들은 완전한 기능을 갖춘 무료 버전을 가지고 있으며 도구를 사용하면 대화 상자 트리를 XML로 내보낼 수 있습니다. 나는 그것을 사용하고 있으며 복잡한 대화 상자 트리를 시각화하고 구성하는 훌륭한 방법입니다.
간단한 오토 마톤이 할 수있는 일 :
(dialogueline_id, condition) -> (next_id, response)
다음과 같이 보일 수 있습니다.
(1, troll is hungry?) -> (2, say "troll be hungry")
(2, player has bananas?) -> (3, say "hey, you have bananas!")
(3, ) -> (-1, (say "i like bananas, i take them and eat, you may pass, bye", remove bananas, feed the troll))
(2, player does not have bananas?) -> (-1, say "go away!!!")
게임에서 당신은 아이디를 찾고 아이디와 조건을 일치 시키려고 노력합니다.
조건과 조치를 모델링해야합니다. 객체, 함수 포인터, XML ...
좋은 대화 편집기도 편리 할 것입니다.