1. 게임 인공지능
GameAI
목적이 부여된 에이전트 행동
By Changhoon Park
http://wawworld.me
Last Update : 2011. 08. 28
11년 10월 14일 금요일
2. 2
목적 기반 개요 구현
에이전트 Raven의 목적 예
목적 중재
부산물
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
3. 3
목적 기반 개요 구현
에이전트 Raven의 목적 예
목적 중재
부산물
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
4. 4
목적 기반 개요 구현
에이전트 Raven의 목적 예
목적 중재
부산물
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
5. 5
목적 기반 개요 구현
에이전트 Raven의 목적 예
목적 중재
부산물
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
6. 6
목적 기반 개요 구현
에이전트 Raven의 목적 예
목적 중재
부산물
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
7. 7
목적 기반 개요 구현
에이전트 Raven의 목적 예
목적 중재
부산물
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
8. template <class entity_type>
int Goal_Composite<entity_type>::ProcessSubgoals()
{
while (!m_SubGoals.empty() &&
(m_SubGoals.front()->isComplete() || m_SubGoals.front()->hasFailed())) {
m_SubGoals.front()->Terminate();
delete m_SubGoals.front();
m_SubGoals.pop_front();
}
if (!m_SubGoals.empty()) {
int StatusOfSubGoals = m_SubGoals.front()->Process();
if (StatusOfSubGoals == completed && m_SubGoals.size() > 1) {
return active;
}
return StatusOfSubGoals;
} else {
return completed;
}
}
8
목적 기반 개요 구현
에이전트 Raven의 목적 예
목적 중재
부산물
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
9. template <class entity_type>
void Goal_Composite<entity_type>::RemoveAllSubgoals()
{
for (SubgoalList::iterator it = m_SubGoals.begin(); it != m_SubGoals.end(); ++it)
{
(*it)->Terminate();
delete *it;
}
m_SubGoals.clear();
}
9
목적 기반 개요 구현
에이전트 Raven의 목적 예
목적 중재
부산물
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
10. 10
목적 기반 개요
에이전트 Raven의 목적 예
목적 중재
부산물
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
11. class Goal_Wander : public Goal<Raven_Bot>
{
public:
Goal_Wander(Raven_Bot* pBot):Goal<Raven_Bot>(pBot, goal_wander) {}
void Activate();
int Process();
void Terminate();
};
void Goal_Wander::Activate() {
m_Status = active; m_pOwner->GetSteering()->WanderOn();
}
int Goal_Wander::Process() {
ActivateIfInactive(); return m_Status;
}
void Goal_Wander::Terminate() {
m_pOwner->GetSteering()->WanderOff();
}
11
목적 기반 개요 Goal_wander
에이전트 Raven의 목적 예 Goal_traverseEdge
Goal_followPath
목적 중재
Goal_MoveToPosition
부산물
Goal_AttackTarget
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
12. class Goal_TraverseEdge : public Goal<Raven_Bot>
{
private:
PathEdge m_Edge;
bool m_bLastEdgeInPath;
double m_dTimeExpected;
double m_dStartTime;
bool isStuck()const;
public:
Goal_TraverseEdge(Raven_Bot* pBot, PathEdge edge, bool LastEdge);
void Activate();
int Process();
void Terminate();
};
12
목적 기반 개요 Goal_wander
에이전트 Raven의 목적 예 Goal_traverseEdge
Goal_followPath
목적 중재
Goal_MoveToPosition
부산물
Goal_AttackTarget
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
13. void Goal_TraverseEdge::Activate()
{
m_Status = active;
//the edge behavior flag may specify a type of movement that necessitates a
//change in the bot's behavior as it follows this edge
switch(m_Edge.GetBehaviorFlag())
{
case NavGraphEdge::swim: {
m_pOwner->SetMaxSpeed(script->GetDouble("Bot_MaxSwimmingSpeed"));
//set appropriate animation
}
break;
case NavGraphEdge::crawl: {
m_pOwner->SetMaxSpeed(script->GetDouble("Bot_MaxCrawlingSpeed"));
//set appropriate animation
}
break;
}
13
목적 기반 개요 Goal_wander
에이전트 Raven의 목적 예 Goal_traverseEdge
Goal_followPath
목적 중재
Goal_MoveToPosition
부산물
Goal_AttackTarget
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
14. //record the time the bot starts this goal
m_dStartTime = Clock->GetCurrentTime();
m_dTimeExpected =m_pOwner->CalculateTimeToReachPosition(m_Edge.GetDestination());
static const double MarginOfError = 2.0;
m_dTimeExpected += MarginOfError;
m_pOwner->GetSteering()->SetTarget(m_Edge.GetDestination());
if (m_bLastEdgeInPath)
{
m_pOwner->GetSteering()->ArriveOn();
}
else
{
m_pOwner->GetSteering()->SeekOn();
}
}
14
목적 기반 개요 Goal_wander
에이전트 Raven의 목적 예 Goal_traverseEdge
Goal_followPath
목적 중재
Goal_MoveToPosition
부산물
Goal_AttackTarget
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
15. int Goal_TraverseEdge::Process()
{
ActivateIfInactive(); // if status is inactive, call Activate()
if (isStuck()) // if the bot has become stuck return failure
{
m_Status = failed;
}
else //if the bot has reached the end of the edge return completed
{
if (m_pOwner->isAtPosition(m_Edge.GetDestination()))
{
m_Status = completed;
}
}
return m_Status;
}
15
목적 기반 개요 Goal_wander
에이전트 Raven의 목적 예 Goal_traverseEdge
Goal_followPath
목적 중재
Goal_MoveToPosition
부산물
Goal_AttackTarget
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
16. void Goal_TraverseEdge::Terminate()
{
//turn off steering behaviors
m_pOwner->GetSteering()->SeekOff();
m_pOwner->GetSteering()->ArriveOff();
//return max speed back to normal
m_pOwner->SetMaxSpeed(script->GetDouble("Bot_MaxSpeed"));
}
16
목적 기반 개요 Goal_wander
에이전트 Raven의 목적 예 Goal_traverseEdge
Goal_followPath
목적 중재
Goal_MoveToPosition
부산물
Goal_AttackTarget
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
17. class Goal_FollowPath : public Goal_Composite<Raven_Bot>
{
private:
//a local copy of the path returned by the path planner
std::list<PathEdge> m_Path;
public:
Goal_FollowPath(Raven_Bot* pBot, std::list<PathEdge> path);
//the usual suspects
void Activate();
int Process();
void Terminate(){}
};
17
목적 기반 개요 Goal_wander
에이전트 Raven의 목적 예 Goal_traverseEdge
Goal_followPath
목적 중재
Goal_MoveToPosition
부산물
Goal_AttackTarget
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
18. void Goal_FollowPath::Activate()
{
m_iStatus = active;
PathEdge edge = m_Path.front();
m_Path.pop_front();
switch(edge.GetBehaviorFlags())
{
case NavGraphEdge::normal:
{
AddSubgoal(new Goal_TraverseEdge(m_pOwner, edge, m_Path.empty()));
}
break;
case NavGraphEdge::goes_through_door:
{
//also add a goal that is able to handle opening the door
AddSubgoal(new Goal_NegotiateDoor(m_pOwner, edge, m_Path.empty()));
}
break;
18
목적 기반 개요 Goal_wander
에이전트 Raven의 목적 예 Goal_traverseEdge
Goal_followPath
목적 중재
Goal_MoveToPosition
부산물
Goal_AttackTarget
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
19. case NavGraphEdge::jump:
{
//add subgoal to jump along the edge
}
break;
case NavGraphEdge::grapple:
{
//add subgoal to grapple along the edge
}
break;
default:
throw
std::runtime_error("<Goal_FollowPath::Activate>: Unrecognized edge type");
}
}
19
목적 기반 개요 Goal_wander
에이전트 Raven의 목적 예 Goal_traverseEdge
Goal_followPath
목적 중재
Goal_MoveToPosition
부산물
Goal_AttackTarget
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
20. int Goal_FollowPath::Process()
{
//if status is inactive, call Activate()
ActivateIfInactive();
//if there are no subgoals and there is still an edge left to traverse, add
//the edge as a subgoal
m_Status = ProcessSubgoals();
//if there are no subgoals present check to see if the path still has edges.
//if it does call Activate to grab the next edge.
if (m_Status == completed && !m_Path.empty())
{
Activate();
}
return m_Status;
}
20
목적 기반 개요 Goal_wander
에이전트 Raven의 목적 예 Goal_traverseEdge
Goal_followPath
목적 중재
Goal_MoveToPosition
부산물
Goal_AttackTarget
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
21. 21
목적 기반 개요 Goal_wander
에이전트 Raven의 목적 예 Goal_traverseEdge
Goal_followPath
목적 중재
Goal_MoveToPosition
부산물
Goal_AttackTarget
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
22. class Goal_MoveToPosition : public Goal_Composite<Raven_Bot>
{
private:
//the position the bot wants to reach
Vector2D m_vDestination;
public:
Goal_MoveToPosition(Raven_Bot* pBot, Vector2D pos);
//the usual suspects
void Activate();
int Process();
void Terminate(){}
//this goal is able to accept messages
bool HandleMessage(const Telegram& msg);
};
22
목적 기반 개요 Goal_wander
에이전트 Raven의 목적 예 Goal_traverseEdge
Goal_followPath
목적 중재
Goal_MoveToPosition
부산물
Goal_AttackTarget
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
23. void Goal_MoveToPosition::Activate()
{
m_Status = active;
//make sure the subgoal list is clear
RemoveAllSubgoals();
if (m_pOwner->GetPathPlanner()->RequestPathToTarget(m_vDestination))
{
AddSubgoal(new Goal_SeekToPosition(m_pOwner, m_vDestination));
}
}
23
목적 기반 개요 Goal_wander
에이전트 Raven의 목적 예 Goal_traverseEdge
Goal_followPath
목적 중재
Goal_MoveToPosition
부산물
Goal_AttackTarget
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
24. bool Goal_MoveToPosition::HandleMessage(const Telegram& msg)
{
//first, pass the message down the goal hierarchy
bool bHandled = ForwardMessageToFrontMostSubgoal(msg);
//if the msg was not handled, test to see if this goal can handle it
if (bHandled == false) {
switch(msg.Msg) {
case Msg_PathReady:
RemoveAllSubgoals(); //clear any existing goals
AddSubgoal(new Goal_FollowPath(m_pOwner,
m_pOwner->GetPathPlanner()->GetPath()));
return true; //msg handled
case Msg_NoPathAvailable:
m_Status = failed;
return true; //msg handled
default: return false;
}
}
return true; //handled by subgoals
}
24
목적 기반 개요 Goal_wander
에이전트 Raven의 목적 예 Goal_traverseEdge
Goal_followPath
목적 중재
Goal_MoveToPosition
부산물
Goal_AttackTarget
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
25. int Goal_MoveToPosition::Process()
{
//if status is inactive, call Activate() and set status to active
ActivateIfInactive();
//process the subgoals
m_Status = ProcessSubgoals();
//if any of the subgoals have failed then this goal replans
ReactivateIfFailed();
return m_Status;
}
25
목적 기반 개요 Goal_wander
에이전트 Raven의 목적 예 Goal_traverseEdge
Goal_followPath
목적 중재
Goal_MoveToPosition
부산물
Goal_AttackTarget
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
26. class Goal_AttackTarget : public Goal_Composite<Raven_Bot>
{
public:
Goal_AttackTarget(Raven_Bot* pOwner);
void Activate();
int Process();
void Terminate(){m_iStatus = completed;}
};
26
목적 기반 개요 Goal_wander
에이전트 Raven의 목적 예 Goal_traverseEdge
Goal_followPath
목적 중재
Goal_MoveToPosition
부산물
Goal_AttackTarget
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
27. void Goal_AttackTarget::Activate()
{
m_iStatus = active;
RemoveAllSubgoals();
if (!m_pOwner->GetTargetSys()->isTargetPresent()) {
m_iStatus = completed;
return;
}
if (m_pOwner->GetTargetSys()->isTargetShootable()) {
Vector2D dummy;
if (m_pOwner->canStepLeft(dummy) || m_pOwner->canStepRight(dummy)) {
AddSubgoal(new Goal_DodgeSideToSide(m_pOwner));
} else {
AddSubgoal(new Goal_SeekToPosition(m_pOwner, m_pOwner->GetTargetBot()->Pos()));
}
} else {
AddSubgoal(new Goal_HuntTarget(m_pOwner));
}
}
27
목적 기반 개요 Goal_wander
에이전트 Raven의 목적 예 Goal_traverseEdge
Goal_followPath
목적 중재
Goal_MoveToPosition
부산물
Goal_AttackTarget
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
28. int Goal_AttackTarget::Process()
{
//if status is inactive, call Activate()
ActivateIfInactive();
//process the subgoals
m_iStatus = ProcessSubgoals();
ReactivateIfFailed();
return m_iStatus;
}
28
목적 기반 개요 Goal_wander
에이전트 Raven의 목적 예 Goal_traverseEdge
Goal_followPath
목적 중재
Goal_MoveToPosition
부산물
Goal_AttackTarget
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
29. 29
목적 기반 개요
에이전트 Raven의 목적 예
목적 중재
부산물
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
30. 30
목적 기반 개요
에이전트 Raven의 목적 예
목적 중재
부산물
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
31. class Raven_Feature
{
public:
static double Health(Raven_Bot* pBot);
static double DistanceToItem(Raven_Bot* pBot, int ItemType);
static double IndividualWeaponStrength(Raven_Bot* pBot, int WeaponType);
static double TotalWeaponStrength(Raven_Bot* pBot);
};
31
목적 기반 개요
에이전트 Raven의 목적 예
목적 중재
부산물
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
32. 32
건강 아이템 착기
목적 기반 개요
무기 찾기
에이전트 Raven의 목적 예
목표 공격
목적 중재
맵 탐험
부산물
모두 통합 By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
33. double GetHealthGoal_Evaluator::CalculateDesirability(Raven_Bot* pBot)
{
double Distance = Raven_Feature::DistanceToItem(pBot, type_health);
if (Distance == 1) {
return 0;
} else {
const double Tweaker = 0.2;
double Desirability = Tweaker * (1-Raven_Feature::Health(pBot)) /
(Raven_Feature::DistanceToItem(pBot, type_health));
Clamp(Desirability, 0, 1);
return Desirability;
}
}
33
건강 아이템 착기
목적 기반 개요
무기 찾기
에이전트 Raven의 목적 예
목표 공격
목적 중재
맵 탐험
부산물
모두 통합 By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
34. 34
건강 아이템 착기
목적 기반 개요
무기 찾기
에이전트 Raven의 목적 예
목표 공격
목적 중재
맵 탐험
부산물
모두 통합 By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
35. double GetWeaponGoal_Evaluator::CalculateDesirability(Raven_Bot* pBot)
{
double Distance = Raven_Feature::DistanceToItem(pBot, m_iWeaponType);
if (Distance == 1) {
return 0;
} else {
//value used to tweak the desirability
const double Tweaker = 0.15f;
double Health, WeaponStrength;
Health = Raven_Feature::Health(pBot);
WeaponStrength = Raven_Feature::IndividualWeaponStrength(pBot, m_iWeaponType);
double Desirability = (Tweaker * Health * (1-WeaponStrength)) / Distance;
//ensure the value is in the range 0 to 1
Clamp(Desirability, 0, 1);
return Desirability;
}
}
35
건강 아이템 착기
목적 기반 개요
무기 찾기
에이전트 Raven의 목적 예
목표 공격
목적 중재
맵 탐험
부산물
모두 통합 By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
36. 36
건강 아이템 착기
목적 기반 개요
무기 찾기
에이전트 Raven의 목적 예
목표 공격
목적 중재
맵 탐험
부산물
모두 통합 By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
37. double AttackTargetGoal_Evaluator::CalculateDesirability(Raven_Bot* pBot)
{
double Desirability = 0.0;
//only do the calculation if there is a target present
if (pBot->GetTargetSys()->isTargetPresent())
{
const double Tweaker = 1.0;
Desirability = Tweaker *
Raven_Feature::Health(pBot) *
Raven_Feature::TotalWeaponStrength(pBot);
}
return Desirability;
}
37
건강 아이템 착기
목적 기반 개요
무기 찾기
에이전트 Raven의 목적 예
목표 공격
목적 중재
맵 탐험
부산물
모두 통합 By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
39. void Goal_Think::Arbitrate()
{
double best = 0;
Goal_Evaluator* MostDesirable = NULL;
//iterate through all the evaluators to see which produces the highest score
GoalEvaluators::iterator curDes = m_Evaluators.begin();
for (curDes; curDes != m_Evaluators.end(); ++curDes) {
double desirabilty = (*curDes)->CalculateDesirability(m_pOwner);
if (desirabilty >= best) {
best = desirabilty;
MostDesirable = *curDes;
}
}
MostDesirable->SetGoal(m_pOwner);
}
39
건강 아이템 착기
목적 기반 개요
무기 찾기
에이전트 Raven의 목적 예
목표 공격
목적 중재
맵 탐험
부산물
모두 통합 By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
40. class Goal_Evaluator
{
protected:
//when the desirability score for a goal has been evaluated it is multiplied
//by this value. It can be used to create bots with preferences based upon
//their personality
double m_dCharacterBias;
public:
Goal_Evaluator(double CharacterBias):m_dCharacterBias(CharacterBias){}
/* EXTRANEOUS DETAIL OMITTED */
};
40
목적 기반 개요 개성
에이전트 Raven의 목적 예 상태 메모리
목적 중재 명령 큐잉
부산물 스크립트 행동 큐
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
41. double AttackTargetGoal_Evaluator::CalculateDesirability(Raven_Bot* pBot)
{
double Desirability = 0.0;
//only do the calculation if there is a target present
if (pBot->GetTargetSys()->isTargetPresent())
{
const double Tweaker = 1.0;
Desirability = Tweaker *
Raven_Feature::Health(pBot) *
Raven_Feature::TotalWeaponStrength(pBot);
//bias the value according to the personality of the bot
Desirability *= m_dCharacterBias;
}
return Desirability;
}
41
목적 기반 개요 개성
에이전트 Raven의 목적 예 상태 메모리
목적 중재 명령 큐잉
부산물 스크립트 행동 큐
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
42. //these biases could be loaded in from a script on a per bot basis
//but for now we'll just give them some random values
const double LowRangeOfBias = 0.5;
const double HighRangeOfBias = 1.5;
double HealthBias = RandInRange(LowRangeOfBias, HighRangeOfBias);
double ShotgunBias = RandInRange(LowRangeOfBias, HighRangeOfBias);
double RocketLauncherBias = RandInRange(LowRangeOfBias, HighRangeOfBias);
double RailgunBias = RandInRange(LowRangeOfBias, HighRangeOfBias);
double ExploreBias = RandInRange(LowRangeOfBias, HighRangeOfBias);
double AttackBias = RandInRange(LowRangeOfBias, HighRangeOfBias);
//create the evaluator objects
m_Evaluators.push_back(new GetHealthGoal_Evaluator(HealthBias));
m_Evaluators.push_back(new ExploreGoal_Evaluator(ExploreBias));
m_Evaluators.push_back(new AttackTargetGoal_Evaluator(AttackBias));
m_Evaluators.push_back(new GetWeaponGoal_Evaluator(ShotgunBias, type_shotgun));
m_Evaluators.push_back(new GetWeaponGoal_Evaluator(RailgunBias, type_rail_gun));
m_Evaluators.push_back(new GetWeaponGoal_Evaluator(RocketLauncherBias,
type_rocket_launcher));
42
목적 기반 개요 개성
에이전트 Raven의 목적 예 상태 메모리
목적 중재 명령 큐잉
부산물 스크립트 행동 큐
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
43. 43
목적 기반 개요 개성
에이전트 Raven의 목적 예 상태 메모리
목적 중재 명령 큐잉
부산물 스크립트 행동 큐
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
44. 44
목적 기반 개요 개성
에이전트 Raven의 목적 예 상태 메모리
목적 중재 명령 큐잉
부산물 스크립트 행동 큐
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
45. void Goal_FollowPath::Activate()
{
//get a reference to the next edge
const PathEdge& edge = m_Path.front();
switch(edge.GetBehaviorFlags())
{
case NavGraphEdge::goes_through_door:
{
//add a goal that is able to handle opening the door
AddSubgoal(new Goal_NegotiateDoor(m_pOwner, edge));
}
break;
//etc
45
목적 기반 개요 개성
에이전트 Raven의 목적 예 상태 메모리
목적 중재 명령 큐잉
부산물 스크립트 행동 큐
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
46. 46
목적 기반 개요 개성
에이전트 Raven의 목적 예 상태 메모리
목적 중재 명령 큐잉
부산물 스크립트 행동 큐
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
47. void Goal_NegotiateDoor::Activate()
{
m_iStatus = active;
RemoveAllSubgoals();
Vector2D posSw = m_pOwner->GetWorld()->GetPosOfClosestSwitch(
m_pOwner->Pos(), m_PathEdge.GetDoorID());
AddSubgoal(new Goal_TraverseEdge(m_pOwner, m_PathEdge));
AddSubgoal(new Goal_MoveToPosition(m_pOwner, m_PathEdge.GetSource()));
AddSubgoal(new Goal_MoveToPosition(m_pOwner, posSw));
}
47
목적 기반 개요 개성
에이전트 Raven의 목적 예 상태 메모리
목적 중재 명령 큐잉
부산물 스크립트 행동 큐
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
48. 48
목적 기반 개요 개성
에이전트 Raven의 목적 예 상태 메모리
목적 중재 명령 큐잉
부산물 스크립트 행동 큐
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
49. 49
목적 기반 개요 개성
에이전트 Raven의 목적 예 상태 메모리
목적 중재 명령 큐잉
부산물 스크립트 행동 큐
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일
50. function AddGenieTourGuide(LampPos, TunnelPos, Player)
--create an instance of a genie at the position of the lamp
genie = CreateGenie(LampPos)
--first welcome the player, text stays on screen for 2 seconds
genie:SayPhrase("Welcome oh great "..Player:GetName().. "!", 2)
--order the player to follow the genie. text stays on screen for
--3 seconds
genie:SayPhrase("Follow me for your three wishes", 3)
--lead the player to the tunnel entrance
genie:LeadPlayerToPosition(Player, TunnelPos)
--vanish
genie:VanishInPuffOfSmoke
end
50
목적 기반 개요 개성
에이전트 Raven의 목적 예 상태 메모리
목적 중재 명령 큐잉
부산물 스크립트 행동 큐
By Changhoon Park
http://wawworld.me
11년 10월 14일 금요일