【问题标题】:Lists in Unity2D - Issue AddingUnity2D 中的列表 - 添加问题
【发布时间】:2016-04-17 20:52:43
【问题描述】:

我正在尝试将一个项目添加到我的 LevelManager 脚本中的列表中。对于一个敌人,当他死后,他的尸体预制件会被添加必要的碰撞器等,以便 LevelManager 处理。

敌人的脚本是:

using UnityEngine;
using System.Collections;

public class EnemyController : MonoBehaviour {

    public Rigidbody2D rb;
    public Animator anim;
    public GameObject deadGuy;
    public LevelManager manager;

    // Use this for initialization
    void Start () {

        rb = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
        manager = GetComponent<LevelManager>();

    }

    // Update is called once per frame
    void Update () {

        if(anim.GetBool("Dead"))
        {
            StartCoroutine("Die");
        }

    }

    private IEnumerator Die()
    {
        yield return new WaitForSeconds(anim.GetCurrentAnimatorStateInfo(0).length);
        Instantiate(deadGuy, gameObject.transform.position, gameObject.transform.rotation);
        manager.worldObjects.Add(deadGuy);
        DestroyObject(gameObject);
    }
}

播放死亡动画,然后将预制件添加为层次结构中的“死人(克隆)”,然后再次播放动画并实例化更多预制件。但是,如果我删除这行代码:

manager.worldObjects.Add(deadGuy);

然后播放动画,添加预制件并删除敌人对象。

【问题讨论】:

  • 我认为您需要在更新中使用另一个 bool 才能仅启动协程一次。
  • 如果游戏对象正在被销毁,但它不应该再次运行,因为敌人脚本已附加到敌人对象。如果删除这行代码,它就可以工作: manager.worldObjects.Add(deadGuy);因此,除非将其删除,否则该行似乎阻止它到达破坏游戏对象本身的下一行

标签: unity3d unity5


【解决方案1】:

因此,似乎最好的方法是将尸体处理放到另一个脚本中并将其附加到预制件上。因此我可以实例化预制件,删除调用实例化的游戏对象,并在关卡管理器中不使用列表

【讨论】:

    【解决方案2】:

    简单的解决方案

    如 cmets 中所述;这是因为 bool Dead 被动画师设置为 true,并且 Unity 对 Update 的每次调用都会创建一个新的dead player。活着的玩家 GameObject 直到播放完死亡玩家的死亡动画后才会被销毁,并且在该动画期间会多次调用更新。

    要解决此问题,请在您的类中添加一个布尔值,例如;

    private bool m_instantiatedDeadPlayer;
    

    然后在您的更新循环中,将 if 语句更改为;

    public void Update (
    {
        if(anim.GetBool("Dead") && !m_instantiatedDeadPlayer)
        {
            m_instantiatedDeadPlayer = true;
            StartCoroutine("Die");
        }
    }
    

    复杂的解决方案

    更好但更复杂的方法是将死亡动画包含在与您的活着的敌人相同的 Animator 中,激活必要的碰撞器等,并让从当前活着的动画到死亡动画的过渡是 @ 987654321@,当敌人的生命值等于 0 时设置。这是假设你有一个附加到敌人的方法来承受伤害,看起来像这样;

    public void ApplyDamage(int p_amount)
    {
        if(!m_isDead)
        {
            m_health = Mathf.Clamp(m_health - p_amount, 0, 100);
    
            if(m_health == 0)
                m_animator.SetTrigger("Dead");
        }
    }
    

    因此,您无需使用协程,而是在生成敌人时将敌人添加到对象列表中,并且每当您需要所有死去的敌人时,都有一个方法返回附加到敌人的私有变量 m_isDead .

    希望对您有所帮助,如果您需要更多详细信息,请告诉我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多