【发布时间】:2019-05-15 03:21:56
【问题描述】:
尽管我的生物 AI 工作(大部分情况下),但我觉得我设置它的方式非常低效,并且可能犯了一些编程罪。我想重写它以使其更干净、更高效且更易于维护,但我不确定从哪里开始。
在我的生物 AI 中,我有一个触发器列表,例如 OnSpawn、OnDeath 或 OnCollisionEnter。每个触发器中都有一个动作列表,例如“施放咒语”或“播放动画”。当触发器的条件满足时,它的动作列表被处理以检查它是否已经在我们的处理列表中,添加它,然后播放它们的关联动作。当触发器的条件不满足时,动作列表会从这个进程列表中移除,同样通过一些移除函数来清理行为。
我已经简化的一些代码:
void Update()
{
if (canAct && !dead)
{
CheckTriggers();
PlayAllActions();
}
}
private void CheckTriggers()
{
for (int i = 0; i < actions.Length; i++)
{
switch (actions[i].trigger)
{
case ActionTrigger.Trigger.OnCollisionEnter:
if (isColliding)
AddActionList(actions[i].actionSetList);
else
RemoveActionList(actions[i].actionSetList);
break;
case ActionTrigger.Trigger.UponBeingAttacked:
if (hasBeenAttacked)
AddActionList(actions[i].actionSetList);
break;
}
}
}
public void AddActionList(ActionSetList actionSetList)
{
bool containsItem = existingActionsList.Any(item => item == actionSetList);
if (containsItem)
return;
existingActionsList.Add(actionSetList);
}
private void PlayAllActions()
{
if (existingActionsList.Count > 0)
for (int i = 0; i < existingActionsList.Count; i++)
ActionPlayEffect(existingActionsList[i]);
}
public void ActionPlayEffect(ActionSetList actionSetList)
{
for (int i = 0; i < actionSetList.Length; i++)
{
switch (actionSetList[i].type)
{
case ActionSet.Type.CastSpell:
if (spellRoutine == null && actionSetList[i].cooldownTimeRemaining <= 0)
spellRoutine = StartCoroutine(Cast(actionSetList[i]));
break;
case ActionSet.Type.PlayAnim:
if (!isInActionPose)
{
animator.SetTrigger("ActionTrigger");
animator.SetInteger("Action", (int)actionSetList[i].animToPlay+1);
isInActionPose = true;
}
break;
}
}
}
public void RemoveActionList(ActionSetList actionSetList)
{
bool containsItem = existingActionsList.Any(item => item == actionSetList);
if (containsItem)
{
ActionRemoveEffect(actionSetList);
existingActionsList.Remove(actionSetList);
}
}
public void ActionRemoveEffect(ActionSetList actionSetList)
{
for (int i = 0; i < actionSetList.Length; i++)
{
switch (actionSetList[i].type)
{
case ActionSet.Type.CastSpell:
CancelCast();
break;
case ActionSet.Type.PlayAnim:
animator.SetTrigger("ActionTrigger");
animator.SetInteger("Action", 0);
isInActionPose = false;
break;
}
}
}
我可以做些什么来构建更高效的生物 AI?
【问题讨论】:
-
看到这个不完整(非功能性)的例子,很难提出任何建议。什么对你来说“更有效率”?什么样的游戏引擎驱动这个?这听起来就像是在基于循环的游戏中运行的简单的事件驱动 AI,但您没有详细说明问题。什么不适用于您当前的操作队列?在大多数应用程序中,队列处理时间是微不足道的。
标签: c# unity3d artificial-intelligence