TL;DR:为什么我只能“杀死”我的第一个敌人,而其他敌人却不受我试图关闭他们的组件的影响?
概述
嗨,伙计们和女孩们,当玩家杀死他们时,我的 AI 切换到布娃娃时遇到了问题,但更具体地说,它也没有停用任何其他组件。
基本上,我有一个通过 IEnumerators 和协程运行状态机的 AI 脚本,我还有一个 RagdollDeath 脚本,只是为了保持代码独立。
理想情况下,当玩家射击敌人时,他们会切换到布娃娃状态。
我是如何做到这一点
的除了在生命值达到 0 时关闭所有 animator、navmesh 和其他组件之外,我还使用以下方法关闭所有刚体
void IsKinematic(bool newvalue)
{
foreach (Rigidbody rb in bodyparts)
{
rb.isKinematic = newvalue;
}
}
这从动画创建了一个美丽而无缝的布娃娃过渡。
我
的问题我遇到的问题是,当我向敌人开火时,他们的表现完全符合预期,但是当我向另一个敌人开火时,它根本不会运行我的脚本,即使我可以看到它正在运行通过使用 Print("Something") 提示。我已经确保预制我的敌人并将更改应用于所述预制件。
更奇怪的是,如果我克隆 2 个敌人并射击新的敌人,第一个将变成布偶!就好像单一行为不起作用。
任何对可能导致这种情况的洞察力将不胜感激。
导致问题的完整代码
public class ZombieStateMachine : MonoBehaviour {
[SerializeField] GameObject player;
[SerializeField] GameObject los;
[SerializeField] GameObject[] waypoints;
[SerializeField] int timeBetweenWaypoints = 1;
[SerializeField] AudioSource jumpyscare;
private int health = 100;
private SuspenseAudioScript suspensescript;
private NavMeshAgent agent;
public bool canSeePlayer;
public float distanceBetween;
public string routine = "null";
private Animator animator;
public bool isAttacking = false;
private ShootScript shootscript;
private Rigidbody[] bodyparts;
private CapsuleCollider capsule;
void IsKinematic(bool newvalue)
{
foreach (Rigidbody rb in bodyparts)
{
rb.isKinematic = newvalue;
}
}
// Use this for initialization
void Start () {
shootscript = GameObject.FindGameObjectWithTag("Player").GetComponent<ShootScript>();
suspensescript = GetComponent<SuspenseAudioScript>();
animator = GetComponent<Animator>();
agent = GetComponent<NavMeshAgent>();
StartCoroutine(Eyesite());
StartCoroutine(Wander());
bodyparts = GetComponentsInChildren<Rigidbody>();
capsule = GetComponent<CapsuleCollider>();
IsKinematic(true);
}
public void KillZombie()
{
this.StopAllCoroutines();
IsKinematic(false);
animator.enabled = false;
agent.enabled = false;
capsule.enabled = false;
this.enabled = false;
}
这是随附的拍摄脚本
public class ShootScript : MonoBehaviour {
[SerializeField] public int health = 100;
[SerializeField] AudioSource gunshotsound;
[SerializeField] Light gunshotflash;
public float impactforce = 2f;
private ZombieStateMachine enemyscript;
private Rigidbody rb;
private CharacterController m_CharacterController;
private Camera cam;
private CapsuleCollider enemycol;
public UnityStandardAssets.Characters.FirstPerson.FirstPersonController fpscontrol;
// Use this for initialization
void Start () {
fpscontrol = GetComponent<UnityStandardAssets.Characters.FirstPerson.FirstPersonController>();
enemycol = GameObject.FindGameObjectWithTag("Enemy").GetComponent<CapsuleCollider>();
enemyscript = GameObject.FindGameObjectWithTag("Enemy").GetComponent<ZombieStateMachine>();
cam = GetComponentInChildren<Camera>();
rb = GetComponent<Rigidbody>();
m_CharacterController = GetComponent<CharacterController>();
}
// Update is called once per frame
void Update () {
Shoot();
}
public void Shoot()
{
if (Input.GetKeyDown(KeyCode.Mouse0))
{
Debug.DrawRay(cam.transform.position, cam.transform.forward, Color.red, 1.0f);
RaycastHit hit;
if (Physics.Raycast(cam.transform.position, cam.transform.forward, out hit, 2000f))
{
if(hit.transform.tag == "Enemy")
{
enemyscript.KillZombie();
gunshotsound.Play();
StartCoroutine(GunshotFlash());
}
else
{
gunshotsound.Play();
StartCoroutine(GunshotFlash());
print("You MIssed!");
}
}
}
}
IEnumerator GunshotFlash()
{
while (true)
{
gunshotflash.enabled = true;
yield return new WaitForSeconds(0.05f);
gunshotflash.enabled = false;
yield return new WaitForSeconds(1);
break;
}
}
public void PlayerDeath()
{
rb.AddForce(this.transform.forward * 2);
rb.isKinematic = false;
m_CharacterController.enabled = false;
fpscontrol.enabled = false;
//rb.useGravity = true;
}
}