Unity 2D:NullReferenceException。如何添加两个管理器脚本?

时间:2017-10-27 00:04:12

标签: animation unity3d unity5 unity3d-2dtools

我对Unity很新,所以请忍受我可怕的解释。我在youtube上关于2D格斗游戏的教程:https://www.youtube.com/watch?v=n8S3WgVoOmo&t=3319s 我将在下面提供我的代码。 在链接的视频中,视频制作者制作一个PlayerManager脚本,该脚本控制我的播放器和播放器的副本。通过一个简单的AI,副本成为我的敌人,我们战斗。这很有效。

现在我想改变它有点像2D平台游戏。我拿了PlayerManager并把它分成两部分。 AIManager(与整个教程中的代码相同)和PlayerManager进行了一些更改。这也运作良好,我能够移动,AI也认识到我。问题来自一个名为DamageScript的脚本。它识别我是否以及何时受到伤害,并触发相关动画。

DamageScript仅与PlayerManager连接时,当我击中AI或AI击中我时,无论谁被击中都会显示出伤害动画。但是在我做了分手之后,有了AI和Player的独立经理,我有两种选择。无论是我打AI,他都做了动画片伤害,当他击中我时,我得到了错误。或者他打我,我有伤害动画,当我打他时我得到一个错误。错误是这样的:

NullReferenceException: Object reference not set to an instance of an object
DamageScript.OnTriggerEnter2D (UnityEngine.Collider2D col) (at Assets/Scripts/DamageScript.cs:19)

这是最初的DamageScript:

public class DamageScript : MonoBehaviour {

void OnTriggerEnter2D(Collider2D col)
    {
        if(col.transform.root != transform.root && col.tag != "Ground" && !col.isTrigger)
        {
            if (!col.transform.GetComponent<AIManager>().damage && !col.transform.GetComponent<PlayerManager>().blocking)
            {
                col.transform.GetComponent<AIManager>().damage = true;

                col.transform.root.GetComponentInChildren<Animator>().SetTrigger("Damage");
            }
        }
    }
}

这样我的玩家做了损伤动画,当我点击时我收到了错误。所以,我认为这样的东西会起作用,但我想我真的不知道如何编码它:

void OnTriggerEnter2D(Collider2D col)
    {
        if(col.transform.root != transform.root && col.tag != "Ground" && !col.isTrigger)
        {
line 11           if (!col.transform.GetComponent<AIManager>().damage && !col.transform.GetComponent<AIManager>().blocking)
            {
                col.transform.GetComponent<AIManager>().damage = true;

                col.transform.root.GetComponentInChildren<Animator>().SetTrigger("Damage");
            }
            else
            {
                if (!col.transform.GetComponent<PlayerManager>().damage)
                {
line 19        col.transform.GetComponent<PlayerManager>().damage = true;

                    col.transform.root.GetComponentInChildren<Animator>().SetTrigger("Damage");
                }
            }
        }
    }
}

毫不奇怪,它不起作用,我仍然在某些命中时崩溃。 如果可能的话,任何帮助将不胜感激。 谢谢!

1 个答案:

答案 0 :(得分:1)

从您所描述的情况来看,我将假设错误主要是由于责任委派的错误重构。

更具体地说,我相信您已经遵循的教程没有正确地遵循single responsibility principle,而是在单个上实施多个职责(播放器和AI)类/文件,以节省视频时间,或简化教程。

稍后,在将职责分为两个脚本和两个对象时,作为初学者,您不知道参考管理中涉及的某些细节和/或陷阱,因此无法为这两个对象分配引用,或者由于脚本现在被拆分,因此无法处理缺少的引用。

出现问题的原因是,如果您的播放器和AI现在有不同的脚本集;一个与每个经理,但两者都没有(不像以前,当玩家和AI对象都有“两个”);然后,在第一个或第二个if * manager.damage语句中,找不到GetComponent的相关管理器,因为它不在该对象中,并且在尝试访问字段/属性时/ null引用上的方法,NullReferenceException将被抛出。

解决方案只是在访问这些字段/属性/方法之前进行正确的空值检查,以防止异常并在第一个管理器被发现为{{1}时继续执行第二个if语句}。

在此期间,不妨缓存查询以使事情变得更好,正如RetiredNinja在评论中所建议的那样。

代码:

null