在Unity3D游戏引擎中使用C#为我的游戏AI类构建FSM。我现在有2个简单的游戏对象,一个Cube(AI)和一个子弹(在调用函数时实例化,下面是代码)。只是为更复杂的密克罗尼西亚联邦建立基础,但是在学期的早期,所以我正在学习它。
我的AI一次投出5发子弹投射子弹,当bulletCount为5然后它会改变状态。所以基本上我只想要它射出5发子弹,等待我选择的时间,重新加载,再射5次,并继续相同的过程。基本上发生的事情完全是我想要它首先做的,一旦它退出我的IEnumerator,它就会射出无数的子弹,即使它是第一次做到我想要的。
AIClass
using UnityEngine;
using System.Collections;
public class AIClass : MonoBehaviour
{
public GameObject bullet;
int bulletCount;
float stunned;
public enum CombatAIStates
{
Firing = 0,
Stunned = 1,
Reloading = 2,
Following = 3,
Idle = 4
}
public CombatAIStates currentState = CombatAIStates.Firing;
void Update()
{
switch (currentState)
{
case CombatAIStates.Firing:
StartCoroutine (WaitMethod ());
if(bulletCount <= 5)
{
spawnBullets ();
Debug.Log ("Firing. ");
Debug.Log ("Bullet: ");
Debug.Log (bulletCount);
StartCoroutine (WaitMethod ());
++bulletCount;
}
if(bulletCount > 5)
{
currentState = CombatAIStates.Reloading;
}
break;
case CombatAIStates.Stunned:
Debug.Log ("Stunned.");
StartCoroutine(WaitMethod());
currentState = CombatAIStates.Firing;
//currentState = CombatAIStates.Firing;
break;
case CombatAIStates.Reloading:
Debug.Log ("Reloading.");
StartCoroutine (WaitMethod ());
currentState = CombatAIStates.Stunned;
break;
}
}
IEnumerator WaitMethod()
{
float waitTime = 10;
Debug.Log ("Before yield.");
yield return new WaitForSeconds (waitTime);
Debug.Log ("After yield.");
bulletCount = 0;
}
void spawnBullets()
{
Instantiate(bullet, transform.position, transform.rotation);
}
}
答案 0 :(得分:3)
我怀疑这是你要做的事情,为了简单起见略微剥离:
public int BulletCount = 0;
public enum CombatAIStates
{
Firing = 0,
Reloading = 1,
}
CombatAIStates currentState = CombatAIStates.Firing;
// Update is called once per frame
void Update () {
switch (currentState) {
case CombatAIStates.Firing:
if (BulletCount < 5) {
Debug.Log ("Firing: " + BulletCount);
++BulletCount;
} else {
currentState = CombatAIStates.Reloading;
StartCoroutine(Reload ());
}
break;
case CombatAIStates.Reloading:
// Nothing to do here, Reload() coroutine is handling things.
// Maybe play a 10 second animation here or twiddle thumbs
break;
}
}
IEnumerator Reload()
{
yield return new WaitForSeconds (10.0f);
BulletCount = 0;
//Now update the current combat state
currentState = CombatAIStates.Firing;
}
我对原始代码的改动并不多。我刚刚将状态更改为Reload
协程,在10秒后切换回Firing
并重置bulletCount
。或者,您可以在交换机的重新加载情况下进行状态更改。但是,不是调用协程只是检查是否bulletCount >= 5
,如果没有,那么重新加载完成,你可以切换回射击。