Unity エディタで編集できるオリジナルのデータ構造を作ろう

前回は、花びらを100個ランダムな位置に配置しました。
気になったのが、花びらの動きが全く同じだった点です。
そこで、花びらごとの水平に移動する距離を1枚ごとにランダムに変えます。

今回はその準備段階として、移動距離として許可する範囲を指定するための構造体のプログラムを作り、それを Unity エディタ上で編集できるようにします。
※ Unity は 2021.3.14f1、 OS は Windows 10 です。

RangeFloat 構造体を作る

今までは Rect や GameObject といったすでに用意されている型の変数を public 指定して、 Unity エディタ上で編集できるようにしました。

今回は、最小と最大の二つの小数値を持つ型が必要です。
RangeInt という最小と最大を二つの整数値で持つ構造体は標準で利用できます。
これを参考にして RangeFloat 構造体を作ってみましょう。

RangeFloat 構造体を定義する C# のプログラムのファイルを作成します。
Project ウィンドウ内の Manager.cs と同じ Assets フォルダ直下に RangeFloat.cs という名前で作成しました。
スクリプトファイルの作成は Project ウィンドウのフォルダ内で右クリックをして、コンテキストメニュー→[Create]→[C# Script] で出来ます。

RangeFloat というスクリプトファイルを Project ウィンドウ内に作成します。

RangeFloat というスクリプトファイルを Project ウィンドウ内に作成します。

作成した RangeFloat.cs ファイルアイコンをダブルクリックするなどしてエディタを開きます。
そして以下のコードに上書きして保存してください。

using UnityEngine;

[System.Serializable]
public struct RangeFloat
{
    public float start;
    public float length;
}

次に、作成した RangeFloat 構造体を「桜の花びら」プレハブに付加したスクリプトでメンバ変数の型として使います。

public class SakuraNoHanabira : MonoBehaviour
{
    //...
    /// 水平方向の移動幅の範囲です。
    public RangeFloat HorizontalDistanceRange;
    //...
}

Unity エディタに戻り、「桜の花びら」プレハブを選択して Inspector ウィンドウでスクリプトコンポーネントを見ると、作成した RangeFloat 型の HorizontalDistanceRange が編集できる項目として追加されました。

編集したスクリプトのコンポーネントに新しい編集項目が追加されました。

編集したスクリプトのコンポーネントに新しい編集項目が追加されました。

エディタで編集する変数を public 指定したくない場合

今まで Unity エディタの Inspector ウィンドウ内で編集したいメンバ変数について public 指定をしてきました。
しかし、public 指定は、外部から簡単に値を書き換えられたりするため、バグ修正が難しくなったり、設計として良くないと取られることもあります。

そんなときは public を、よりメンバ変数を保護する protectedprivate アクセス修飾子に変え [SerializeField] 属性を追加してみましょう。
具体的には以下のようになります。

[System.Serializable]
public struct RangeFloat
{
    [SerializeField]
    private float start;
    [SerializeField]
    private float length;
}

public から private にアクセス修飾子を変えたことで、プログラム上、外部からの値の読み書きができなくなりました。
しかし、これではプログラムで値にアクセスできなくなり、役に立ちません。
そこで、アクセサを追記します。 アクセサは、アクセスできない変数外部とのやりとりを仲介する関数です。これにより、変数は守られ、外部からも許可されたやり方でアクセスできます。

[System.Serializable]
public struct RangeFloat
{
    [SerializeField]
    private float start;
    [SerializeField]
    private float length;

    public float Start
    {
        get { return start; }
        set { start = value; }
    }

    public float Length
    {
        get { return length; }
        set { length = value; }
    }

    public float End
    {
        get { return start + length; }
    }
}

Start と Length というアクセサを作りました。内部には get と set の定義があります。get は値を読みとる処理で呼び出され、 set は値を書き換える処理で呼び出されます。 set の中で使われている value は上書きする値の入った引数のようなものです。

End は実体のないデータです。すでに存在している最小値 start と長さ length の足し算の値です。
いちいち足し算をせずに範囲の最大を得られるように読み取り専用のアクセサとして作りました。

先ほど宣言した HorizontalDistanceRange メンバ変数も public ではなく protected に変更し [SerializeField] 属性をつけましょう。

    /// 水平方向の移動幅の範囲です。
    [SerializeField]
    protected RangeFloat HorizontalDistanceRange;

これでプログラム上では外部から保護され、Unity エディタの Inspector ウィンドウでは編集できます。

Inspector ウィンドウの HorizontalDistanceRange の編集 UI は先ほどと同じですが、 public 指定ではない変数も編集できるようになりました。

編集したスクリプトのコンポーネントに新しい編集項目が追加されました。

編集したスクリプトのコンポーネントに新しい編集項目が追加されました。

 

 

コメント

Ads Blocker Image Powered by Code Help Pro

お願い - Ads Blocker Detected

このサイトは広告を掲載して運営しています。

ポップアップを閉じて閲覧できますが、よろしければ

このサイト内の広告を非表示にする拡張機能をオフにしていただけませんか?

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.

タイトルとURLをコピーしました