Unity Ragdoll Character Creator,Rigidbody [] Arrays和一般代码问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity Ragdoll Character Creator,Rigidbody [] Arrays和一般代码问题相关的知识,希望对你有一定的参考价值。

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

概观 嗨Guys和Gals,当玩家杀死它时,我遇到了人工智能切换到Ragdoll的问题,但更具体地说,它也没有停用任何其他组件。

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

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

我是如何做到这一点的 除了在健康状态达到0时关闭所有动画师,导航器和其他组件,我还会关闭所有刚体

void IsKinematic(bool newvalue)
{
    foreach (Rigidbody rb in bodyparts)
    {
        rb.isKinematic = newvalue;
    }
}

这创造了一个美丽而无缝的布娃娃从动画过渡。

我的问题 我遇到的问题是,当我向敌人射击时,他们完全按照预期行事,但当我向另一个敌人射击时,它根本不会运行我的脚本,即使我可以看到它通过使用运行打印(“Something”)提示。我已经确保预制我的敌人并对所述预制件进行更改。 甚至更奇怪的是,如果我克隆2个敌人并射击新的敌人,那么第一个将会穿过这个级别的布娃娃!这几乎就像monobehavior不起作用。 任何可能导致这种情况的见解都将非常感激。 导致问题的完整代码 公共类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;
}

}

答案

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

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

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

enemycol = GetComponent<CapsuleCollider>();

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

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

改成

    enemyscript = GetComponent<ZombieStateMachine>();

以上是关于Unity Ragdoll Character Creator,Rigidbody [] Arrays和一般代码问题的主要内容,如果未能解决你的问题,请参考以下文章

网易大咖分享之从Unity_RagDoll系统科普到动画全部基础原理

求Unity3D的人物模型!

Unity UGUI——Text组件(Character)

Unity3d 布娃娃系统

Gym102832K. Ragdoll(CCPC长春)

Unity3.1 利用内置的3D对象创建三维模型