C# 生物AI的触发和动作
尽管我的人工智能在工作(大部分情况下),但我觉得我设置它的方式非常低效,可能犯了一些编程错误。我想把它重写得更干净、更高效、更易于维护,但我不确定从哪里开始 在我的生物AI中,我有一个触发器列表,如OnSpawn、OnDath或OnCollisionCenter。在每个触发器中都有一个动作列表,例如“施放法术”或“播放动画”。当触发器的条件满足时,将处理其操作列表,以检查它是否不在我们的处理列表中,添加它,然后播放它们的关联操作。当触发器的条件不满足时,操作列表将从此进程列表中删除,类似地,进程将通过一些删除函数来清理行为 我简化了一些代码:C# 生物AI的触发和动作,c#,unity3d,artificial-intelligence,C#,Unity3d,Artificial Intelligence,尽管我的人工智能在工作(大部分情况下),但我觉得我设置它的方式非常低效,可能犯了一些编程错误。我想把它重写得更干净、更高效、更易于维护,但我不确定从哪里开始 在我的生物AI中,我有一个触发器列表,如OnSpawn、OnDath或OnCollisionCenter。在每个触发器中都有一个动作列表,例如“施放法术”或“播放动画”。当触发器的条件满足时,将处理其操作列表,以检查它是否不在我们的处理列表中,添加它,然后播放它们的关联操作。当触发器的条件不满足时,操作列表将从此进程列表中删除,类似地,进程
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;
}
}
}
void Update()
{
如果(CANCT&!死)
{
检查触发器();
PlayAllActions();
}
}
私有void CheckTriggers()
{
for(int i=0;iitem==actionSetList);
if(containsItem)
返回;
existingActionsList.Add(actionSetList);
}
私人无效PlayalActions()
{
如果(existingActionsList.Count>0)
for(int i=0;i
我能做些什么来构建一个更高效的生物AI?我可能会用它来编写一个类似的系统 委托在某种程度上可以被视为一个包含方法列表的变量。如果执行该委托,则执行它包含的所有方法 这将允许您将这样的方法添加到方法列表中,然后在需要时调用这些方法
delegate void OnSpawn(GameObject gameObject); //Create delegate type
public OnSpawn onSpawn; //Create variable from delegate type
void SetUpStats(Gameobject gameObject){
//Set hp, initialize spells
}
void SetUpAnimations(GameObject gameObject){
//Initialize animations
}
void PlaySpawnSound(GameObject gameObject){
//Play a spawn sound
}
void Start(){
if (onSpawn == null) //Add content to delegate
{
onSpawn = new OnSpawn(SetUpStats); //You may be able to write onSpawn = SetUpStats; instead, for shorter code. But please test it.
onSpawn += SetUpAnimations;
onSpawn += PlaySpawnSound;
}
}
void Spawn(){
onSpawn(gameObject);
//Call delegate, invoking all methods stored in it.
//Note that they all receive the same input. In this case the gameObject.
//You can give them any input you want, so long as you define it in the delegate type.
//I chose a gameObject as you can get all components and more from it.
}
如果您有任何疑问或疑问,请告诉我。我可能会使用编写类似的系统 委托在某种程度上可以被视为一个包含方法列表的变量。如果执行该委托,则执行它包含的所有方法 这将允许您将这样的方法添加到方法列表中,然后在需要时调用这些方法
delegate void OnSpawn(GameObject gameObject); //Create delegate type
public OnSpawn onSpawn; //Create variable from delegate type
void SetUpStats(Gameobject gameObject){
//Set hp, initialize spells
}
void SetUpAnimations(GameObject gameObject){
//Initialize animations
}
void PlaySpawnSound(GameObject gameObject){
//Play a spawn sound
}
void Start(){
if (onSpawn == null) //Add content to delegate
{
onSpawn = new OnSpawn(SetUpStats); //You may be able to write onSpawn = SetUpStats; instead, for shorter code. But please test it.
onSpawn += SetUpAnimations;
onSpawn += PlaySpawnSound;
}
}
void Spawn(){
onSpawn(gameObject);
//Call delegate, invoking all methods stored in it.
//Note that they all receive the same input. In this case the gameObject.
//You can give them any input you want, so long as you define it in the delegate type.
//I chose a gameObject as you can get all components and more from it.
}
如果您有任何问题或疑问,请告诉我。这个不完整(非功能性)的示例很难提出任何建议。什么是“更高效”对你来说?是什么样的游戏引擎驱动的?这听起来像是一个在基于周期的游戏中运行的简单事件驱动AI,但你还没有足够详细地说明问题。你当前的操作队列中有什么不起作用?在大多数应用程序中,队列处理时间很短。也就是说,这是不完整的(非功能性的)例如,很难提出任何建议。什么是“更有效的”对你来说?是什么样的游戏引擎驱动的?这听起来像是一个在基于周期的游戏中运行的简单事件驱动的AI,但你还没有足够详细地说明问题。你当前的操作队列中有什么不起作用?在大多数应用程序中,队列处理时间微不足道。