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

Animation Unity 2D:NullReferenceException。如何添加两个管理器脚本?,animation,unity3d,unity5,unity3d-2dtools,Animation,Unity3d,Unity5,Unity3d 2dtools,我对Unity很陌生,所以请忍受我可怕的解释。我在youtube上观看了一个关于2D格斗游戏的教程: 我将在下面提供我的代码。 在链接的视频中,视频制作者制作一个PlayerManager脚本,该脚本控制我的播放器和播放器的副本。通过一个简单的人工智能,复制品成为我的敌人,我们战斗。这与预期的一样有效 现在我想把它改成一个2D平台。我把playermanger一分为二AIManager(与教程中的代码完全相同)和一个playermanger,但有一些更改。这也很有效,我能够移动,AI也能认出我。

我对Unity很陌生,所以请忍受我可怕的解释。我在youtube上观看了一个关于2D格斗游戏的教程: 我将在下面提供我的代码。 在链接的视频中,视频制作者制作一个
PlayerManager
脚本,该脚本控制我的播放器和播放器的副本。通过一个简单的人工智能,复制品成为我的敌人,我们战斗。这与预期的一样有效

现在我想把它改成一个2D平台。我把
playermanger
一分为二
AIManager
(与教程中的代码完全相同)和一个
playermanger
,但有一些更改。这也很有效,我能够移动,AI也能认出我。问题来自一个名为DamageScript的脚本。它可以识别我是否以及何时受到伤害,并触发相关动画

DamageScript
仅连接到
playermanger
时,当我击中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)
这是最初的损坏脚本:

公共类损坏脚本:单行为{
无效OnTriggerEnter2D(碰撞的R2D列)
{
if(col.transform.root!=transform.root&&col.tag!=“地面”&&col.isTrigger)
{
如果(!col.transform.GetComponent().damage&!col.transform.GetComponent().blocking)
{
col.transform.GetComponent().damage=true;
col.transform.root.getComponentChildren().SetTrigger(“损坏”);
}
}
}
}
通过这种方式,我的播放机会制作伤害动画,当我点击时会出现错误。所以,我想这样的东西会管用,但我想我真的不知道如何编码:

void OnTriggerEnter2D(碰撞的R2D列)
{
if(col.transform.root!=transform.root&&col.tag!=“地面”&&col.isTrigger)
{
第11行如果(!col.transform.GetComponent().damage&&!col.transform.GetComponent().blocking)
{
col.transform.GetComponent().damage=true;
col.transform.root.getComponentChildren().SetTrigger(“损坏”);
}
其他的
{
如果(!col.transform.GetComponent().damage)
{
第19行col.transform.GetComponent().damage=true;
col.transform.root.getComponentChildren().SetTrigger(“损坏”);
}
}
}
}
}
毫不奇怪,它不起作用,我仍然会在一些点击中崩溃。 如有可能,我们将不胜感激。
谢谢大家!

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

更具体地说,我相信很明显,您所遵循的教程没有正确遵循,而是在单个类/文件上实现了多个职责(播放器和AI),以节省视频时间,或简化教程

后来,当将职责拆分为两个脚本和两个对象时,作为初学者,您不知道引用管理中涉及的一些细节和/或陷阱,因此无法将引用分配给这两个对象,或者无法处理缺少的引用,因为脚本现在已拆分

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

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

正如退休的德尼加在评论中所建议的那样,在这个时候,我们不妨缓存查询以使事情变得更好


代码:
void OnTriggerEnter2D(碰撞的R2D列){
if(col.transform.root!=transform.root&&col.tag!=“地面”&&col.isTrigger){
//缓存以避免多个查询并简化访问
var playermanger=col.transform.GetComponent();//其中一个将找不到,而是接收null
var aiManager=col.transform.GetComponent();//其中一个将找不到,而是接收null
var animator=col.transform.root.getComponentChildren();
如果(aiManager!=null//null检查丢失
&&!aiManager.damage&&!aiManager.blocking){//好多了
aiManager.damage=true;
if(animator!=null)
动画师。设置触发器(“损坏”);
}
否则{
if(playerManager!=null&&!playerManager.damage){
playerManager.damage=true;
动画师。设置触发器(“损坏”);
}
}
}
}

第19行是哪一行?我添加了错误行。现在取决于我是打AI还是他打我。如果我只保留原始代码,那么只有当我点击AI时才会得到错误。现在我可以用一次攻击来攻击他,然后在几秒钟内尝试一下,它通常会崩溃。如果他打我也直接撞车。我似乎无法使这两个脚本一起工作。工作起来很有魅力!我真的很感激,我绝对不会一个人做这件事,现在我知道如何处理类似的问题了。