Forked from LotteMakesStuff/AutohookAttribute.cs
Last active
October 1, 2019 04:27
-
-
Save codeimpossible/e7629352059441ffd7cd20e212e098b8 to your computer and use it in GitHub Desktop.
Revisions
-
codeimpossible revised this gist
Oct 1, 2019 . 3 changed files with 35 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,17 @@ // NOTE DONT put in an editor folder! using UnityEngine; public enum AutohookSearchArea { Self, Parent, Children } public class AutohookAttribute : PropertyAttribute { public AutohookSearchArea SearchArea { get; private set; } public AutohookAttribute(AutohookSearchArea searchArea = AutohookSearchArea.Self) { SearchArea = searchArea; } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -46,6 +46,7 @@ public override float GetPropertyHeight(SerializedProperty property, GUIContent private Component FindAutohookTarget(SerializedProperty property) { var root = property.serializedObject; var attribute = PropertyUtility.GetAttribute<AutohookAttribute>(property); if (root.targetObject is Component) { @@ -54,7 +55,12 @@ private Component FindAutohookTarget(SerializedProperty property) // ...then use GetComponent(type) to see if there is one on our object. var component = (Component)root.targetObject; switch (attribute.SearchArea) { case AutohookSearchArea.Self: return component.GetComponent(type); case AutohookSearchArea.Parent: return component.GetComponentInParent(type); case AutohookSearchArea.Children: return component.GetComponentInChildren(type); } } else { @@ -79,4 +85,16 @@ private static System.Type GetTypeFromProperty(SerializedProperty property) // ... using that we can return the raw .net type! return fieldInfo.FieldType; } /// <summary> /// Uses reflection to get the attribute from a serialized property /// </summary> /// <param name="property"></param> /// <returns></returns> public static T GetAttribute<T>(SerializedProperty property) where T : Attribute { FieldInfo fieldInfo = ReflectionUtility.GetField(GetTargetObject(property), property.name); T[] attributes = (T[])fieldInfo.GetCustomAttributes(typeof(T), true); return attributes.Length > 0 ? attributes[0] : null; } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,9 +2,12 @@ heres a tiny little example of how to use it ```C# public class AutohookTest : MonoBehaviour { [Autohook] // <-- will match Rigidbody on the current gameobject public Rigidbody rigidbody; [Autohook(AutohookSearchArea.Children)] // <-- will search children for first AudioSource public AudioSource audio; // Update is called once per frame void Update() { @@ -13,6 +16,5 @@ public class AutohookTest : MonoBehaviour } } ``` The `AutoHook` attribute was originally coded by [LotteMakesStuff](https://gist.github.com/LotteMakesStuff). If you find it usefule you should [support them on ko-fi](https://ko-fi.com/A08215TT)! -
LotteMakesStuff revised this gist
Apr 5, 2019 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,7 +2,7 @@ heres a tiny little example of how to use it ```C# public class AutohookTest : MonoBehaviour { [Autohook] // <-- yeah its that easy! public Rigidbody rigidbody; // Update is called once per frame -
LotteMakesStuff revised this gist
Apr 5, 2019 . 1 changed file with 18 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,18 @@ heres a tiny little example of how to use it ```C# public class AutohookTest : MonoBehaviour { [Autohook] public Rigidbody rigidbody; // Update is called once per frame void Update() { // do something rigidbody.AddForce(Vector3.up); } } ``` You can watch a demo of this in action here https://youtu.be/faVt09NGzws [](https://ko-fi.com/A08215TT) -
LotteMakesStuff revised this gist
Apr 5, 2019 . No changes.There are no files selected for viewing
-
LotteMakesStuff revised this gist
Apr 5, 2019 . No changes.There are no files selected for viewing
-
LotteMakesStuff created this gist
Apr 5, 2019 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,6 @@ // NOTE DONT put in an editor folder! using UnityEngine; public class AutohookAttribute : PropertyAttribute { } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,82 @@ // NOTE put in a Editor folder using UnityEditor; using UnityEngine; [CustomPropertyDrawer(typeof(AutohookAttribute))] public class AutohookPropertyDrawer : PropertyDrawer { public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { // First, lets attempt to find a valid component we could hook into this property var component = FindAutohookTarget(property); if (component != null) { // if we found something, AND the autohook is empty, lets slot it. // the reason were straight up looking for a target component is so we // can skip drawing the field if theres a valid autohook. // this just looks a bit cleaner but isnt particularly safe. YMMV if (property.objectReferenceValue == null) property.objectReferenceValue = component; return; } // havent found one? lets just draw the default property field, let the user manually // hook something in. EditorGUI.PropertyField(position, property, label); } public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { // if theres a valid autohook target we skip drawing, so height is zeroed var component = FindAutohookTarget(property); if (component != null) return 0; // otherwise, return its default height (which should be the standard 16px unity usually uses) return base.GetPropertyHeight(property, label); } /// <summary> /// Takes a SerializedProperty and finds a local component that can be slotted into it. /// Local in this context means its a component attached to the same GameObject. /// This could easily be changed to use GetComponentInParent/GetComponentInChildren /// </summary> /// <param name="property"></param> /// <returns></returns> private Component FindAutohookTarget(SerializedProperty property) { var root = property.serializedObject; if (root.targetObject is Component) { // first, lets find the type of component were trying to autohook... var type = GetTypeFromProperty(property); // ...then use GetComponent(type) to see if there is one on our object. var component = (Component)root.targetObject; return component.GetComponent(type); } else { Debug.Log("OH NO handle fails here better pls"); } return null; } /// <summary> /// Uses reflection to get the type from a serialized property /// </summary> /// <param name="property"></param> /// <returns></returns> private static System.Type GetTypeFromProperty(SerializedProperty property) { // first, lets get the Type of component this serialized property is part of... var parentComponentType = property.serializedObject.targetObject.GetType(); // ... then, using reflection well get the raw field info of the property this // SerializedProperty represents... var fieldInfo = parentComponentType.GetField(property.propertyPath); // ... using that we can return the raw .net type! return fieldInfo.FieldType; } }