Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
2
Question by TBernard · Jan 31, 2015 at 07:25 PM · c#editorpropertydrawer

Creating a PropertyDrawer for a fixed size int array

Disclaimer: I'm (very) new to Unity. Probably getting in over my head, but I find that to be the quickest way to learn.

Using Unity 4.5, scripting in C#

TLDR; I need to create a property drawer that shows 4 specific elements of a fixed size array, doesn't allow array resizing, and has custom labels. My attempts so far only let me overwrite the drawer for the individual array elements. HALP!!! /TLDR;

I have the following class: Assets/Scripts/Board/Cell.cs

 using UnityEngine;
 using System.Collections;
 
 namespace Board {
     public class Cell : MonoBehaviour {
 
         const int MIN_PENALTY = 0;
         const int MAX_PENALTY = 2;
 
         [BoardCellPenaltiesAttribute] public int[] penalty;
 
         // Use this for initialization
         void Start () {
         
         }
         
         // Update is called once per frame
         void Update () {
         
         }
 
         public int getPenalty(int dir) {
             if (dir > 0 && dir < penalty.Length) {
                 return penalty[dir];
             }
             return 0;
         }
         public void setPenalty(int dir, int val) {
             if (val >= MIN_PENALTY && val <= MAX_PENALTY) {
                 penalty[dir] = val;
             }
         }
 
     }
 }

I created the following Attribute: Assets/Scripts/Z_Editor/Attributes/BoardCellPenaltiesAttribute.cs

 using UnityEditor;
 using UnityEngine;
 
 public class BoardCellPenaltiesAttribute : PropertyAttribute {
     public BoardCellPenaltiesAttribute () {}
 }

Finally I have this PropertyDrawer:

 using UnityEditor;
 using UnityEngine;
 
 [CustomPropertyDrawer (typeof (BoardCellPenaltiesAttribute))]
 public class BoardCellPenaltiesDrawer : PropertyDrawer {

 public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) 
 { 
     EditorGUI.HelpBox (position, property.type.ToString () , MessageType.None);
 }
 

}

All the tutorials I've tried say this method should allow me to create a drawer for the whole array. What I see is the dropdown for Penalties, a size input box, then one helpbox per array element. The help box prints a type of int, not int[].

Why is my attribute applying to each element of the array rather than the array itself, and how can I override the drawer for the entire array? Ultimately I'm trying to prevent the editor from resizing the array and also show custom labels and edit boxes for 4 and only 4 elements of the array. Esoteric I know.

Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image VesuvianPrime · Jan 31, 2015 at 07:52 PM 1
Share

Hi TBernard

It should be pretty straight-forward draw your 4 items in the inspector using a PropertyDrawer. You can simply use the SerializedProperty method GetArrayElementAtIndex to get the SerializedProperty at a given index and feed it into a PropertyField.

I would suggest, however, perhaps you are better served storing 4 fields inside BoardCellPenaltiesAttribute, ins$$anonymous$$d of an array.

avatar image TBernard · Jan 31, 2015 at 08:26 PM 0
Share

@VesuvianPrime - Thanks. I actually tried GetArrayElementAtIndex() but I get this error:

 Retrieving array element but no array was provided
 UnityEditor.SerializedProperty:GetArrayElementAtIndex(Int32)

It seems the property being passed into the OnGUI function is not the serialized array, but rather each of it's members.

Also, I know it's odd use of an array, but its going to simplify how I interact with the object down the road.

avatar image VesuvianPrime · Jan 31, 2015 at 10:00 PM 0
Share

The SerializedProperty co$$anonymous$$g into the OnGUI method should be the serialized BoardCellPenaltiesAttribute. You can get the children of it using FindPropertyRelative, just make sure you're flagged your fields as [SerializeField].

1 Reply

· Add your reply
  • Sort: 
avatar image
2

Answer by TBernard · Jan 31, 2015 at 10:56 PM

After beating my head against this wall for a day I finally noted THIS gem in the introductory blog post.

Namely, "You can't make a PropertyDrawer for arrays or generic lists themselves." and "elements inside arrays and lists do work with PropertyDrawers"

Guess it can't be done. Time to look at different approaches.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image VesuvianPrime · Feb 01, 2015 at 12:22 AM 1
Share

I'm pretty confident it can be done. Just make a hierarchy that looks like:

 [Serializable]
 BoardCellPenaltiesAttribute : PropertyAttribute
 {
     [SerializeField] public int[] myFixedArray;
 }

And then in your PropertyDrawer you can do stuff like:

 [CustomPropertyDrawer (typeof (BoardCellPenaltiesAttribute))]
 public class BoardCellPenaltiesDrawer : PropertyDrawer
 {
     public override void OnGUI (Rect position, SerializedProperty property, GUIContent label)
     {
         SerializedProperty arrayProp = property.FindPropertyRelative("myFixedArray");
 
         SerializedProperty firstIntProp = arrayProp.GetArrayElementAtIndex(0);
 
         EditorGUI.PropertyField(position, firstIntProp, label);
 
         // etc
     }
 }

There's a little more work to do, namely overriding the height of the property drawer (4 rows?) but this kind of approach should do exactly what you want.

avatar image TBernard · Feb 01, 2015 at 12:43 AM 0
Share

@VesuvianPrime - Ah I see. I suppose if I made my array part of a serializable object then yes I could attach the drawer to that object. That's different then the custom attribute approach I was trying to use where the data was in a normal int array and a custom [BoardCellPenaltiesAttribute] was used to change how the editor shows it. That might be the approach I have to take. Its either that or a custom inspector anyway. Thanks.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

3 People are following this question.

avatar image avatar image avatar image

Related Questions

Call a function from CustomPropertyDrawer of Arbitrary class 1 Answer

Display Custom Inspectors for each class in a List<> 1 Answer

PropertyDrawer not painted when scrolling upwards 0 Answers

Statefull PropertyDrawer 0 Answers

Intractable CustomPropertyDrawer 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges