※ これは 2022/01/01 時点の Unity 2021.2.7f1 の情報です
最新版では動作が異なる可能性がありますのでご注意ください
Packages
管理の自作基盤ライブラリで Assets
側にテンプレートファイルをコピーできるようにしたものの、列挙型(enum)の記述を partial によって既定部分とアプリごとに追記する部分みたいな分散記述ができなくて困った
これを何とかする
スポンサードリンク
といっても公式 Microsoft Docs にやり方が載ってるのでそれを利用するだけ
Packages
側にこんな列挙型風の抽象クラスを用意して
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Reflection; namespace MatatabiUx.Common { /// <summary> /// 抽象列挙型クラス /// </summary> public abstract class Enumeration : IComparable { /// <summary> /// 名称 /// </summary> public string Name { get; } /// <summary> /// ID /// </summary> public int Id { get; } /// <summary> /// コンストラクタ /// </summary> /// <param name="id">ID</param> /// <param name="name">名称</param> protected Enumeration(int id, string name) => (Id, Name) = (id, name); /// <summary> /// <see cref="object.ToString()"/> /// </summary> public override string ToString() => Name; /// <summary> /// すべての列挙値を取得する /// </summary> /// <typeparam name="T">列挙型</typeparam> public static IEnumerable<T> GetItems<T>() where T : Enumeration => typeof(T).GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy) .Select(f => f.GetValue(null)) .Cast<T>(); /// <summary> /// <see cref="object.Equals(object)"/> /// </summary> public override bool Equals(object obj) { if (obj is not Enumeration otherValue) return false; var typeMatches = GetType().Equals(obj.GetType()); var valueMatches = Id.Equals(otherValue.Id); return typeMatches && valueMatches; } /// <summary> /// <see cref="object.GetHashCode()"/> /// </summary> public override int GetHashCode() => Id; /// <summary> /// <see cref="IComparable.CompareTo(object)"/> /// </summary> /// <param name="other">比較対象</param> public int CompareTo(object other) => Id.CompareTo(((Enumeration)other).Id); } }
Assets
側に例えば音声指定用の列挙型を Enumeration
クラスを継承して追加
using System.Collections.Generic; namespace MatatabiUx.Common { /// <summary> /// 音声種別 /// </summary> public partial class Audios : Enumeration { /// <summary> /// 読み込み先パス /// </summary> public string Path { get; } /// <summary> /// コンストラクタ /// </summary> /// <param name="id">ID</param> /// <param name="name">名称</param> /// <param name="path">読み込み先パス</param> public Audios(int id, string name, string path = null) : base(id, name) { if (string.IsNullOrWhiteSpace(path)) { Path = $"Audios/Common/{name}"; } else { Path = path; } } /// <summary> /// <see cref="Enumeration.GetItems{T}"/> /// </summary> public static IEnumerable<Audios> GetItems() => Enumeration.GetItems<Audios>(); #region 既定の列挙値 public static Audios Apply = new Audios(-1, nameof(Apply)); public static Audios Cancel = new Audios(-2, nameof(Cancel)); #endregion //既定の列挙値 } }
これとは別に partial で追加の列挙値を記述
追加分のコードはこんな感じ
namespace MatatabiUx.Common { /// <summary> /// 音声種別 /// </summary> public partial class Audios : Enumeration { public static Audios Alert = new Audios(1, nameof(Alert)); } }
とりあえず下記のようなテストコードを走らせて試してみる
using MatatabiUx.Common; using System.Linq; using UnityEngine; public class Test : MonoBehaviour { public void Start() { UnityEngine.Debug.Log( $"Audios={string.Join(", ", Audios.GetItems().Select(x => x.Name).ToArray())}"); } }
ちゃんと分割した列挙値が全部出た