unity inspector 自动装载Commont和Prefab属性

在使用unity的过程中,经常遇到这样的问题:每次都需要手动为序列化属性。像这样:

试着找了找,真的找到了一份代码,但是缺少自动装载Prefab的功能。之后我花了点时间添加这个功能。

使用方法:

 1   [Autohook]
 2     public Button SendBtn;
 3     [Autohook]
 4     public Button StartBtn;
 5     [Autohook]
 6     public Button LeaveBtn;
 7     [Autohook]
 8     public Text RoomDateText;
 9     [Autohook]
10     public ScrollRect PlayerList;
11
12     [Autohook(AutohookAttribute.HookType.Prefab)]
13     public GameObject PlayerBarPrefab;
14     [Autohook(AutohookAttribute.HookType.Prefab)]
15     public GameObject RoomBarPrefab;

下面是源文件:

 1 // NOTE DONT put in an editor folder!
 2 using UnityEngine;
 3
 4 /// <summary>
 5 ///  use [Autohook] to modify Component
 6 ///  use [Autohook(AutohookAttribute.HookType.Prefab)] to modify Prefab
 7 /// </summary>
 8 public class AutohookAttribute : PropertyAttribute
 9 {
10     public readonly HookType hookType;
11     public readonly string prefabPath;
12
13     public enum HookType {
14         Component,
15         Prefab
16     }
17
18     public AutohookAttribute(HookType hookType = HookType.Component, string prefabPath = "Assets/Prefabs")
19     {
20         this.hookType = hookType;
21         this.prefabPath = prefabPath;
22     }
23 }

AutohookAttribute.cs

  1 // NOTE put in a Editor folder
  2 using UnityEditor;
  3 using UnityEngine;
  4 using UnityEngine.Assertions;
  5
  6 [CustomPropertyDrawer(typeof(AutohookAttribute))]
  7 public class AutohookPropertyDrawer : PropertyDrawer
  8 {
  9     public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
 10     {
 11         if (property.objectReferenceValue != null)
 12         {
 13             EditorGUI.PropertyField(position, property, label);
 14             return;
 15         }
 16         AutohookAttribute autohookAttribute = (AutohookAttribute)attribute;
 17         if (autohookAttribute.hookType == AutohookAttribute.HookType.Component)
 18         {
 19             //Assert.IsFalse(GetTypeFromProperty(property).Equals(typeof(GameObject)),
 20             //    "use [Autohook] to modify "+property.name);
 21             var component = FindAutohookTarget(property);
 22             if (component != null)
 23             {
 24                 //  if (property.objectReferenceValue == null)
 25                 property.objectReferenceValue = component;
 26             }
 27         } else if (autohookAttribute.hookType == AutohookAttribute.HookType.Prefab)
 28         {
 29             //Assert.IsTrue(GetTypeFromProperty(property).Equals(typeof(GameObject)),
 30             //    "use [Autohook(AutohookAttribute.HookType.Prefab)] to modify " + property.name);
 31             string name = property.name;
 32             if (name.EndsWith("Prefab"))
 33             {
 34                 name = name.Remove(name.Length - 6);
 35             }
 36             var prefab = FindPrefab(property, name, autohookAttribute.prefabPath);
 37             if (prefab != null)
 38             {
 39                 property.objectReferenceValue = prefab;
 40             }
 41         }
 42
 43
 44         EditorGUI.PropertyField(position, property, label);
 45     }
 46
 47     private GameObject FindPrefab(SerializedProperty property, string name, string assertPath)
 48     {
 49         string[] guids = AssetDatabase.FindAssets("t:Prefab", new string[] { assertPath });
 50         foreach (string guid in guids)
 51         {
 52             string path = AssetDatabase.GUIDToAssetPath(guid);
 53             string prefabName = System.IO.Path.GetFileNameWithoutExtension(path);
 54             if (name == prefabName)
 55             {
 56                 return AssetDatabase.LoadAssetAtPath<GameObject>(path);
 57             }
 58         }
 59         return null;
 60     }
 61
 62     /// <summary>
 63     /// Takes a SerializedProperty and finds a local component that can be slotted into it.
 64     /// Local in this context means its a component attached to the same GameObject.
 65     /// This could easily be changed to use GetComponentInParent/GetComponentInChildren
 66     /// </summary>
 67     /// <param name="property"></param>
 68     /// <returns></returns>
 69     private Component FindAutohookTarget(SerializedProperty property)
 70     {
 71
 72         var root = property.serializedObject;
 73
 74         if (root.targetObject is Component)
 75         {
 76             // first, lets find the type of component were trying to autohook...
 77             var type = GetTypeFromProperty(property);
 78
 79             // ...then use GetComponent(type) to see if there is one on our object.
 80             var component = (Component)root.targetObject;
 81             //  var gb = (GameObject) root.targetObject;
 82             //  Debug.LogError(component.transform(type));
 83             var components = component.GetComponentsInChildren(type);
 84             foreach (var item in components)
 85             {
 86                 //确保GameObject不要有重名的
 87                 if (item.gameObject.name == property.name)
 88                 {
 89                     return item.gameObject.GetComponent(type);
 90                 }
 91             }
 92         }
 93         else
 94         {
 95             Debug.Log("OH NO handle fails here better pls");
 96         }
 97
 98         return null;
 99     }
100
101     /// <summary>
102     /// Uses reflection to get the type from a serialized property
103     /// </summary>
104     /// <param name="property"></param>
105     /// <returns></returns>
106     private static System.Type GetTypeFromProperty(SerializedProperty property)
107     {
108         // first, lets get the Type of component this serialized property is part of...
109         var parentComponentType = property.serializedObject.targetObject.GetType();
110         // ... then, using reflection well get the raw field info of the property this
111         // SerializedProperty represents...
112         var fieldInfo = parentComponentType.GetField(property.propertyPath);
113         // ... using that we can return the raw .net type!
114         return fieldInfo.FieldType;
115     }
116 }

AutohookPropertyDrawer.cs

原文地址:https://www.cnblogs.com/backinfile/p/12359861.html

时间: 2024-10-13 17:37:22

unity inspector 自动装载Commont和Prefab属性的相关文章

C#开发Unity游戏教程之游戏对象的属性变量

C#开发Unity游戏教程之游戏对象的属性变量 Unity游戏对象的属性--变量 通过对上一章的学习,读者应该了解到了,游戏对象上的属性与脚本中的变量,建立联系的方式就是将脚本赋予游戏对象.上一章仅仅是简单的介绍了脚本中的变量,读者一定只是瘾,如今好了.作者将使用一整章的篇幅介绍变量与属性. Unity游戏对象的属性 在Unity中.游戏场景中游戏对象的属性,能够在Inspector视图里查看,想看哪个游戏对象的属性.就使用鼠标选中哪个游戏对象就可以. 比如,要查看游戏场景中Main Camer

Extjs的form表单自动装载数据(通过Ext.data.Model的代理加载数据)

在做项目的时候遇到一个问题,以前双击grid页面一行数据的时候,会吧双击这一行的数据自动加载到双击的页面(Ext的弹出框),可以通过this.down(''form).getForm().loadRecord(record)来自动加载,可是现在有一个需求就是双击grid一行弹出一个新的浏览器页面(不是ext的弹出框,通过window.open()实现),只能把双击的id传到页面,再重新查数据手动赋值,如果一个页面字段很多,一个一个赋值是很辛苦的,所以就想能不能自动装载数据 通过长时间研究发现,t

springboot(二)配置SpringBoot支持自动装载Servlet

Servlet详解:https://blog.csdn.net/yanmiao0715/article/details/79949911 Web 技术成为当今主流的互联网 Web 应用技术之一,而 Servlet 是 Java Web 技术的核心基础之一. Servlet是Java编写服务器端的程序组件,主要功能在于交互式数据操作,动态生成WEB内容等.传统的Spring项目,配置Servlet比较繁琐,需要在web.xml内添加对应的标签以及映射路径规则.本章主要讲解在SpringBoot项目

Unity Inspector 给组件自动关联引用(二)

通过声明的变量名称,主动关联引用. 使用这个关联引用两种方式1.  给你组件继承  MonoAutoQuote 点击组件inspector 按钮执行2.  给你组件类添加[AAutoQuote] 特性  通过Plateface/SetSelectGameRef 执行 [AAutoQuote] public class MonoAutoQuote : MonoBehaviour ,IAutoQuote{} public interface IAutoQuote { } public class A

Unity 摄像机Clear Flags和Culling Mask属性用途详解

原文地址:http://blog.csdn.net/tanmengwen/article/details/8798231 1.简述两个属性 1.1 Clear Flags 清除标记 每个相机在渲染时会存储颜色和深度信息.屏幕的未绘制部分是空的,默认情况下会显示天空盒.当你使用多个相机时,每一个都将自己的颜色和深度信息存储在缓冲区中,还将积累大量的每个相机的渲染数据.当场景中的任何特定相机进行渲染时,你可以设定清除标记以清除缓冲区信息的不同集合.可以通过下面四个选项之一来完成: 1.Skybox

类的自动加载、类属性类方法的调用

类的自动加载: 方法一:spl_autoload_register(function($className){ require $className.".php"; }); $imooc = new Imooc(); 方法二: 类方法和类属性的调用: 原文地址:https://www.cnblogs.com/weixiaofantasy/p/9830227.html

扩展Unity Inspector

Unity Editor下,可以在不改变原有布局的情况下扩展Inspect的界面. 在继承了Editor的类中,有两种实现方式: using UnityEditor; [CustomEditor(typeof(CustomClass))] public class CustomClassEditor : Editor { public override void OnInspectorGUI() { // 自定义代码 base.OnInspectorGUI(); // 自定义代码 } } 和 u

unity, inspector debug

以前经常因为脚本中private变量不在inspector界面中显示,不方便观察其值的变化,所以本该用private的用了public. 今天发现,原来inspector有个选项,如图,平常勾选的是Normal,则inspector界面只显示public变量,如果改为勾选Debug,则private变量也会以灰字显示出来.

unity工程自动保存的脚本

using UnityEngine; using UnityEditor; using System; public class AutoSave : EditorWindow { private bool autoSaveScene = true; private bool showMessage = true; private bool isStarted = false; private int intervalScene; private DateTime lastSaveTimeSce