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

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

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

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

Unity

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

Q&A

解決済

3回答

12239閲覧

Inspectorにて配列の長さだけを変更できないようにしたい

sadada

総合スコア7

C#

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

Unity

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

0グッド

0クリップ

投稿2020/01/20 15:13

編集2020/01/20 15:15

UnityでInspectorに表示されている配列の長さだけを変更できないようにしたいです。

下記のようなPropertyDrawerを継承したクラスを作成して属性をつけてみましたが、propertyに対する属性なので当然ながら配列のサイズが変更できてしまいます。

どのようにすれば配列の長さだけを変更できないようにすることができますでしょうか?
(配列の長さだけ編集できないようにする方法として、荒業ですが、各Inspectorの値の表示位置をSizeのところにかぶせるように表示させて、物理的に編集不可能にするぐらいしか思いつきませんでした・・・)
よろしくお願いいたします。

cs

1[CustomPropertyDrawer(typeof(ReadOnlyLengthAttribute))] 2public class ReadOnlyLengthDrawer : PropertyDrawer 3{ 4 public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 5 { 6 GUI.enabled = false; 7 EditorGUI.PropertyField(position, property, label, true); 8 GUI.enabled = true; 9 } 10} 11

cs

1 [SerializeField] 2 [ReadOnlyLength] 3 private int[] m_value = new int[3]; 4

イメージ説明

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

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

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

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

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

guest

回答3

0

強制的にサイズを2にしてしまうとか。

cs

1// Assets/Scripts/Test01.cs 2using UnityEngine; 3using System.Collections; 4 5public class Test01 : MonoBehaviour { 6 [SerializeField] int[] hoge = new int[2] { 0, 1 }; 7}

cs

1// Assets/Editor/Test01Editor.cs 2using UnityEngine; 3using UnityEditor; 4 5[CustomEditor(typeof(Test01))] 6public class Test01Editor : Editor { 7 public override void OnInspectorGUI() 8 { 9 base.OnInspectorGUI(); 10 11 SerializedProperty prop = this.serializedObject.FindProperty("hoge"); 12 while (prop.arraySize > 2) { 13 prop.DeleteArrayElementAtIndex(2); 14 } 15 this.serializedObject.ApplyModifiedPropertiesWithoutUndo(); 16 } 17}

投稿2020/01/21 13:52

katsuko

総合スコア3536

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

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

sadada

2020/01/21 14:33

各々のクラスごとに用意する必要はありますが絶対に変更できないので確実ですね。ありがとうございました!
guest

0

ベストアンサー

検索してもできないという情報ばかりひっかかりますね...
どうやら配列などに対してPropertyAttributeを付加しても、PropertyDrawerOnGUIは個々の配列要素についてのプロパティ描画処理を担当することになるようです。すでに「Size」の部分は終わってしまって、描画させないようにはできないかもしれません。

「表示位置をSizeのところにかぶせるように表示させて」というのは名案だと思ったのですが、どうやらこちらも困難なようです。
描画は上から順に行われるようなので、後からSizeの上に何か重ね描きすることは可能そうでした。
ですが各コントロールのマウス操作判定も上から順に行われるようですので、たとえ真上にボタンを置いたつもりでもSizeフィールドの方が入力を受け取ってしまうみたいです。
この入力受け付け優先権を変更する方法も見つけられませんでした。

いい解決策をお出しできず不本意ですが、Sizeフィールドに重ねて「絶対いじるな」とでも脅しを表示してやるなんてどうですかね?
結局書き換えることはできてしまうので「ReadOnlyLength」にはできませんでしたが...
確実に変更できないようブロックしたいとなるとizmktrさんの案になるか、あるいは特定のクラス専用のPropertyDrawerにして表示内容全体をコントロールするかでしょうか。でもそれだと任意の変数に属性を付けるだけでいいという便利さは得られませんよね...

C#

1using System.Text.RegularExpressions; 2using UnityEditor; 3using UnityEngine; 4 5[CustomPropertyDrawer(typeof(ReadOnlyLengthAttribute))] 6public class ReadOnlyLengthDrawer : PropertyDrawer 7{ 8 private static readonly Regex ArrayFirstElementPattern = new Regex(".+\.Array\.data\[0\]", RegexOptions.Compiled); 9 private static readonly GUIStyle WarningLabelStyle = new GUIStyle(GUI.skin.label) {alignment = TextAnchor.MiddleCenter}; 10 11 public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 12 { 13 if (ArrayFirstElementPattern.IsMatch(property.propertyPath)) 14 { 15 var maskRect = position; 16 maskRect.y -= EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; 17 var gray = (byte)(EditorGUIUtility.isProSkin ? 56 : 194); 18 EditorGUI.DrawRect(maskRect,new Color32(gray, gray, gray, 192)); 19 GUI.Label(maskRect, "Don't modify the size!", WarningLabelStyle); 20 } 21 22 EditorGUI.PropertyField(position, property, label, true); 23 } 24}

図

投稿2020/01/21 12:48

Bongo

総合スコア10811

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

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

sadada

2020/01/21 13:40

>ですが各コントロールのマウス操作判定も上から順に行われるようですので、たとえ真上にボタンを置いたつもりでも そうなんですね・・・初めて知りました。 脅し文句+グレーアウトまですると、編集できない感じが強く表現されてわかりやすいですね。 編集できないようにするということが無理とわかりスッキリしました。ありがとうございました!
guest

0

多分出来ないです

ただ、固定長って個別に名前が割り当てられることが多いので、
別々の変数名にするのがいいんじゃないかと思います。

Vector3 のように、x,y,zで作っておき、
vec[0]みたいなアクセス方法も提供する、みたいな感じです

投稿2020/01/21 09:25

izmktr

総合スコア2856

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

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

sadada

2020/01/21 13:33

確かに別々の変数名用意してvalue[0]のように実装するのもいいですね。 配列のサイズを変更できなくする方法ばかり考えてしまっていました。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問