UnityEngine.Component.GetComponent[T] () 返回 null

UnityEngine.Component.GetComponent[T] () return a null

提问人:kira 提问时间:5/8/2023 最后编辑:derHugokira 更新时间:5/10/2023 访问量:132

问:

这是我的 start 函数,我在其中初始化了类的所有属性

void Start()
    {   this._rowCount=0;
        this._ActiveSteps=new List<Steps>();
        this._inActiveSteps=new List<Steps>();
        this._row=new Vector3[5]{new Vector3(-2,-8),new Vector3(-1,-7),new Vector3(0,-6),new Vector3(1,-5),new Vector3(2,-4)};
        this._player=GameObject.Find("Player");  
        this._plyrCollider=this._player.GetComponent<CircleCollider2D>();
        this._Row=new int[4]{2,4,6,8};

       GenerateRow();
       Debug.Log(".ElementAt(0);  "+this._ActiveSteps.ElementAt(0).GetComponent<BoxCollider2D>());
    }

还使用 debug.log 进行测试,它返回一个 nullreferenceexception,但为什么 如果我们看一下 GenerateRow() 方法,我们会发现

 public void GenerateRow(){
      foreach(Vector3 pose in _row){
        Steps step=new Steps(pose,true); 
        this._ActiveSteps.Add(step);
        Steps steep=new Steps(pose,false); 
        this._inActiveSteps.Add(step);
      }
    }

我做错了什么 我迷失了希望,我没有犯一些关键的原始错误

起初,我以为是这个。关键字问题,但是在修复它并将debug.log放在GenerateRow方法之后之后,似乎没有任何变化

C# unity-game-engine nullreferenceexception

评论

0赞 TheNomad 5/9/2023
为什么到处使用?另外,在哪里添加对撞机?你打电话来搜索它,但它被添加到哪里,让你期望它在那里?另外,不应该是?或者是否将相同的步骤添加到活动和非活动列表?this.GetComponent()this._inActiveSteps.Add(step);this._inActiveSteps.Add(steep);
0赞 kira 5/9/2023
我希望“这个”不会引起一个大问题,我可以学习在 Unity 上使用 oop 的良好做法,该组件是手动添加到预制件上的,也感谢您刚才发现的陡峭的损失
0赞 TheNomad 5/9/2023
this不是问题,但它在特定情况下使用,而不是在每个功能中都发送垃圾邮件。这也来自我在许多构造函数中看到的可怕做法,但在构造函数社区中被接受,这些构造函数具有与类变量相同的参数名称并用于“修复它”。通常,当您使用类的当前实例调用函数时,应使用此函数。但正如我所说,这不是问题,除非你需要,否则不要在课堂上到处乱发垃圾邮件。this
0赞 kira 5/9/2023
有趣的是,非常感谢您提供更详细的解释,这些说明有助于将来的使用,并更好地理解我一直需要更干净和更强大的工作

答:

0赞 Tom 5/8/2023 #1

由于我不是Unity开发人员,因此我对框架的经验非常有限,因此我并不清楚发生了什么。

但是,从您的问题标题来看,它似乎是对以下问题的呼吁:

GetComponent<BoxCollider2D>()

这导致了异常 - 即我认为是您的 Steps 类/结构没有“BoxCollider2D”组件(或没有实现“BoxCollider2D”接口)。你有没有想过使用“CircleCollider2D”来代替?我可以看到你的_player领域正在使用它(我推测用于碰撞检测)。

对不起,我现在无法提供更多帮助。如果您能提供更多上下文(例如,Steps 类/结构的实现),这可能会有所帮助。

最后,我确实在您的代码中观察到了一些可能有帮助和/或感兴趣的东西。请考虑以下一些友好的建议。

  • 您有一个看似多余的_rowCount字段。考虑将其删除。集合(例如,_ActiveSteps_row)具有 CountLength 属性,这些属性将告诉您每个集合的大小。
  • 请考虑为代码中的所有内容提供更好的名称。随着应用程序的增长,命名变得越来越重要,特别是如果您不是唯一从事代码工作的开发人员;此外,在 6 个月不看代码后,您回到自己的代码,如果您这样做,将感谢您。例如,您有两个名称基本相同的字段,_row_Row;根本不清楚它们应该代表什么,或者它们之间的区别是什么(它们甚至相关吗?它们听起来像是一回事,但显然不是。此外,同样,GenerateRow 突然变得模棱两可 - 它是否对_row_Row或两者兼而有之?
  • GenerateRow 方法中,声明并初始化一个名为 steep 的变量;但是,这从未使用过。您是否打算在以下行中使用它 _inActiveSteps.Add(step);?如果是这样,如果你更恰当地命名,你可以使这些问题更容易被发现 - 像 step 变成 activeStepsteep 变成 inactiveStep 之类的东西。

我知道你可能还只是刚开始做Unity开发者(或一般的开发者),但请注意上述内容,你不仅会帮助自己,而且会在未来极大地帮助他人。

评论

0赞 TheNomad 5/9/2023
干得好!对于不使用Unity的人,您提供了非常好的建议,也可以在那里应用!
0赞 kira 5/9/2023 #2

谢谢大家的建议,我希望陡峭的变量不会让你迷路,因为这是你刚刚解决的另一个问题,甚至没有注意到,所以再次感谢。

对于主要问题,即它位于 steps 类中,我使用构造函数显然没有返回,并将不返回存储到数组中,即使程序实例化了包括碰撞器在内的所有组件,也会使活动和非活动列表为空NullReferenceExceptiongameobject

public Steps(Vector3 position,bool active){ this._position=position;
    this._step=Instantiate (Resources.Load ("Prefab/StepSet")) as GameObject;
    this._grass=_step.transform.GetChild(0).gameObject;
    this._offSet=_step.transform.GetChild(1).gameObject;
  
    this._offSet.transform.localScale=new Vector3( Random.Range(-1,1)<0?-0.6f:0.6f, Random.Range(-1,1)<0?-0.1f:0.1f,1); 
    
    this._grass.GetComponent<SpriteRenderer>().sprite=Resources.Load<Sprite>("Graphics/_World/_Grass/stepGrass-"+Random.Range(1,3));
    this._grass.transform.localScale=new Vector3( Random.Range(-1,1)<0?-0.6f:0.6f,0.1f,1);

    this._step.transform.position=this._position; 
    //this._step.transform.SetParent(this.transform, false);

}
public GameObject Step(){return this._step;}

此外,GenerateRow 方法的新版本代码是

public void GenerateRow(){
  foreach(Vector3 pose in _row){
    GameObject step=new Steps(pose,true).Step(); 
    this._ActiveSteps.Add(step);
    GameObject steep=new Steps(pose,false).Step(); 
    this._inActiveSteps.Add(steep);
  }
}

也许如果可以的话,为什么不使用它。它是否会导致任何问题,只是因为我遵循了尝试^^良好做法