亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何檢查 Unity Inspector 空參數和不正確值的腳本

如何檢查 Unity Inspector 空參數和不正確值的腳本

C#
Smart貓小萌 2023-04-16 10:01:14
我試圖讓我的 Unity 游戲代碼盡可能健壯,理想情況下我希望能夠在游戲啟動之前拋出異常,例如在編譯時,如果 Unity Inspector 參數丟失或不正確(例如 null或超出范圍)。Attributes目前我正在使用和UnityEngine.Assertionson的組合Awake()來檢查空引用或不正確的值;在游戲啟動時拋出異常(而不是在執行過程中的意外點),例如:public class PlayerMovement : MonoBehaviour{    [SerializeField]    [Tooltip("Rigidbody of the Player.")]    private Rigidbody playerRigidBody;    [SerializeField]    [Tooltip("Forward force of the Player.")]    [Range(100f, 50000f)]    private float forwardForce = 6000f;    [SerializeField]    [Tooltip("Sideways force of the Player.")]    [Range(10f, 1000f)]    private float sidewaysForce = 120f;    private GameManager gameManager;    void Awake()    {        // Cache essential references        gameManager = GameObject.FindGameObjectWithTag("GameManager").GetComponent<GameManager>();        // Assert that all required references are present and correct        UnityEngine.Assertions.Assert.IsNotNull(gameManager, "Member \"gameManager\" is required.");        UnityEngine.Assertions.Assert.IsNotNull(playerRigidBody, "Member \"Rigidbody\" is required.");        //UnityEngine.Assertions.Assert.IsTrue(ForwardForce > 100, "\"ForwardForce\" must be greater than 100");        //UnityEngine.Assertions.Assert.IsTrue(SidewaysForce > 10, "\"SidewaysForce\" must be greater than 10");    }    ...}這是最佳實踐,還是有更好的方法在游戲啟動前驗證基本參數?
查看完整描述

1 回答

?
皈依舞

TA貢獻1851條經驗 獲得超3個贊

不是真的在編譯時,但如果你想在每次在 Unity 中打開項目時進行檢查,重新編譯代碼或加載新場景,你可以使用[InitializeOnLoad]and?SceneManager.sceneLoaded。

首先有一個像這樣的界面

public interface INullReferenceChecker

{

? ? void CheckReferences();

}

然后在eg里面有一個全局編輯器腳本Assets/Editor/RunNullChecks.cs(重要的是那個是放在Editor后面的所以去掉)


[InitializeOnLoad]

public class RunNullChecks

{

? ? public static RunNullChecks

? ? {

? ? ? ? // first of all also add a callback so it gets re-run everytime you switch a scene


? ? ? ? // removing it first makes sure it is only added once

? ? ? ? EditorSceneManager.sceneOpened -= Run;

? ? ? ? EditorSceneManager.sceneOpened += Run;


? ? ? ? Run();

? ? }


? ? private static void Run(Scene scene, LoadSceneMode mode)

? ? {

? ? ? ? Run();

? ? }


? ? public static void Run()

? ? {

? ? ? ? // here it depends a bit on your needs

? ? ? ? // you either can check only stuff in the Scene like

? ? ? ? var nullCheckers = FindObjectsOfType<INullReferenceChecker>();

? ? ? ? // this gets only active and enabled components!

? ? ? ? // or you could include all prefabs, ScriptableObjects using

? ? ? ? //var nullCheckers = Resources.FindObjectsOfTypeAll<INullReferenceChecker>();


? ? ? ? // and then let them do whatever they implemented

? ? ? ? foreach(var tester in nullCheckers)

? ? ? ? {

? ? ? ? ? ? tester.CheckReferences();

? ? ? ? }

? ? }

}

那么你會有


public class PlayerMovement : MonoBehaviour, INullReferenceChecker

{

? ? ...


? ? public override void CheckReferences()

? ? {

? ? ? ? UnityEngine.Assertions.Assert.IsNotNull(gameManager, "Member \"gameManager\" is required.");

? ? ? ? UnityEngine.Assertions.Assert.IsNotNull(playerRigidBody, "Member \"Rigidbody\" is required.");



? ? ? ? // you could also simply go for

? ? ? ? if(!gameManager) Debug.LogErrorFormat(this, "Member \"{0}\" is required.", nameof(gameManager));

? ? ? ? if(!playerRigidBody) Debug.LogErrorFormat(this, "Member \"{0}\" is required.", nameof(playerRigidBody));

? ? }

}

另一種選擇也可能是使用[ExecuteInEditMode]屬性。

這使得

  • Awake每次打開項目/加載場景/向場景添加新組件時調用的方法

  • Update每次更改場景中的內容時都會調用方法

然而,您可能會禁用某些代碼塊,例如Update檢查Application.IsPlaying和/或Application.isEditor。


查看完整回答
反對 回復 2023-04-16
  • 1 回答
  • 0 關注
  • 255 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號