首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >单位2D: NullReferenceException。如何添加两个管理器脚本?

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

Stack Overflow用户
提问于 2017-10-27 00:04:11
回答 1查看 114关注 0票数 0

我对团结很陌生,所以请容忍我的可怕解释。我在youtube上跟随了一个关于2D战斗游戏的教程:https://www.youtube.com/watch?v=n8S3WgVoOmo&t=3319s,我将在下面提供我的代码。在链接视频中,视频制作者制作了一个PlayerManager脚本,它控制着我的播放器和我的播放器的副本。通过一个简单的人工智能,复制成为我的敌人和我们战斗。这样做的效果不出所料。

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

DamageScript连接到PlayerManager上时,当我点击AI或AI攻击我时,被击中的人就会显示伤害动画。但是在分开之后,我有两个选择,分别是AI和球员的经理。要么我打人工智能,他就会伤害动画,当他打我的时候我就会犯错误。或者他打我,我有伤害动画,当我击中他,我得到一个错误。错误是:

代码语言:javascript
运行
复制
NullReferenceException: Object reference not set to an instance of an object
DamageScript.OnTriggerEnter2D (UnityEngine.Collider2D col) (at Assets/Scripts/DamageScript.cs:19)

这是原始的DamageScript:

代码语言:javascript
运行
复制
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");
            }
        }
    }
}

这样,我的玩家做伤害动画,我得到的错误,当我击中。所以,我想像这样的东西会起作用,但我想我真的不知道怎么编码它:

代码语言:javascript
运行
复制
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");
                }
            }
        }
    }
}

不出所料,它不起作用,我仍然会在一些命中事故。如果可能的话,任何帮助都将不胜感激。谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-27 03:08:11

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

更具体地说,我认为您所遵循的教程没有正确地遵循https://en.wikipedia.org/wiki/Single_responsibility_principle,而是在单个类/文件上实现了多个职责(player和AI),以节省视频的时间或简化教程。

稍后,当将责任划分为两个脚本和两个对象时,作为初学者,您不知道引用管理中涉及的一些细节和/或缺陷,因此无法为两个对象分配引用,或者在脚本现在被拆分时没有处理丢失的引用。

之所以会出现这个问题,是因为如果您的播放器和AI现在有不同的脚本集;每个管理器都有一个脚本,但两者都没有脚本(与以前不同,当时player和AI对象都“都有”);那么,无论是在第一个或第二个if*manager.damage语句上,都不会在GetComponent中找到所讨论的管理器,因为它不在该对象中,并且在试图访问null引用上的字段/属性/方法时,将引发NullReferenceException

解决方案只是在访问这些字段/属性/方法之前执行正确的空检查,防止异常,如果发现第一个管理器是null,则继续执行第二个null语句。

尽管如此,最好还是缓存查询以使事情更好,正如RetiredNinja在注释中所建议的那样。

代码:

代码语言:javascript
运行
复制
void OnTriggerEnter2D(Collider2D col) {
    if(col.transform.root != transform.root && col.tag != "Ground" && !col.isTrigger) {
        //Cache to avoid multiple queries and to simplify access
        var playermanager = col.transform.GetComponent<PlayerManager>(); //One of these won't be found and will receive null instead
        var aiManager = col.transform.GetComponent<AIManager>(); //One of these won't be found and will receive null instead
        var animator = col.transform.root.GetComponentInChildren<Animator>();

        if (aiManager != null //Null-check was missing
          && !aiManager.damage && !aiManager.blocking) { //Much nicer
            aiManager.damage = true;
            if(animator!=null)
                animator.SetTrigger("Damage");
        }
        else {
            if (playerManager != null && !playerManager.damage) {
                playerManager.damage = true;

                animator.SetTrigger("Damage");
            }
        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46965573

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档