Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么我必须在start中引用组件,但在no void中声明变量?_C#_Unity3d - Fatal编程技术网

C# 为什么我必须在start中引用组件,但在no void中声明变量?

C# 为什么我必须在start中引用组件,但在no void中声明变量?,c#,unity3d,C#,Unity3d,c#和unity的新成员。我不明白为什么必须在引用组件的不同位置声明变量。顺便说一句,我是跟着来的 使用系统集合; 使用System.Collections.Generic; 使用UnityEngine; 公羊:单一行为 { 公众浮标运行速度; 公共交通延误; 二等兵布尔·希比海; 公共交通延误; 私有碰撞器myCollider;//此处声明的变量 私有刚体;//在这里 //在第一帧更新之前调用Start void Start() { myCollider=GetComponent();//但在

c#和unity的新成员。我不明白为什么必须在引用组件的不同位置声明变量。顺便说一句,我是跟着来的

使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
公羊:单一行为
{
公众浮标运行速度;
公共交通延误;
二等兵布尔·希比海;
公共交通延误;
私有碰撞器myCollider;//此处声明的变量
私有刚体;//在这里
//在第一帧更新之前调用Start
void Start()
{
myCollider=GetComponent();//但在此处设置
myRigidbody=GetComponent();//这里
}
//这里有一些更新和其他东西
}

您正在定义一个类。当您声明变量时,您说的是“a
Sheep
具有此属性”,但您不一定告诉它该属性是什么,或者
Sheep
对该属性做了什么

在Unity中的
Start()
函数中,您正在为MonoBehavior(您的
Sheep
派生自的类;不要太担心早期的工作原理)提供指示,说明在对象开始存在时如何正确操作。在本例中,您要做的第一件事是找到碰撞器和刚体,以便在其他函数中(
Update()
)您将知道MyAllider和
myRigidbody
是什么


希望这能有所帮助。你说你是新来的,所以我尽了最大的努力去做。这似乎是新与统一以及C#本身的混合体。让我们把它分解一下:

遗产 编写Unity脚本时,通常是在编写C#类。此类及其所有信息都包含在松鼠状(卷曲)大括号“{”和“}”中。但是,该类也可以从另一个类继承。考虑像使用模板一样继承。MonoBehavior是一个统一定义的类,它有一系列已经创建的字段、属性和方法,比如“Update()”“Start()”“gameObject”,等等。当您从MonoBehavior继承时,实际上是说“使用MonoBehavior模板”

因此,下面的代码已经有很多字段/方法可用于MonoBehavior继承,即使您自己还没有编写任何字段/方法:

public class NewScript : MonoBehaviour
{
}
类级别字段 字段是“声明”变量时看到的内容:

float numA = 100;
正如您在上面的代码中所看到的,我可以在声明字段时为其赋值。一旦类被构造,这个声明就会发生。在这种情况下,声明变量的赋值在声明时立即发生。如果我试图用另一个类的数据声明我的字段,而另一个类还没有被构造,它将失败

统一引擎与单一行为 现在,我们已经确定,您的类在MonoBehavior的“掩护下”发生了一些事情,并且类级别的字段声明会立即发生,现在我们可以开始讨论问题的实质:

以下是Unity计划启动方式的简化:

  • 创建所有游戏对象,初始化其组件,并构建其脚本
  • 所有组件都运行away()
  • 所有组件都运行Start()
  • 游戏周期开始(更新、固定更新、最新更新等)
  • 请注意,一些游戏对象和组件可能是先构建的。如果您试图在构建另一个组件之前调用游戏对象上的GetComponent,它将失败。这就是为什么在声明字段时,不能在构造函数阶段调用GetComponent

    可供替代的 Unity允许在MonoBehavior中序列化字段,并在inspector中公开它们。您可以改为使用[SerializeField]标题编写字段声明(或使字段公开可访问),并在inspector中将组件拖放到其中:

        [SerializeField] private Collider myCollider; // variables declared here
        [SerializeField] private Rigidbody myRigidbody; 
    

    通过将它们定义为字段,您可以在类的所有实例(非静态)方法中使用它们。为了在整个类中访问这些变量,您需要将它们限定到类中,不仅仅是
    Start
    -方法。@HimBromBeere那么为什么我不能在创建变量的地方执行
    GetComponent
    呢?含糊不清的回答:在定义(私有碰撞器myCollider)中,你不能说它的值是GetComponent,因为GetComponent需要一个对象来处理,但当定义被读取时,它还没有被创建。但是在其声明(myCollider=GetComponent)中,该对象存在并且unity场景已启动。您不能在类级别调用
    GetComponent
    ,因为在C#中不允许这样做。所有可执行代码必须位于C#中的方法内。