簡體   English   中英

為什么我必須在開始時引用組件,但聲明變量不能為空?

[英]Why do I have to reference components in start, but declare variables in no void?

c# 和 unity 的新手。 我很困惑為什么必須在不同的地方聲明變量來引用組件。 順便說一句,我按照教程來到這里。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Sheep : MonoBehaviour
{
    public float runSpeed;
    public float gotHayDestroyDelay;
    private bool hitByHay;

    public float dropDestroyDelay;
    private Collider myCollider; // variables declared here
    private Rigidbody myRigidbody; // and here

    // Start is called before the first frame update
    void Start()
    {
        myCollider = GetComponent<Collider>(); // but set here
        myRigidbody = GetComponent<Rigidbody>(); // and here
    }

    // void Update and some more things here
}

您正在定義一個類。 當您聲明一個變量時,您是在說“A Sheep具有此屬性”,但您不一定要告訴它該屬性什么或Sheep對該屬性做了什么。

在 Unity 中的Start()函數中,您正在向 MonoBehaviour(您的Sheep派生自的類;不要擔心它在早期是如何工作的)指示當對象開始存在時正確執行什么操作。 在這種情況下,您要做的第一件事是找到您的碰撞器和剛體,以便在其他函數中(例如Update() )您將知道myCollidermyRigidbody是什么。

希望這有幫助。 你說你是新來的,所以我盡力了ELI5。

這似乎是 Unity 和 C# 本身的新鮮事物的混合體。 讓我們分解一下:

遺產

編寫 Unity 腳本時,通常是在編寫 C# 類。 此類及其所有信息都包含在松鼠(花括號)“{”和“}”中。 但是這個類也可以從另一個類繼承 考慮像使用模板一樣繼承。 Monobehaviour 是一個 Unity 定義的類,它已經創建了一堆字段、屬性和方法,例如“Update()”“Start()”“gameObject”等。當您從 MonoBehaviour 繼承時,您實際上是在說“使用MonoBehaviour 模板”。

因此,即使您自己沒有編寫任何字段/方法,以下代碼已經從 MonoBehaviour 繼承中提供了許多可用的字段/方法:

public class NewScript : MonoBehaviour
{
}

班級字段

字段是您“聲明”變量時看到的內容:

float numA = 100;

正如您在上面的代碼中看到的那樣,我可以在聲明字段時為其賦值。 這個聲明在類被構造后立即發生。 在這種情況下,聲明變量的賦值會在聲明時立即發生。 如果我試圖用來自另一個類的數據聲明我的字段,而另一個類尚未構建,它就會失敗。

Unity 引擎和 MonoBehaviour

既然我們已經確定您的類在 MonoBehaviour 的“幕后”中發生了一些事情,並且類級別的字段聲明會立即發生,我們可以了解事情的實質:

以下是 Unity 程序啟動方式的簡化:

  1. 創建所有游戲對象,初始化它們的組件,並構造它們的腳本。
  2. 所有組件都運行 Awake()。
  3. 所有組件都運行 Start()。
  4. 游戲周期開始(Update、FixedUpdate、LateUpdate 等)。

請注意,某些游戲對象和組件可能會先於其他游戲對象和組件構建。 如果您嘗試在構造另一個組件之前在 GameObject 上調用 GetComponent,它將失敗。 這就是為什么在聲明字段時無法在構造函數階段調用 GetComponent 的原因。

選擇

Unity 允許在單一行為中序列化字段,在檢查器中公開它們。 您可以改為使用 [SerializeField] 標頭編寫您的字段聲明(或使您的字段可公開訪問)並將組件拖放到檢查器中:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM