質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

1563閲覧

【Unity】Editor上でListの要素数が変化した時に処理を実行させたい

Y0241-N

総合スコア1066

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2022/12/13 09:06

編集2022/12/13 09:07

実現したいこと

Unity Edtior上で01ClassのListを持つ02ClassのListを持つ03Classtを作っています。

03Class(02ClassをList化して所持)
--02Class(01ClassをList化して所持)
----01Class

この03のClassListの要素数を変化した場合に、処理を走らせ、新しく生成された要素(Class)を
走らせた処理に基づいた状態にしたいため、Editor上でListの要素数が変化した時に、新しい要素に以下の処理を適用させた状態とさせたいです。

走らせたい処理

C#

1 void Reset() 2 { 3 for(int i = 0 ; i < EF_EnumCount; i++) 4 { 5 List.Add( 6 new EF_Class{ 7 efName = Enum.GetName(typeof(EF), i) , 8 ef = (EF) i } ); 9 } 10 }

02Classの状態をEnumの要素数分自動的01Classを作成する処理となっています。

試したこと

02Classを独立して使用する場合にはReset()メソッドを使えばアタッチした際に自動的に
思うような状態に出来ていました。

調べた感じではEditorをカスタマイズすればできるのかな?という気がしていますが、
具体的な方法が分からない為、質問させていただきます。
宜しくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

03ClassにISerializationCallbackReceiverを実装しておいて、デシリアライゼーションのタイミングでリストの内容をチェックするというのはいかがでしょうか?

C#

1using System; 2using System.Collections.Generic; 3using UnityEngine; 4 5// Class03にはISerializationCallbackReceiverを実装しておく 6public class Class03 : MonoBehaviour, ISerializationCallbackReceiver 7{ 8 [SerializeField] private List<Class02> children; 9 10 // シリアライズ時には特に何か行う必要はない 11 public void OnBeforeSerialize() 12 { 13 } 14 15 // デシリアライズ時にClass02リストの内容をチェックする 16 // もしlistが空の子がいれば、それが新しく追加された 17 // 未初期化の子だと推定されるので、Resetを実行する 18 public void OnAfterDeserialize() 19 { 20 foreach (Class02 child in children) 21 { 22 if (!child.IsInitialized) 23 { 24 child.Reset(); 25 } 26 } 27 } 28} 29 30[Serializable] 31public class Class02 32{ 33 private static readonly int EF_EnumCount = Enum.GetNames(typeof(EF)).Length; 34 35 [SerializeField] private List<EF_Class> list; 36 37 // Class02に、初期化済みかどうかを示すプロパティを追加しておく 38 // (さしあたり、listが空なら未初期化状態だと見なすことにしました) 39 public bool IsInitialized => list is { Count: > 0 }; 40 41 public void Reset() 42 { 43 list ??= new List<EF_Class>(); 44 list.Clear(); 45 for (int i = 0; i < EF_EnumCount; i++) 46 { 47 list.Add(new EF_Class { efName = Enum.GetName(typeof(EF), i), ef = (EF)i }); 48 } 49 } 50} 51 52[Serializable] 53public class EF_Class 54{ 55 public string efName; 56 public EF ef; 57} 58 59public enum EF 60{ 61 Alfa, 62 Bravo, 63 Charlie, 64 Delta, 65 Echo 66}

投稿2022/12/14 09:44

Bongo

総合スコア10816

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Y0241-N

2022/12/15 01:33

回答ありがとうございました。 教えていただいた方法で思い通りの挙動となりました、とても便利ですね。 ひとつ教えていただきたいのですが、 list.Clear(); の部分の処理はなぜ必要なのでしょうか? 念のためにlistに要素がある場合に初期化するためという感じなのでしょうか?
Bongo

2022/12/15 02:45

あそこであのように「まずlistがnullなら新しく生成、次いでlistの内容を空にする」としたのは、もしかするとResetメソッドは初期化時の1回だけ呼ばれるとは限らず、listの内容を色々と書き換えた後で初期状態にふたたび戻したい時にも使うことを想定していらっしゃるのかもしれない...などと勝手に想像してのことでした。そういったケースは考慮不要でしたら、あそこは削除してしまってかまわないかと思います。
Y0241-N

2022/12/15 04:03

なるほど、ありがとうございます。 的確な回答をして頂きありがとうございました、とても助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問