【问题标题】:Issues with Unity's Ragdoll Character Creator, Rigidbody[] Arrays, and general code issuesUnity 的 Ragdoll Character Creator、Rigidbody[] 数组和一般代码问题
【发布时间】:2018-05-11 01:58:22
【问题描述】:

TL;DR:为什么我只能“杀死”我的第一个敌人,而其他人却不受我试图关闭他们的组件的影响?

概述

嗨,伙计们,我遇到了当玩家杀死他们时我的 AI 切换到 Ragdoll 的问题,但更具体地说,它也没有停用任何其他组件。

基本上,我有一个通过 IEnumerators 和协程运行状态机的 AI 脚本,我还有一个 RagdollDeath 脚本,只是为了保持代码独立。

理想情况下,当玩家射击敌人时,他们会切换到布娃娃状态。

我如何做到这一点

除了在生命值达到 0 时关闭所有 animator、navmesh 和其他组件外,我还使用

关闭所有刚体
void IsKinematic(bool newvalue)
{
    foreach (Rigidbody rb in bodyparts)
    {
        rb.isKinematic = newvalue;
    }
}

这会从动画中创建一个美丽而无缝的布娃娃过渡。

我的问题

我遇到的问题是,当我向敌人开火时,他们的行为完全符合预期,但是当我向另一个敌人开火时,它根本不会运行我的脚本,即使我可以看到它通过 using Print("Something") 提示。我已确保预制我的敌人并对所述预制件应用更改。

更奇怪的是,如果我克隆 2 个敌人并射击新的敌人,第一个将变成布偶!几乎就好像单一行为不起作用。

任何对可能导致此问题的原因的见解将不胜感激。

导致问题的完整代码
公共类 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;
}

}

【问题讨论】:

    标签: c# unity3d artificial-intelligence ragdoll


    【解决方案1】:

    不确定您是否遇到过此问题的解决方案,但我相信问题出在您的 Shoot 脚本启动方法中。

    enemycol = GameObject.FindGameObjectWithTag("Enemy").GetComponent<CapsuleCollider>();
    

    这样做会返回第一个带有“Enemy”标签的游戏​​对象,最好这样做:

    enemycol = GetComponent<CapsuleCollider>();
    

    可能需要对下面的行做同样的事情,enemyscript 变量:

    enemyscript = GameObject.FindGameObjectWithTag("Enemy").GetComponent<ZombieStateMachine>();
    

    改成

        enemyscript = GetComponent<ZombieStateMachine>();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-06
      相关资源
      最近更新 更多