├── Assets ├── Plugins.meta └── Plugins │ ├── AU.meta │ └── AU │ ├── Editor.meta │ ├── Editor │ ├── ShowInEditor.cs │ └── ShowInEditor.cs.meta │ ├── Sample.meta │ └── Sample │ ├── Editor.meta │ ├── Editor │ ├── TestEditor.cs │ └── TestEditor.cs.meta │ ├── SampleComponent.cs │ ├── SampleComponent.cs.meta │ ├── ShowInEditorTest.cs │ ├── ShowInEditorTest.cs.meta │ ├── Test.unity │ └── Test.unity.meta ├── LICENSE.txt ├── demo.jpg └── readme.md /Assets/Plugins.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4f5c66bcba8bc8c4abd127053bfa46a8 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Plugins/AU.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 81282f5086184474185377ce6c197b77 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Plugins/AU/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a9b601d55b44a344b9ee8162636fe0a0 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Plugins/AU/Editor/ShowInEditor.cs: -------------------------------------------------------------------------------- 1 | // 2 | // [ShowInEditor v0.1] 3 | // Developed as part of Project Ambiguous Utopia 4 | // By Darkfall (http://darkfall.me) 5 | // License: MIT 6 | // 7 | 8 | using UnityEngine; 9 | using System.Collections; 10 | using System.Reflection; 11 | using System.Collections.Generic; 12 | using System.Linq; 13 | 14 | #if UNITY_EDITOR 15 | 16 | using UnityEditor; 17 | 18 | #endif 19 | 20 | namespace AU 21 | { 22 | 23 | public enum ShowInEditorFlags 24 | { 25 | Default, 26 | ReadOnly, 27 | ReadWrite, 28 | } 29 | 30 | public enum ShowInEditorMessageType 31 | { 32 | None = 0, 33 | Info = 1, 34 | Warning = 2, 35 | Error = 3, 36 | } 37 | 38 | public enum ShowInEditorColor 39 | { 40 | Default = 0, 41 | Green, 42 | Red, 43 | Blue, 44 | Magenta, 45 | White, 46 | Cyan, 47 | Yellow, 48 | } 49 | 50 | public enum ShowInEditorStyle 51 | { 52 | Default, 53 | // button only available for methods 54 | Button, 55 | // slider only available for int / floats 56 | Slider, 57 | } 58 | 59 | 60 | /** 61 | * 62 | */ 63 | public class ShowInEditorRange 64 | { 65 | public float Min; 66 | public float Max; 67 | 68 | public ShowInEditorRange(float min, float max) 69 | { 70 | Min = min; 71 | Max = max; 72 | } 73 | } 74 | 75 | [System.AttributeUsage(System.AttributeTargets.Property | 76 | System.AttributeTargets.Field | 77 | System.AttributeTargets.Method | 78 | System.AttributeTargets.Class | 79 | System.AttributeTargets.Struct)] 80 | public class ShowInEditor : System.Attribute 81 | { 82 | public ShowInEditorFlags Flags; 83 | 84 | public string Comment = ""; 85 | public string Name = ""; 86 | public string Prefix = ""; 87 | 88 | /** 89 | * 90 | * Can modify the length of the array or not 91 | * 92 | * When enabled, users can modify the length of the array in the inspector (similar to how default inspector works) 93 | */ 94 | public bool CanModifyArrayLength = false; 95 | 96 | /** 97 | * Compress array layout to a horizontal group 98 | * Only support primitive types (bool, int, float) 99 | * 100 | * When enabled, the layout of an array will be 101 | * NAME 102 | * ELEMENT1 ELEMENT2 ELEMENT3 ... 103 | * Instead of 104 | * 105 | * NAME 106 | * [0] ... 107 | * [1] ... 108 | * [2] ... 109 | * 110 | * Also disables IsArrayBaseType and CanModifyArrayLength 111 | */ 112 | public bool CompactArrayLayout = false; 113 | 114 | /** 115 | * If its an array 116 | * Tells the inspector to draw a button to add the subclassess of the type instead of the type itself 117 | * Useful for abstract types 118 | */ 119 | public bool IsArrayBaseType = false; 120 | 121 | /** 122 | * When decorating a method, optionally making a button in the inspector 123 | * and the method will be invoked when the button is clicked 124 | */ 125 | public ShowInEditorStyle Style = ShowInEditorStyle.Default; 126 | 127 | /** 128 | * When the field is int / float 129 | * Optionally making clamping the value within range 130 | * When the style is slider, the GUI control will be a slider 131 | * **/ 132 | public float RangeMin = 0; 133 | public float RangeMax = 0; 134 | 135 | public ShowInEditorRange Range; 136 | 137 | /** 138 | * When its a button, optionally group the button using the grouping index 139 | * Default is -1 means no group (vertical aligned) 140 | */ 141 | public int Group = -1; 142 | 143 | public ShowInEditorMessageType CommentType = ShowInEditorMessageType.None; 144 | 145 | public static Color[] EditorColors = { 146 | GUI.color, 147 | Color.green, 148 | Color.red, 149 | Color.blue, 150 | Color.magenta, 151 | Color.white, 152 | Color.cyan, 153 | Color.yellow 154 | }; 155 | 156 | public ShowInEditorColor CommentColor = ShowInEditorColor.Default; 157 | public ShowInEditorColor FieldColor = ShowInEditorColor.Default; 158 | 159 | public int IndentLevel = 0; 160 | 161 | public Color UnityColor 162 | { 163 | get 164 | { 165 | return EditorColors[(int)FieldColor]; 166 | } 167 | } 168 | public Color UnityCommentColor 169 | { 170 | get 171 | { 172 | return EditorColors[(int)CommentColor]; 173 | } 174 | } 175 | 176 | } 177 | 178 | #if UNITY_EDITOR 179 | 180 | public static class EditorHelper 181 | { 182 | public abstract class MemberField 183 | { 184 | protected System.Object _obj; 185 | protected ShowInEditor _attribute; 186 | protected System.Type _sysType; 187 | protected SerializedPropertyType _serializedType; 188 | 189 | public string NamePrefix = ""; 190 | 191 | public System.Object ReferenceObject { get { return _obj; } } 192 | 193 | public ShowInEditor Attribute { get { return _attribute; } } 194 | 195 | public SerializedPropertyType Type { get { return _serializedType; } } 196 | 197 | public ShowInEditorFlags Flags { get { return _attribute.Flags; } } 198 | 199 | public ShowInEditorStyle Style { get { return _attribute.Style; } } 200 | 201 | public string Comment { get { return _attribute.Comment; } } 202 | 203 | public bool CanModifyArrayLength { get { return _attribute.CanModifyArrayLength; } } 204 | 205 | public bool CompactArrayLayout { get { return _attribute.CompactArrayLayout; } } 206 | 207 | public bool IsArrayBaseType { get { return _attribute.IsArrayBaseType; } } 208 | 209 | public Color Color { get { return _attribute.UnityColor; } } 210 | 211 | public Color CommentColor { get { return _attribute.UnityCommentColor; } } 212 | 213 | public bool IsDefaultColor { get { return _attribute.FieldColor == ShowInEditorColor.Default; } } 214 | 215 | public bool IsDefaultCommentColor { get { return _attribute.CommentColor == ShowInEditorColor.Default; } } 216 | 217 | public int Group { get { return _attribute.Group; } } 218 | 219 | public ShowInEditorRange ValueRange 220 | { 221 | get 222 | { 223 | if(_attribute.Range == null && _attribute.RangeMin != _attribute.RangeMax) 224 | _attribute.Range = new ShowInEditorRange(_attribute.RangeMin, _attribute.RangeMax); 225 | return _attribute.Range; 226 | } 227 | } 228 | 229 | public UnityEditor.MessageType CommentMessageType { get { return (UnityEditor.MessageType)_attribute.CommentType; } } 230 | 231 | public int IndentLevel 232 | { 233 | get { return _attribute.IndentLevel; } 234 | set { _attribute.IndentLevel = value; } 235 | } 236 | 237 | public void Rebind(System.Object obj) 238 | { 239 | _obj = obj; 240 | } 241 | 242 | public MemberField(System.Object obj, ShowInEditor attr, SerializedPropertyType type) 243 | { 244 | _obj = obj; 245 | _attribute = attr; 246 | _serializedType = type; 247 | } 248 | 249 | public abstract System.Object GetValue(); 250 | 251 | public abstract void SetValue(System.Object value); 252 | 253 | public abstract string GetName(); 254 | 255 | public abstract System.Type GetFieldType(); 256 | 257 | public abstract bool IsReadOnly(); 258 | 259 | public string GetName(MemberInfo info) 260 | { 261 | return _attribute.Prefix + NamePrefix + (_attribute.Name.Length > 0 ? _attribute.Name : ObjectNames.NicifyVariableName(info.Name)); 262 | } 263 | 264 | protected static 265 | Dictionary _typemap = new Dictionary 266 | { 267 | { typeof(int), SerializedPropertyType.Integer }, 268 | { typeof(float), SerializedPropertyType.Float }, 269 | { typeof(bool), SerializedPropertyType.Boolean }, 270 | { typeof(double), SerializedPropertyType.Float }, 271 | { typeof(string), SerializedPropertyType.String }, 272 | { typeof(Vector2), SerializedPropertyType.Vector2 }, 273 | { typeof(Vector3), SerializedPropertyType.Vector3 }, 274 | { typeof(Vector4), SerializedPropertyType.Vector4 }, 275 | { typeof(Quaternion), SerializedPropertyType.Quaternion }, 276 | { typeof(Rect), SerializedPropertyType.Rect }, 277 | { typeof(Bounds), SerializedPropertyType.Bounds }, 278 | { typeof(Color), SerializedPropertyType.Color }, 279 | { typeof(AnimationCurve), SerializedPropertyType.AnimationCurve }, 280 | { typeof(Gradient), SerializedPropertyType.Gradient }, 281 | }; 282 | 283 | public static bool GetSerializedTypeFromType(System.Type type, out SerializedPropertyType serializedType) 284 | { 285 | serializedType = SerializedPropertyType.Generic; 286 | if (type.IsEnum) 287 | { 288 | serializedType = SerializedPropertyType.Enum; 289 | return true; 290 | } 291 | if (type.IsSubclassOf(typeof(UnityEngine.Object))) 292 | { 293 | serializedType = SerializedPropertyType.ObjectReference; 294 | return true; 295 | } 296 | if (type.IsArray) 297 | { 298 | return GetSerializedTypeFromType(type.GetElementType(), out serializedType); 299 | } 300 | return _typemap.TryGetValue(type, out serializedType); 301 | } 302 | } 303 | 304 | public class PropertyField : MemberField 305 | { 306 | PropertyInfo _info; 307 | 308 | MethodInfo _getter; 309 | MethodInfo _setter; 310 | 311 | public PropertyInfo PropertyInfo 312 | { 313 | get { return _info; } 314 | } 315 | 316 | public PropertyField(System.Object instance, ShowInEditor attribute, SerializedPropertyType type, PropertyInfo info) 317 | : base(instance, attribute, type) 318 | { 319 | _info = info; 320 | 321 | _getter = _info.GetGetMethod(); 322 | _setter = _info.GetSetMethod(); 323 | } 324 | 325 | public override System.Object GetValue() 326 | { 327 | return _getter.Invoke(_obj, null); 328 | } 329 | 330 | public override void SetValue(System.Object value) 331 | { 332 | _setter.Invoke(_obj, new System.Object[] { value }); 333 | } 334 | 335 | public override string GetName() 336 | { 337 | return GetName(_info); 338 | } 339 | 340 | public override System.Type GetFieldType() 341 | { 342 | return _info.PropertyType; 343 | } 344 | 345 | public static bool IsReadOnly(ShowInEditor attribute, PropertyInfo info) 346 | { 347 | return attribute.Flags == ShowInEditorFlags.ReadOnly || !info.CanWrite; 348 | } 349 | 350 | public override bool IsReadOnly() 351 | { 352 | return IsReadOnly(_attribute, _info); 353 | } 354 | 355 | public static bool GetSerializedType(PropertyInfo info, out SerializedPropertyType propertyType) 356 | { 357 | return GetSerializedTypeFromType(info.PropertyType, out propertyType); 358 | } 359 | } 360 | 361 | public class FieldField : MemberField 362 | { 363 | protected FieldInfo _info; 364 | 365 | public FieldInfo FieldInfo 366 | { 367 | get { return _info; } 368 | } 369 | 370 | public FieldField(System.Object instance, ShowInEditor attribute, SerializedPropertyType type, FieldInfo info) 371 | : base(instance, attribute, type) 372 | { 373 | _info = info; 374 | } 375 | 376 | public override System.Object GetValue() 377 | { 378 | return _info.GetValue(_obj); 379 | } 380 | 381 | public override void SetValue(System.Object value) 382 | { 383 | _info.SetValue(_obj, value); 384 | } 385 | 386 | public override System.Type GetFieldType() 387 | { 388 | return _info.FieldType; 389 | } 390 | 391 | public override string GetName() 392 | { 393 | return GetName(_info); 394 | } 395 | 396 | public static bool IsReadOnly(ShowInEditor attribute, FieldInfo info) 397 | { 398 | if (attribute.Flags == ShowInEditorFlags.Default) 399 | return !info.IsPublic; 400 | return attribute.Flags == ShowInEditorFlags.ReadOnly; 401 | } 402 | 403 | public override bool IsReadOnly() 404 | { 405 | return IsReadOnly(_attribute, _info); 406 | } 407 | 408 | public static bool GetSerializedType(FieldInfo info, out SerializedPropertyType propertyType) 409 | { 410 | return GetSerializedTypeFromType(info.FieldType, out propertyType); 411 | } 412 | } 413 | 414 | public class ArrayFieldField : FieldField 415 | { 416 | public bool editor_showContent = true; 417 | 418 | public int Length 419 | { 420 | get 421 | { 422 | IList arr = (IList)this.GetValue(); 423 | if (arr != null) 424 | return arr.Count; 425 | return 0; 426 | } 427 | set 428 | { 429 | IList oldArr = (IList)this.GetValue(); 430 | if (value != oldArr.Count) 431 | { 432 | IList newArr = (IList)System.Activator.CreateInstance(_info.FieldType, value); 433 | for (int i = 0; i < (int)Mathf.Min(oldArr.Count, newArr.Count); ++i) 434 | newArr[i] = oldArr[i]; 435 | this.SetValue(newArr); 436 | } 437 | } 438 | } 439 | 440 | public ArrayFieldField(System.Object instance, ShowInEditor attribute, SerializedPropertyType type, FieldInfo info) 441 | : base(instance, attribute, type, info) 442 | { 443 | 444 | } 445 | 446 | public override System.Type GetFieldType() 447 | { 448 | return _info.FieldType.GetElementType(); 449 | } 450 | 451 | public new static bool GetSerializedType(FieldInfo info, out SerializedPropertyType propertyType) 452 | { 453 | return GetSerializedTypeFromType(info.FieldType.GetElementType(), out propertyType); 454 | } 455 | 456 | public void Add(System.Object obj) 457 | { 458 | IList arr = (IList)this.GetValue(); 459 | if (arr == null) 460 | { 461 | arr = (IList)System.Activator.CreateInstance(_info.FieldType, 0); 462 | } 463 | if(arr.IsReadOnly || arr.IsFixedSize) 464 | { 465 | IList newArr = (IList)System.Activator.CreateInstance(_info.FieldType, arr.Count + 1); 466 | for (int i = 0; i < arr.Count; ++i) 467 | newArr[i] = arr[i]; 468 | newArr[arr.Count] = obj; 469 | this.SetValue(newArr); 470 | } 471 | else 472 | { 473 | arr.Add(obj); 474 | } 475 | } 476 | 477 | public void Remove(System.Object obj) 478 | { 479 | IList arr = (IList)this.GetValue(); 480 | if (arr == null) 481 | return; 482 | 483 | if (arr.IsReadOnly || arr.IsFixedSize) 484 | { 485 | IList newArr = (IList)System.Activator.CreateInstance(_info.FieldType, arr.Count - 1); 486 | int index = 0; 487 | for (int i = 0; i < arr.Count; ++i) 488 | { 489 | if (arr[i] != obj) 490 | { 491 | newArr[index] = arr[i]; 492 | index++; 493 | } 494 | } 495 | this.SetValue(newArr); 496 | } 497 | else 498 | { 499 | arr.Remove(obj); 500 | } 501 | } 502 | 503 | public void RemoveAt(int atIndex) 504 | { 505 | IList arr = (IList)this.GetValue(); 506 | if (arr == null) 507 | return; 508 | 509 | if (arr.IsReadOnly || arr.IsFixedSize) 510 | { 511 | IList newArr = (IList)System.Activator.CreateInstance(_info.FieldType, arr.Count - 1); 512 | int index = 0; 513 | for (int i = 0; i < arr.Count; ++i) 514 | { 515 | if (i != atIndex) 516 | { 517 | newArr[index] = arr[i]; 518 | index++; 519 | } 520 | } 521 | this.SetValue(newArr); 522 | } 523 | else 524 | { 525 | arr.RemoveAt(atIndex); 526 | } 527 | } 528 | } 529 | 530 | public class MethodField : MemberField 531 | { 532 | protected MethodInfo _info; 533 | 534 | public MethodInfo FieldInfo 535 | { 536 | get { return _info; } 537 | } 538 | 539 | public MethodField(System.Object instance, ShowInEditor attribute, SerializedPropertyType type, MethodInfo info) 540 | : base(instance, attribute, type) 541 | { 542 | _info = info; 543 | } 544 | 545 | public void Invoke() 546 | { 547 | _info.Invoke(_obj, new object[0] { }); 548 | } 549 | 550 | public override System.Object GetValue() 551 | { 552 | return _info.Invoke(_obj, new object[0] { }); 553 | } 554 | 555 | public override void SetValue(System.Object value) 556 | { 557 | // 558 | } 559 | 560 | public override System.Type GetFieldType() 561 | { 562 | return _info.ReturnType; 563 | } 564 | 565 | public override string GetName() 566 | { 567 | return GetName(_info); 568 | } 569 | 570 | public static bool IsReadOnly(ShowInEditor attribute, MethodInfo info) 571 | { 572 | return true; 573 | } 574 | 575 | public override bool IsReadOnly() 576 | { 577 | return true; 578 | } 579 | 580 | public static bool GetSerializedType(MethodInfo info, out SerializedPropertyType propertyType) 581 | { 582 | return GetSerializedTypeFromType(info.ReturnType, out propertyType); 583 | } 584 | } 585 | 586 | public class ButtonGroupField : MethodField 587 | { 588 | protected MethodField[] _buttons; 589 | 590 | public MethodField[] Buttons 591 | { 592 | get { return _buttons; } 593 | } 594 | 595 | public ButtonGroupField(MethodField[] buttons) 596 | : base(null, null, SerializedPropertyType.Generic, null) 597 | { 598 | _buttons = buttons; 599 | _attribute = _buttons[0].Attribute; 600 | } 601 | } 602 | 603 | public class ObjectReferenceField : FieldField 604 | { 605 | protected MemberField[] _members; 606 | 607 | public bool editor_showContent = true; 608 | 609 | public MemberField[] Members 610 | { 611 | get { return _members; } 612 | } 613 | 614 | public ObjectReferenceField(System.Object instance, ShowInEditor attribute, SerializedPropertyType type, FieldInfo info, MemberField[] members) 615 | : base(instance, attribute, type, info) 616 | { 617 | _members = members; 618 | } 619 | 620 | public void BindRefernecedObject(System.Object obj) 621 | { 622 | foreach (MemberField mf in _members) 623 | { 624 | mf.Rebind(obj); 625 | } 626 | } 627 | } 628 | 629 | public class ArrayObjectReferenceField : ArrayFieldField 630 | { 631 | protected MemberField[] _members; 632 | 633 | public bool[] editor_ShowContents; 634 | 635 | public MemberField[] Members 636 | { 637 | get { return _members; } 638 | set { _members = value; } 639 | } 640 | 641 | public ArrayObjectReferenceField(System.Object instance, ShowInEditor attribute, SerializedPropertyType type, FieldInfo info, MemberField[] members) 642 | : base(instance, attribute, type, info) 643 | { 644 | _members = members; 645 | } 646 | 647 | public void BindRefernecedObject(System.Object obj) 648 | { 649 | foreach (MemberField mf in _members) 650 | { 651 | mf.Rebind(obj); 652 | } 653 | } 654 | } 655 | 656 | public static int DrawIntegerField(string name, object value, System.Type sysType, ShowInEditorRange range, ShowInEditorStyle style) 657 | { 658 | int v; 659 | if (style != ShowInEditorStyle.Slider || range == null) 660 | { 661 | v = EditorGUILayout.IntField(name, (int)value); 662 | if (range != null) 663 | v = (int)Mathf.Clamp(v, range.Min, range.Max); 664 | return v; 665 | } 666 | else 667 | { 668 | int vv = (int)value; 669 | v = (int)EditorGUILayout.Slider(name, (float)vv, range.Min, range.Max); 670 | return v; 671 | } 672 | } 673 | 674 | public static float DrawFloatField(string name, object value, System.Type sysType, ShowInEditorRange range, ShowInEditorStyle style) 675 | { 676 | float fv; 677 | if (sysType != typeof(double)) 678 | { 679 | fv = (float)value; 680 | } 681 | else 682 | { 683 | // aaaa 684 | double v = (double)value; 685 | fv = (float)v; 686 | } 687 | 688 | float rv; 689 | if (style != ShowInEditorStyle.Slider || range == null) 690 | { 691 | rv = EditorGUILayout.FloatField(name, fv); 692 | if (range != null) 693 | rv = Mathf.Clamp(rv, range.Min, range.Max); 694 | } 695 | else 696 | { 697 | rv = EditorGUILayout.Slider(name, fv, range.Min, range.Max); 698 | } 699 | return rv; 700 | } 701 | 702 | public static object DrawFieldElement(SerializedPropertyType type, string name, object value, System.Type sysType, ShowInEditorRange range, ShowInEditorStyle style) 703 | { 704 | switch (type) 705 | { 706 | case SerializedPropertyType.Integer: 707 | return DrawIntegerField(name, value, sysType, range, style); 708 | 709 | case SerializedPropertyType.Float: 710 | return DrawFloatField(name, value, sysType, range, style); 711 | 712 | case SerializedPropertyType.Boolean: 713 | return EditorGUILayout.Toggle(name, (bool)value); 714 | 715 | case SerializedPropertyType.String: 716 | return EditorGUILayout.TextField(name, (string)value); 717 | 718 | case SerializedPropertyType.Vector2: 719 | return EditorGUILayout.Vector2Field(name, (Vector2)value); 720 | 721 | case SerializedPropertyType.Vector3: 722 | return EditorGUILayout.Vector3Field(name, (Vector3)value); 723 | 724 | case SerializedPropertyType.Vector4: 725 | return EditorGUILayout.Vector4Field(name, (Vector4)value); 726 | 727 | case SerializedPropertyType.Quaternion: 728 | { 729 | Vector4 v = EditorGUILayout.Vector4Field(name, (Vector4)value); 730 | Quaternion q = new Quaternion(v.x, v.y, v.z, v.w); 731 | return q; 732 | } 733 | 734 | case SerializedPropertyType.Enum: 735 | return EditorGUILayout.EnumPopup(name, (System.Enum)value); 736 | 737 | case SerializedPropertyType.Color: 738 | return EditorGUILayout.ColorField(name, (Color)value); 739 | 740 | case SerializedPropertyType.Rect: 741 | return EditorGUILayout.RectField(name, (Rect)value); 742 | 743 | case SerializedPropertyType.Bounds: 744 | return EditorGUILayout.BoundsField(name, (Bounds)value); 745 | 746 | case SerializedPropertyType.Gradient: 747 | Gradient g = (Gradient)value; 748 | EditorGUILayout.LabelField(name, g.ToString()); 749 | break; 750 | 751 | case SerializedPropertyType.AnimationCurve: 752 | return EditorGUILayout.CurveField(name, (AnimationCurve)value); 753 | 754 | case SerializedPropertyType.ObjectReference: 755 | { 756 | if (typeof(UnityEngine.Object).IsAssignableFrom(sysType)) 757 | { 758 | return EditorGUILayout.ObjectField(name, (UnityEngine.Object)value, sysType, true); 759 | } 760 | } 761 | break; 762 | 763 | default: 764 | break; 765 | } 766 | 767 | return null; 768 | } 769 | 770 | public static object DrawFieldElementCompact(SerializedPropertyType type, object value, System.Type sysType, ShowInEditorRange range, ShowInEditorStyle style) 771 | { 772 | switch (type) 773 | { 774 | case SerializedPropertyType.Integer: 775 | return DrawIntegerField("", value, sysType, range, style); 776 | 777 | case SerializedPropertyType.Float: 778 | return DrawFloatField("", value, sysType, range, style); 779 | 780 | case SerializedPropertyType.Boolean: 781 | // for some reason, editor gui layout doesn't work here 782 | return GUILayout.Toggle((bool)value, new GUIContent(""), new GUILayoutOption[] { GUILayout.Width(24) }); 783 | 784 | case SerializedPropertyType.String: 785 | return EditorGUILayout.TextField((string)value); 786 | 787 | case SerializedPropertyType.Enum: 788 | return EditorGUILayout.EnumPopup((System.Enum)value); 789 | 790 | default: 791 | break; 792 | } 793 | 794 | return null; 795 | } 796 | 797 | public static void DrawArrayField(ArrayFieldField field) 798 | { 799 | IList arr = (IList)field.GetValue(); 800 | 801 | field.editor_showContent = EditorGUILayout.Foldout(field.editor_showContent, field.GetName() + System.String.Format(": ({0} Elements)", arr != null ? arr.Count : 0)); 802 | 803 | if (field.editor_showContent) 804 | { 805 | EditorGUI.indentLevel = 1 + field.IndentLevel; 806 | 807 | if (arr != null) 808 | { 809 | if (field.IsReadOnly()) 810 | { 811 | if (arr.Count == 0) 812 | EditorGUILayout.LabelField("The array is empty"); 813 | 814 | for (int i = 0; i < arr.Count; ++i) 815 | { 816 | System.Object v = arr[i]; 817 | if(v != null) 818 | EditorGUILayout.LabelField(string.Format("[{0}]", i), arr[i].ToString()); 819 | else 820 | EditorGUILayout.LabelField(string.Format("[{0}]", i), "(null)"); 821 | } 822 | } 823 | else 824 | { 825 | System.Type type = field.GetFieldType(); 826 | if (field.CompactArrayLayout && type.IsPrimitive) 827 | { 828 | EditorGUILayout.BeginHorizontal(); 829 | 830 | if (field.Type == SerializedPropertyType.Boolean) 831 | { 832 | // for some reason, editor gui layout doesn't work here 833 | GUILayout.Space(EditorGUI.indentLevel * 24); 834 | } 835 | for (int i = 0; i < arr.Count; ++i) 836 | { 837 | arr[i] = DrawFieldElementCompact(field.Type, arr[i], type, field.ValueRange, field.Style); 838 | } 839 | 840 | EditorGUILayout.EndHorizontal(); 841 | } 842 | else 843 | { 844 | int indexToRemove = -1; 845 | for (int i = 0; i < arr.Count; ++i) 846 | { 847 | EditorGUILayout.BeginHorizontal(); 848 | if (field.CanModifyArrayLength) 849 | { 850 | if (GUILayout.Button("-", new GUILayoutOption[] { GUILayout.Width(24) })) { 851 | indexToRemove = i; 852 | } 853 | } 854 | arr[i] = DrawFieldElement(field.Type, string.Format("[{0}]", i), arr[i], type, field.ValueRange, field.Style); 855 | 856 | EditorGUILayout.EndHorizontal(); 857 | } 858 | 859 | if (indexToRemove != -1) 860 | { 861 | field.RemoveAt(indexToRemove); 862 | } 863 | 864 | EditorGUILayout.BeginHorizontal(); 865 | 866 | GUILayout.FlexibleSpace(); 867 | 868 | if(GUILayout.Button("Add", new GUILayoutOption[] { GUILayout.Width(80) })) 869 | { 870 | field.Add(System.Activator.CreateInstance(type)); 871 | } 872 | 873 | EditorGUILayout.EndHorizontal(); 874 | } 875 | 876 | } 877 | } 878 | } 879 | } 880 | 881 | public static void DrawMethodField(MethodField field) 882 | { 883 | if (field.Style != ShowInEditorStyle.Button) 884 | { 885 | object v = field.GetValue(); 886 | 887 | if (v != null) 888 | { 889 | if (v.GetType().IsArray) 890 | { 891 | IList arr = (IList)v; 892 | EditorGUILayout.LabelField(field.GetName() + System.String.Format(": ({0} Elements)", arr.Count)); 893 | 894 | EditorGUI.indentLevel = 1 + field.IndentLevel; 895 | for (int i = 0; i < arr.Count; ++i) 896 | { 897 | EditorGUILayout.LabelField(string.Format("[{0}]", i), arr[i].ToString()); 898 | } 899 | } 900 | else 901 | { 902 | EditorGUILayout.LabelField(field.GetName(), v.ToString()); 903 | } 904 | } 905 | else 906 | { 907 | EditorGUILayout.LabelField(field.GetName(), "null"); 908 | } 909 | } 910 | else 911 | { 912 | if (GUILayout.Button(field.GetName())) 913 | { 914 | field.Invoke(); 915 | } 916 | } 917 | } 918 | 919 | public static void DrawGenericField(MemberField field) 920 | { 921 | EditorGUILayout.BeginHorizontal(); 922 | 923 | if (field.IsReadOnly()) 924 | { 925 | System.Object v = field.GetValue(); 926 | if (v != null) 927 | EditorGUILayout.LabelField(field.GetName(), field.GetValue().ToString()); 928 | else 929 | EditorGUILayout.LabelField(field.GetName(), "(null)"); 930 | 931 | EditorGUILayout.EndHorizontal(); 932 | return; 933 | } 934 | field.SetValue(DrawFieldElement(field.Type, field.GetName(), field.GetValue(), field.GetFieldType(), field.ValueRange, field.Style)); 935 | 936 | EditorGUILayout.EndHorizontal(); 937 | } 938 | 939 | public static string GetObjectName(ref System.Object obj) 940 | { 941 | if (obj == null) 942 | return "(null)"; 943 | 944 | if (obj is UnityEngine.Component) 945 | return (obj as UnityEngine.Component).gameObject.name + "."; 946 | else if (obj is UnityEngine.GameObject) 947 | return (obj as UnityEngine.GameObject).name + "."; 948 | return obj.GetType().Name; 949 | } 950 | 951 | public static void DrawObjectReference(ref System.Object obj, MemberField[] fields, Color defaultColor) 952 | { 953 | if (obj != null) 954 | { 955 | foreach (MemberField memberField in fields) 956 | { 957 | //memberField.NamePrefix = namePrefix; 958 | DrawField(memberField, defaultColor); 959 | } 960 | } 961 | else 962 | { 963 | EditorGUILayout.LabelField("(null)"); 964 | } 965 | } 966 | 967 | public static void DrawObjectReferenceField(ObjectReferenceField field, Color defaultColor) 968 | { 969 | System.Object obj = field.GetValue(); 970 | 971 | field.editor_showContent = EditorGUILayout.Foldout(field.editor_showContent, 972 | field.GetName()); 973 | 974 | if (field.editor_showContent) 975 | { 976 | field.BindRefernecedObject(obj); 977 | DrawObjectReference(ref obj, field.Members, defaultColor); 978 | } 979 | } 980 | 981 | public static void DrawArrayObjectReferenceField(ArrayObjectReferenceField field, Color defaultColor) 982 | { 983 | object v = field.GetValue(); 984 | System.Array arr = (System.Array)v; 985 | 986 | EditorGUILayout.BeginHorizontal(); 987 | 988 | field.editor_showContent = EditorGUILayout.Foldout(field.editor_showContent, 989 | field.GetName() + System.String.Format(": ({0} Elements)", arr != null ? arr.Length : 0)); 990 | 991 | GUILayout.FlexibleSpace(); 992 | 993 | if (!field.IsArrayBaseType && field.CanModifyArrayLength) 994 | { 995 | if (GUILayout.Button("Add", new GUILayoutOption[] { GUILayout.Width(80) })) 996 | { 997 | System.Object instance = System.Activator.CreateInstance(field.GetFieldType()); 998 | field.Add(instance); 999 | } 1000 | } 1001 | else 1002 | { 1003 | if (GUILayout.Button("Add...", new GUILayoutOption[] { GUILayout.Width(80) })) 1004 | { 1005 | System.Type type = field.GetFieldType(); 1006 | var typeNames = type.Assembly.GetTypes() 1007 | .Where(t => t.IsSubclassOf(type) && !t.IsAbstract) 1008 | .Select(t => t.Name); 1009 | 1010 | UnityEditor.GenericMenu menu = new GenericMenu(); 1011 | foreach (var name in typeNames) 1012 | { 1013 | menu.AddItem(new GUIContent(name), false, ((object o) => 1014 | { 1015 | System.Type t = type.Assembly.GetType(type.Namespace + "." + name); 1016 | System.Object inst = null; 1017 | if (t.IsSubclassOf(typeof(UnityEngine.MonoBehaviour))) 1018 | { 1019 | if (field.ReferenceObject is GameObject) 1020 | inst = ((GameObject)field.ReferenceObject).AddComponent(t); 1021 | else if (field.ReferenceObject is MonoBehaviour) 1022 | inst = ((MonoBehaviour)field.ReferenceObject).gameObject.AddComponent(t); 1023 | else 1024 | Debug.LogError("[ShowInEditor] Cannot add comopnent in object references"); 1025 | 1026 | if (inst != null) 1027 | { 1028 | ((MonoBehaviour)inst).hideFlags = HideFlags.HideInInspector; 1029 | } 1030 | } 1031 | else 1032 | { 1033 | inst = System.Activator.CreateInstance(t); ; 1034 | } 1035 | 1036 | field.Members = GetFieldsFromType(t, null, field.IndentLevel + 2); 1037 | field.Add(inst); 1038 | }), name); 1039 | } 1040 | 1041 | menu.ShowAsContext(); 1042 | } 1043 | 1044 | } 1045 | 1046 | EditorGUILayout.EndHorizontal(); 1047 | if (field.editor_showContent) 1048 | { 1049 | EditorGUI.indentLevel = 1 + field.IndentLevel; 1050 | 1051 | if (v != null) 1052 | { 1053 | if (field.editor_ShowContents == null || field.editor_ShowContents.Length != arr.Length) 1054 | { 1055 | field.editor_ShowContents = Enumerable.Repeat(true, arr.Length).ToArray(); 1056 | } 1057 | 1058 | int indexToRemove = -1; 1059 | for (int i = 0; i < arr.Length; ++i) 1060 | { 1061 | GUILayout.BeginHorizontal(); 1062 | 1063 | System.Object obj = arr.GetValue(i); 1064 | 1065 | bool showObj = field.editor_ShowContents[i]; 1066 | showObj = EditorGUILayout.Foldout(showObj, GetObjectName(ref obj)); 1067 | field.editor_ShowContents[i] = showObj; 1068 | 1069 | if (field.CanModifyArrayLength) 1070 | { 1071 | if (GUILayout.Button("-", new GUILayoutOption[] { GUILayout.Width(24) })) 1072 | { 1073 | indexToRemove = i; 1074 | } 1075 | } 1076 | GUILayout.EndHorizontal(); 1077 | 1078 | if (showObj) 1079 | { 1080 | field.BindRefernecedObject(obj); 1081 | DrawObjectReference(ref obj, field.Members, defaultColor); 1082 | } 1083 | 1084 | if (field.GetFieldType().IsValueType) 1085 | { 1086 | arr.SetValue(obj, i); 1087 | } 1088 | 1089 | EditorGUI.indentLevel = 1 + field.IndentLevel; 1090 | } 1091 | 1092 | if (indexToRemove != -1) 1093 | { 1094 | field.RemoveAt(indexToRemove); 1095 | } 1096 | } 1097 | 1098 | } 1099 | 1100 | } 1101 | 1102 | public static void DrawButtonGroup(ButtonGroupField field) 1103 | { 1104 | GUILayout.BeginHorizontal(); 1105 | foreach (MethodField button in field.Buttons) 1106 | { 1107 | if (GUILayout.Button(button.GetName())) 1108 | { 1109 | button.Invoke(); 1110 | } 1111 | } 1112 | GUILayout.EndHorizontal(); 1113 | } 1114 | 1115 | public static void DrawField(MemberField field, Color defaultColor) 1116 | { 1117 | EditorGUI.indentLevel = field.IndentLevel; 1118 | 1119 | if (field.Comment.Length > 0) 1120 | { 1121 | if (field.IsDefaultCommentColor) 1122 | GUI.color = defaultColor; 1123 | else 1124 | GUI.color = field.CommentColor; 1125 | EditorGUILayout.HelpBox(field.Comment, field.CommentMessageType); 1126 | } 1127 | 1128 | if (field.IsDefaultColor) 1129 | GUI.color = defaultColor; 1130 | else 1131 | GUI.color = field.Color; 1132 | 1133 | if (field is ArrayObjectReferenceField) 1134 | { 1135 | DrawArrayObjectReferenceField((ArrayObjectReferenceField)field, defaultColor); 1136 | } 1137 | else if (field is ArrayFieldField) 1138 | { 1139 | DrawArrayField((ArrayFieldField)field); 1140 | } 1141 | else if(field is ButtonGroupField) 1142 | { 1143 | DrawButtonGroup((ButtonGroupField)field); 1144 | } 1145 | else if (field is MethodField) 1146 | { 1147 | DrawMethodField((MethodField)field); 1148 | } 1149 | else if (field is ObjectReferenceField) 1150 | { 1151 | DrawObjectReferenceField((ObjectReferenceField)field, defaultColor); 1152 | } 1153 | else 1154 | { 1155 | DrawGenericField(field); 1156 | } 1157 | } 1158 | 1159 | public static void DrawFields(MemberField[] fields) 1160 | { 1161 | Color defaultColor = GUI.color; 1162 | 1163 | EditorGUILayout.BeginVertical(); 1164 | 1165 | foreach (MemberField field in fields) 1166 | { 1167 | DrawField(field, defaultColor); 1168 | } 1169 | 1170 | EditorGUILayout.EndVertical(); 1171 | 1172 | GUI.color = defaultColor; 1173 | } 1174 | 1175 | public static MemberField[] GetFieldsFromType(System.Type type, System.Object obj, int level = 0) 1176 | { 1177 | List fields = new List(); 1178 | Dictionary> buttonFields = new Dictionary>(); 1179 | 1180 | BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static; 1181 | 1182 | foreach (MemberInfo member in type.GetMembers(bindingFlags)) 1183 | { 1184 | ShowInEditor attribute = member.GetCustomAttributes(false).OfType().FirstOrDefault(); 1185 | 1186 | if(level > 0 && 1187 | attribute == null && 1188 | (member is FieldInfo) && 1189 | ((FieldInfo)member).IsPublic) 1190 | { 1191 | attribute = new ShowInEditor(); 1192 | } 1193 | 1194 | if (attribute != null) 1195 | { 1196 | if (member is PropertyInfo) 1197 | { 1198 | PropertyInfo property = member as PropertyInfo; 1199 | if (!property.CanRead) 1200 | continue; 1201 | 1202 | // skip array property, to do (or is it neccessary?) 1203 | if (property.PropertyType.IsArray) 1204 | continue; 1205 | 1206 | if (attribute != null) 1207 | { 1208 | SerializedPropertyType serializedType = SerializedPropertyType.Integer; 1209 | bool isKnownType = PropertyField.GetSerializedType(property, out serializedType); 1210 | 1211 | if (!isKnownType) 1212 | attribute.Flags = ShowInEditorFlags.ReadOnly; 1213 | 1214 | fields.Add(new PropertyField(obj, attribute, serializedType, property)); 1215 | } 1216 | } 1217 | else if (member is FieldInfo) 1218 | { 1219 | FieldInfo field = member as FieldInfo; 1220 | 1221 | System.Type realType = field.FieldType; 1222 | if (realType.IsArray) 1223 | realType = field.FieldType.GetElementType(); 1224 | 1225 | bool isObjectRef = !FieldField.IsReadOnly(attribute, field); 1226 | 1227 | isObjectRef &= (realType.IsClass || 1228 | (realType.IsValueType && !realType.IsEnum && !realType.IsPrimitive)); 1229 | 1230 | if (isObjectRef) 1231 | { 1232 | ShowInEditor showInEditor = realType.GetCustomAttributes(false).OfType().FirstOrDefault(); 1233 | 1234 | isObjectRef &= (showInEditor != null); 1235 | } 1236 | 1237 | MemberField mf; 1238 | if (isObjectRef) 1239 | { 1240 | MemberField[] memberFields = GetFieldsFromType(realType, null, level + 2); 1241 | 1242 | if (!field.FieldType.IsArray) 1243 | { 1244 | mf = (new ObjectReferenceField(obj, attribute, SerializedPropertyType.ObjectReference, field, memberFields)); 1245 | } 1246 | else 1247 | { 1248 | mf = (new ArrayObjectReferenceField(obj, attribute, SerializedPropertyType.ObjectReference, field, memberFields)); 1249 | } 1250 | } 1251 | else 1252 | { 1253 | SerializedPropertyType serializedType = SerializedPropertyType.Integer; 1254 | bool isKnownType = FieldField.GetSerializedType(field, out serializedType); 1255 | 1256 | if (!isKnownType) 1257 | attribute.Flags = ShowInEditorFlags.ReadOnly; 1258 | 1259 | if (!field.FieldType.IsArray) 1260 | mf = new FieldField(obj, attribute, serializedType, field); 1261 | else 1262 | mf = new ArrayFieldField(obj, attribute, serializedType, field); 1263 | } 1264 | 1265 | if (field.IsPublic) 1266 | attribute.CanModifyArrayLength = true; 1267 | 1268 | if (mf != null) 1269 | { 1270 | if (mf.IndentLevel == 0) 1271 | mf.IndentLevel = level; 1272 | 1273 | fields.Add(mf); 1274 | } 1275 | } 1276 | else if (member is MethodInfo) 1277 | { 1278 | MethodInfo method = member as MethodInfo; 1279 | 1280 | if (method.GetParameters().Length == 0) 1281 | { 1282 | if (method.ReturnType != typeof(void)) 1283 | { 1284 | fields.Add(new MethodField(obj, attribute, SerializedPropertyType.Generic, method)); 1285 | } 1286 | else if (attribute.Style == ShowInEditorStyle.Button) 1287 | { 1288 | if (attribute.Group == -1) 1289 | { 1290 | fields.Add(new MethodField(obj, attribute, SerializedPropertyType.Generic, method)); 1291 | } 1292 | else 1293 | { 1294 | List group; 1295 | if (!buttonFields.TryGetValue(attribute.Group, out group)) 1296 | { 1297 | group = new List(); 1298 | buttonFields.Add(attribute.Group, group); 1299 | } 1300 | group.Add(new MethodField(obj, attribute, SerializedPropertyType.Generic, method)); 1301 | } 1302 | } 1303 | else 1304 | Debug.LogError("[ShowInEditor] Method that returns nothing cannot be shown in the editor"); 1305 | } 1306 | else 1307 | { 1308 | Debug.LogError("[ShowInEditor] Method with arguments cannot be shown in the editor"); 1309 | } 1310 | } 1311 | } 1312 | } 1313 | 1314 | foreach (List buttonGroup in buttonFields.Values) 1315 | { 1316 | fields.Add(new ButtonGroupField(buttonGroup.ToArray())); 1317 | } 1318 | return fields.ToArray(); 1319 | } 1320 | 1321 | public static MemberField[] GetFields(System.Object obj, int level = 0) 1322 | { 1323 | return GetFieldsFromType(obj.GetType(), obj, level); 1324 | } 1325 | } 1326 | 1327 | public abstract class AUEditor : Editor 1328 | { 1329 | public bool forceRepaint = false; 1330 | public bool drawDefaultFields = true; 1331 | 1332 | EditorHelper.MemberField[] _properties = null; 1333 | 1334 | void OnEnable() 1335 | { 1336 | _properties = EditorHelper.GetFields(this.target); 1337 | } 1338 | 1339 | public override void OnInspectorGUI() 1340 | { 1341 | if (this.target == null) 1342 | return; 1343 | 1344 | if (_properties == null) 1345 | { 1346 | _properties = EditorHelper.GetFields(this.target); 1347 | } 1348 | 1349 | if (drawDefaultFields) 1350 | { 1351 | this.DrawDefaultInspector(); 1352 | 1353 | EditorGUILayout.HelpBox("ShowInEditor Fields: ", MessageType.None); 1354 | } 1355 | 1356 | if (_properties == null) 1357 | return; 1358 | 1359 | EditorHelper.DrawFields(_properties); 1360 | 1361 | if (forceRepaint && Application.isPlaying) 1362 | { 1363 | Repaint(); 1364 | } 1365 | } 1366 | 1367 | } 1368 | 1369 | #endif 1370 | } 1371 | 1372 | -------------------------------------------------------------------------------- /Assets/Plugins/AU/Editor/ShowInEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4dab9982b6569eb49960f30d8f68d6e8 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Plugins/AU/Sample.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fa17ca9aea1903248ac15d3c4abb8d3a 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Plugins/AU/Sample/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 74b3854067d86374d84a701b413c5300 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Plugins/AU/Sample/Editor/TestEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using UnityEditor; 4 | 5 | [CustomEditor(typeof(ShowInEditorTest))] 6 | class TestEditor : AU.AUEditor 7 | { 8 | public TestEditor() 9 | { 10 | /** 11 | * Force repaint when force the editor to repaint each editor frame in play mode 12 | * This is useful when members will be changed frequently 13 | * Since the editor will not auto update when the member is not changed by the user 14 | */ 15 | // forceRepaint = true; 16 | 17 | /** 18 | * Draw default inspector or not 19 | */ 20 | drawDefaultFields = false; 21 | } 22 | } -------------------------------------------------------------------------------- /Assets/Plugins/AU/Sample/Editor/TestEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3125b9e76c55a2b429950c323b31426d 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Plugins/AU/Sample/SampleComponent.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | [AU.ShowInEditor] 5 | public class SampleComponent : MonoBehaviour { 6 | 7 | [AU.ShowInEditor(CompactArrayLayout = true)] 8 | public bool[] measures = new bool[8]; 9 | 10 | 11 | } 12 | -------------------------------------------------------------------------------- /Assets/Plugins/AU/Sample/SampleComponent.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 85a12629e1d0a4e409c2f2c45867e0c6 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Plugins/AU/Sample/ShowInEditorTest.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using AU; 4 | 5 | [ShowInEditor] 6 | class SimpleStruct 7 | { 8 | [ShowInEditor(Comment = "By default, only public members are modifiable")] 9 | public int i = 42; 10 | 11 | [ShowInEditor(Comment = "But you can modify it with flags = ShowInEditorFlags.ReadWrite", Flags = ShowInEditorFlags.ReadWrite)] 12 | string xixi = "XD"; 13 | } 14 | 15 | [ExecuteInEditMode] 16 | public class ShowInEditorTest : MonoBehaviour { 17 | 18 | [ShowInEditor(Comment = "Readonly private field (default)", CommentColor = ShowInEditorColor.Green)] 19 | int privateField = 42; 20 | 21 | [ShowInEditor(Comment = "ReadWrite private field", CommentColor = ShowInEditorColor.Green, Flags = ShowInEditorFlags.ReadWrite)] 22 | int rwPrivateField = 42; 23 | 24 | [ShowInEditor(Comment = "Struct refrence", CommentColor = ShowInEditorColor.Red, Flags = ShowInEditorFlags.ReadWrite)] 25 | SimpleStruct structReference = new SimpleStruct(); 26 | 27 | [ShowInEditor(Comment = "Component refrence array (Execute in editor mode)", CommentColor = ShowInEditorColor.Red, Flags = ShowInEditorFlags.ReadWrite)] 28 | SampleComponent[] componentReferenceArray; 29 | 30 | 31 | [ShowInEditor(CanModifyArrayLength = true, Flags = ShowInEditorFlags.ReadWrite, Comment = "Modifiable array (and serializable)", CommentColor = ShowInEditorColor.Yellow, Name = "Array of GameObjects")] 32 | [SerializeField] 33 | GameObject[] array; 34 | 35 | #region Properties 36 | 37 | string _someProperty = "Hello World"; 38 | float _rwProperty = 333; 39 | 40 | [ShowInEditor(Comment = "Readonly property", CommentColor = ShowInEditorColor.Cyan)] 41 | public string SomeProperty 42 | { 43 | get { return _someProperty; } 44 | } 45 | 46 | 47 | [ShowInEditor(Comment = "RW property", CommentColor = ShowInEditorColor.Cyan)] 48 | public float RWProperty 49 | { 50 | get { return _rwProperty; } 51 | set { _rwProperty = value; } 52 | } 53 | 54 | #endregion 55 | 56 | [ShowInEditor(Comment = "This is a method, and it will be readonly", CommentColor = ShowInEditorColor.Magenta)] 57 | public override string ToString() 58 | { 59 | return base.ToString(); 60 | } 61 | 62 | [ShowInEditor(Comment = "this is method call button", Style = ShowInEditorStyle.Button)] 63 | public void TestButton() 64 | { 65 | Debug.Log("Hello World"); 66 | } 67 | 68 | [ShowInEditor(Comment = "this is a button group", Style = ShowInEditorStyle.Button, Group = 1)] 69 | public void TestButton1() 70 | { 71 | Debug.Log("Hello World 1"); 72 | } 73 | 74 | [ShowInEditor(Style = ShowInEditorStyle.Button, Group = 1)] 75 | public void TestButton2() 76 | { 77 | Debug.Log("Hello World 2"); 78 | } 79 | 80 | [ShowInEditor(Style = ShowInEditorStyle.Button, Group = 1)] 81 | public void TestButton3() 82 | { 83 | Debug.Log("Hello World 3"); 84 | } 85 | 86 | [ShowInEditor(RangeMin = 0, RangeMax = 100)] 87 | public int intWithRange; 88 | 89 | [ShowInEditor(RangeMin = 0, RangeMax = 50, Style = ShowInEditorStyle.Slider)] 90 | public int intSlider; 91 | 92 | public void Start() 93 | { 94 | componentReferenceArray = GetComponentsInChildren(); 95 | 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /Assets/Plugins/AU/Sample/ShowInEditorTest.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c74fad7fbccd77c4a8e0a82f98de3be6 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Plugins/AU/Sample/Test.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkfall/ShowInEditor/f531d084c927f62260784e30e7d70076b1d0c060/Assets/Plugins/AU/Sample/Test.unity -------------------------------------------------------------------------------- /Assets/Plugins/AU/Sample/Test.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 143f952c0f216fb4ca468b1e0504e77e 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Ruiwei Bu (darkfall) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /demo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkfall/ShowInEditor/f531d084c927f62260784e30e7d70076b1d0c060/demo.jpg -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | __Brief__ 2 | 3 | A simple editor inspector enhancement for Unity3D. 4 | 5 | Adding support for showing public & non-public properties, fields, methods and static members in the editor inspector. 6 | 7 | Support nested objects. 8 | 9 | License: MIT 10 | 11 | ![](https://github.com/darkfall/ShowInEditor/blob/master/demo.jpg) 12 | 13 | __How to__ 14 | 15 | * Add [ShowInEditor] attribute to the members you want to show in the inspector. For example: 16 | 17 | [ShowInEditor(Comment = "This is a private field")] 18 | int privateField = 42; 19 | 20 | * Create a custom editor for the type and inherit from AU.AUEditor 21 | 22 | [CustomEditor(typeof(AType))] 23 | class AEditor : AU.AUEditor 24 | { 25 | 26 | } 27 | 28 | * Done! 29 | 30 | __Attribute Options__ 31 | 32 | * Comment (string) 33 | 34 | Comment will be shown above the field 35 | 36 | * CommentType (ShowInEditorMessagetype) 37 | 38 | Message type of the comment helpbox 39 | 40 | * Name (string) 41 | 42 | Override the name of the field 43 | 44 | * CommentColor (ShowInEditorColor) 45 | 46 | Color of the comment file 47 | 48 | * FieldColor (ShowInEditorColor) 49 | 50 | Color of the field 51 | 52 | * CanModifyArrayLength (bool) 53 | 54 | When the member is an array, can the user modify the length of the array in the inspector or not. Default is __false__ 55 | 56 | * CompressArrayLayout (bool) 57 | 58 | When the member is an array, compress the array layout into a horizontal group to save space. Only supports primitive types. 59 | 60 | * Style (ShowInEditorStyle) 61 | 62 | Default, Button, Slider 63 | 64 | * Group 65 | 66 | When the member is a method and its a button, group the button horizontally by the group index. Default is -1 means no group at all. 67 | 68 | * RangeMin/RangeMax 69 | 70 | Range of int / float values, also serves as range min / max when the style is slider 71 | 72 | __Nested Object__ 73 | 74 | If you want custom structs/classes/components also showing in the inspector, the type of the object must also be decorated by the [ShowInEditor] attribute. For example: 75 | 76 | [ShowInEditor] 77 | class SimpleClass 78 | { 79 | [ShowInEditor(Comment = "By default, only public members are modifiable")] 80 | public int i = 42; 81 | 82 | [ShowInEditor(Comment = "But you can modify it with flags = ShowInEditorFlags.ReadWrite", Flags = ShowInEditorFlags.ReadWrite)] 83 | string xixi = "XD"; 84 | } 85 | 86 | --------------------------------------------------------------------------------