Unity 記錄常用的特性 Attribute


建立時間: 2023年7月15日 01:42
更新時間: 2024年12月8日 00:05

說明

本篇將用來記錄 Unity 常用的特性,像是最常見的 [SerializeField]。

特性

關於特性是什麼,請參考 c# 介紹 Attribute 屬性 []

FormerlySerializedAs

它主要用在腳本變數重新命名時,避免遊戲物件設定腳本的屬性資料丟失。

using UnityEngine;

public class Player : MonoBehaviour
{
    [SerializeField]
    private int health;
}

假設 Hierarchy 有一個遊戲物件,並且已經添加 Player 組件,設定 health = 100。

我打算將 health 重新命名成 playerHealth。

using UnityEngine;
using UnityEngine.Serialization;

public class Player : MonoBehaviour
{
    [FormerlySerializedAs("health")]
    [SerializeField]
    private int playerHealth;
}

此時如果回到 Unity Editor 這樣我之前設定的 health 屬性資料就會變成在 playerHealth。

接著你可以再把 [FormerlySerializedAs("health")] 拿掉。

若是要修改 ScriptableObject 的 asset 資料,請參考相關文章 Unity 更新 ScriptableObject 屬性名稱 資料不丟失

Header

Header 可以在 Inspector 分類變數,當腳本有很多變數的時候相當實用。

using UnityEngine;

public class Example : MonoBehaviour
{
    [Header("Health Settings")]
    public int health = 0;
    public int maxHealth = 100;

    [Header("Shield Settings")]
    public int shield = 0;
    public int maxShield = 0;
}

如上 healthmaxHealth 會在 “Health Settings” 底下,shieldmaxShield 會在 “Shield Settings” 底下。

Obsolete

Obsolete 屬性會將程式碼元素標記為不再建議使用。ObsoleteObsoleteAttribute 的別名。

ObsoleteAttribute

標記不再使用的程式項目。

範例

下列範例會定義類別,其中包含屬性和以 ObsoleteAttribute 屬性標記的方法。在程式代碼中存取屬性的值 OldProperty 會產生編譯程式警告,但呼叫 CallOldMethod 方法會產生編譯程序錯誤。此範例也會顯示當您嘗試編譯原始程式碼時所產生的輸出。

using System;
using System.Reflection;

public class Example
{
   // 標記 OldProperty 為過時。
   [ObsoleteAttribute("此屬性已過時,請使用 NewProperty 替代.", false)]
   public static string OldProperty
   { get { return "The old property value."; } }

   public static string NewProperty
   { get { return "The new property value."; } }

   // 標記 CallOldMethod 為過時。
   [ObsoleteAttribute("此方法已過時,請調用 CallNewMethod 替代.", true)]
   public static string CallOldMethod()
   {
      return "You have called CallOldMethod.";
   }

   public static string CallNewMethod()
   {
      return "You have called CallNewMethod.";
   }

   public static void Main()
   {
      Console.WriteLine(OldProperty);
      Console.WriteLine();
      Console.WriteLine(CallOldMethod());
   }
}
// 嘗試編譯此範例會產生類似以下輸出的輸出:
//    Example.cs(31,25): error CS0619: 'Example.CallOldMethod()' is obsolete:
//            'This method is obsolete. Call CallNewMethod instead.'
//    Example.cs(29,25): warning CS0618: 'Example.OldProperty' is obsolete:
//            'This property is obsolete. Use NewProperty instead.'

參考自 https://learn.microsoft.com/zh-tw/dotnet/api/system.obsoleteattribute?view=net-9.0

SerializeField

SerializeField 是用來將腳本不公開的成員,設定成可以在 Unity Editor 存取,是非常常見的特性。

Driver.cs

using UnityEngine;

public class Driver : MonoBehaviour
{
    [SerializeField]
    float moveSpeed = 0.01f;

    [SerializeField]
    float steerSpeed = 1f;
}

SerializeField in Inspector

Serializable

將 class 設成可序列化,目前我了解這個特性的其中一個用途就是將 json 檔的內容轉換成物件。

請參考 Unity 手冊 JsonUtility.FromJson

以下是參考官方文件並稍微修改的腳本,另外示範使用 SerializeField 特性,定義私有屬性。

using System;
using UnityEngine;

[Serializable]
public class PlayerInfo
{
    [SerializeField]
    private string name;
    public int lives;
    public float health;

    public static PlayerInfo CreateFromJSON(string jsonString)
    {
        return JsonUtility.FromJson<PlayerInfo>(jsonString);
    }

    // Given JSON input:
    // {"name":"Dr Charles","lives":3,"health":0.8}
    // this example will return a PlayerInfo object with
    // name == "Dr Charles", lives == 3, and health == 0.8f.
}

TextArea

TextArea 特性是一個用於在 Inspector 視圖中顯示多行文字方塊的特性。

namespace Assets.Scripts
{
    [CreateAssetMenu(fileName = "Question", menuName = "Scriptable Objects/Quiz Question")]
    public class QuestionScriptableObject : ScriptableObject
    {
        [SerializeField]
        [TextArea(2, 6)]
        private string question = "Enter new question here";
    }
}

如上我設定最低顯示2行,最高顯示6行的文字方塊。

TextArea preview

觀看次數: 1082
attributeFormerlySerializedAsserializableserializeFieldunity
按讚追蹤 Enjoy 軟體 Facebook 粉絲專頁
每週分享資訊技術

一杯咖啡的力量,勝過千言萬語的感謝。

支持我一杯咖啡,讓我繼續創作優質內容,與您分享更多知識與樂趣!