Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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
0
Question by TheBlackBurrito · Jun 10, 2017 at 07:03 AM · editorarrayinspectorattribute

Unity Inspector batching Custom Property Attributes in Arrays

I've created a Custom Property Attribute for color variables, which adds a drop down with a quick access of colors we are using a lot as a team. This all works fine.

The issue is if the attribute is added to a color in a struct, and then I have an array of that struct. If I change the value of the color in the array, it affects all of the same parameters of the struct in that array.

In other words, it feels like Unity is batching the Attributes in Arrays. This doesn't happen with ones with come default with Unity though, such as [Range()], so obviously there is a way to fix it.

Here is my code for the property attribute. (Note: The colors have been changed when i posted this).

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 #if UNITY_EDITOR
 using UnityEditor;
 #endif
 
 public class DefaultColorAttributes : PropertyAttribute {
 
     public Color color;
     public DefaultColorAttributes()
     {
         Debug.Log("I made this");
     }
 
 }
 
 public class CustomColors {
 
     public static Color Cancel = new Color(1, 0, 0, 1); 
     public static Color Focal = new Color(0, 0, 1, 1);
     public static Color Black = new Color(0, 0, 0, 1);
     public static Color Midpoint = new Color(0.5f, 0.5f, 0.5f, 1);
     public static Color White = new Color(1, 1, 1, 1);
     public static Color Select = new Color(0, 1, 0, 1);
 
     public enum ColorEnum : int { Custom = 0, Focal, Black, Midpoint, White, Cancel, Select }
 
 }
 
 #if UNITY_EDITOR
 [CustomPropertyDrawer(typeof(DefaultColorAttributes))]
 public class RangeDrawer : PropertyDrawer {
 
     private CustomColors .ColorEnum currentEnum = CustomColors .ColorEnum.Custom;
 
     public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
     {
 
         DefaultColorAttributes ColorAttributes = attribute as DefaultColorAttributes;
 
         Rect enumPosition = position;
         enumPosition.width = position.width / 4;
 
         Rect colorPosition = position;
         colorPosition.x += position.width / 4;
         colorPosition.width -= position.width / 4;
 
         currentEnum = (CustomColors .ColorEnum)EditorGUI.EnumPopup(enumPosition, currentEnum);
 
 
         switch (currentEnum) {
             case CustomColors .ColorEnum.Custom:
                 property.colorValue = EditorGUI.ColorField(colorPosition, property.colorValue);
                 break;
             case CustomColors .ColorEnum.Focal:
                 property.colorValue = EditorGUI.ColorField(colorPosition, CustomColors .Focal);
                 break;
             case CustomColors .ColorEnum.Black:
                 property.colorValue = EditorGUI.ColorField(colorPosition, CustomColors .Black);
                 break;
             case CustomColors .ColorEnum.Midpoint:
                 property.colorValue = EditorGUI.ColorField(colorPosition, CustomColors .Midpoint);
                 break;
             case CustomColors .ColorEnum.White:
                 property.colorValue = EditorGUI.ColorField(colorPosition, CustomColors .White);
                 break;
             case CustomColors .ColorEnum.Cancel:
                 property.colorValue = EditorGUI.ColorField(colorPosition, CustomColors .Cancel);
                 break;
             case CustomColors .ColorEnum.Select:
                 property.colorValue = EditorGUI.ColorField(colorPosition, CustomColors .Select);
                 break;
         }
 
     }
 }
 #endif
 
 
 

Here is a script which shows off what I'm talking about

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class NewBehaviourScript : MonoBehaviour {
 
     [DefaultColorAttributes()]
     public Color Color1;
     [DefaultColorAttributes()]
     public Color Color2;
 
     public balhah[] Blahs;
 
     // Use this for initialization
     void Start () {
         
     }
     
     // Update is called once per frame
     void Update () {
         
     }
 }
 
 [System.Serializable]
 public struct balhah {
 
     [DefaultColorAttributes()]
     public Color BLAH1;
     [DefaultColorAttributes()]
     public Color BLAH2;
 
     [Range(0,1)] 
     public float range;
 }
 

This is what it looks like alt text

example.png (17.6 kB)
Comment
Add comment
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

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Adam-Mechtley · Jun 10, 2017 at 09:46 AM

It's not super well documented, but yes the idea is that (as an optimization) the same PropertyDrawer instance will be shared in this case. The way I usually recommend working around this if you need it to be stateful is to instead do something like Dictionary<string, ColorEnum> m_CurrentEnumPerPropertyPath instead of simply ColorEnum currentEnum. What you then do is then store values that are keyed with property.propertyPath for use in your EnumPopup.

Comment
Add comment · Show 1 · 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 TheBlackBurrito · Jun 14, 2017 at 04:58 AM 0
Share

Thanks, this works perfectly.

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

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Gradient Changes in Editor Reset In Play Mode. Why? 1 Answer

Editor scripting: Object reference not set to an instance of an object 0 Answers

DeletArrayElementAtIndex crashes Unity when operating a bool array 1 Answer

Can a GameObject inside of an array be made "accessible" from the editor? 2 Answers

SerializeFIeld in custom attribute 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