unity编辑器扩展高级用法

在PropertyDrawer中,您不能使用来自GUILayoutEditorGUILayout的自动布局API,而只能使用来自GUIEditorGUI的绝对Rect API始终传递相应的起始位置和维度。

你需要

  • 计算显示嵌套内容所需的总高度
  • 将此高度添加到public override float GetPropertyHeight,这将告诉检查员根据Rect保留以绘制您的财产
  • 将为sub-editor保留的相应Rect传递到editor中,并在给定位置和尺寸处绘制

=>您不能简单地使用默认编辑器来实现这一点,因为它在PropertyDrawers无法使用的auto-layout系统中运行。

cs 复制代码
#region UNITY_EDITOR
using System.Collections.Generic;
using System;
using UnityEditor;
using static UnityEditor.Progress;
using UnityEngine;
using Unity.VisualScripting;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Xml.Linq;
using System.IO;

public class UICollector : MonoBehaviour
{


    public string GenerateClassName;
    public OperateSetting OperateSetting;
    public List<ComponentInfo> components = new List<ComponentInfo>();
   
    public void GenerateMainClass()
    {
  //  F:\AAAAAAAAAAAG4\UnityProject\MyDoor\trunk\client_root\Assets\Scripts\Game\Runtime\Logic\Dialog\_AirShipBodayTab.cs
        string mainPath = $"{Application.dataPath}/Scripts/Game/Runtime/Logic/Dialog/{GenerateClassName}.cs";
        if (!File.Exists(mainPath))
        {
            File.Create(mainPath).Close();         
        }

        UnityEditor.AssetDatabase.Refresh();
        File.WriteAllText(mainPath,
            @"using UnityEngine;
using System;
using UnityEngine.UI;
public partial class _D_CLASSNAME : Dialog
{
    public override bool IsFullScreen() { return true;}
    public override bool NeedShowCoins(){   return false; }
    protected override void OnCreate()
    {
                       
    }
}
".Replace("_D_CLASSNAME", GenerateClassName)
        );
        UnityEditor.AssetDatabase.Refresh();
        GeneratePartClass();

    }


    private void GeneratePartClass()
    {

        string fielddata = "";
        string referdata = "";
        foreach (var item in components)
        {
            if (!string.IsNullOrEmpty(item.name)&& item.component!=null)
            {
                fielddata += $"private {item.component.GetType().Name} {item.name};\n";
                referdata += $"{item.name} = transform.Find(\"{ item.path }\").GetComponent<{item.component.GetType().Name}>();\n";
            }
        }

        

        string baseTemp = @"using System;
using UnityEngine;
using UnityEngine.UI;

public partial class _D_CLASSNAME : Dialog
{
    FILEDLIST
    protected override void InitRef()
    {
      REFERENCE
    }
}
";
        string info = "";
        info = baseTemp.Replace("FILEDLIST", fielddata);
        info = info.Replace("_D_CLASSNAME", GenerateClassName);
        info = info.Replace("REFERENCE", referdata);
        string aprtPath = $"{Application.dataPath}/Scripts/Game/Runtime/Logic/Dialog/Partial/{GenerateClassName}.cs";
        if (!File.Exists(aprtPath))
        {
            File.CreateText(aprtPath).Close();
            UnityEditor.AssetDatabase.Refresh();         
        }

        File.WriteAllText(aprtPath, info);
        UnityEditor.AssetDatabase.Refresh();
    }



}



[Serializable]
public class ComponentInfo
{
    public string name;
    public string path;
    public int index;
    public UnityEngine.Component component;
    public GameObject go;
    public GameObject lastObject;
}
[CustomPropertyDrawer(typeof(ComponentInfo))]
public class ComponentInfoEditor : PropertyDrawer
{

    private UnityEngine.Object lastObject;
    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        return base.GetPropertyHeight(property, label) + 40;//这个总区域的高度
    }
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        GUI.color = Color.white;
        float span = 220;
        float width = 180;
        var f1Rect = new Rect(position.x + span * 1, position.y, width, 20);
        var f2Rect = new Rect(position.x + span * 0, position.y, width, 20);
        var f3Rect = new Rect(position.x, position.y + 20, width, 20);
        var f4Rect = new Rect(position.x + span * 1, position.y + 20, width, 20);
        var f5Rect = new Rect(position.x + span * 2, position.y + 20, width, 20);

        EditorGUIUtility.labelWidth = 70;

        var go = property.FindPropertyRelative("go").objectReferenceValue;
        if (go != null)
        {
            EditorGUI.PropertyField(f2Rect, property.FindPropertyRelative("go"));
            bool isChange = false;
           var lastObject = property.FindPropertyRelative("lastObject").objectReferenceValue;
            if (isChange == false) isChange = lastObject != go;
            property.FindPropertyRelative("lastObject").objectReferenceValue = go;
            UnityEngine.Component[] components = go.GetComponents<UnityEngine.Component>();
            List<string> types = new List<string>();
            foreach (UnityEngine.Component comp in components)
            {
                types.Add(comp.GetType().Name);
            }
            int nowindex = EditorGUI.Popup(f1Rect, property.FindPropertyRelative("index").intValue, types.ToArray());
            if (isChange == false) isChange = property.FindPropertyRelative("index").intValue != nowindex;
            property.FindPropertyRelative("index").intValue = nowindex;
            int index = property.FindPropertyRelative("index").intValue;
            property.FindPropertyRelative("component").objectReferenceValue = components[index];
            if (isChange || string.IsNullOrEmpty(property.FindPropertyRelative("name").stringValue))
            {
                string name = "m_" + components[index].GetType().Name.Substring(0, 4) + "_" + components[index].name;
                property.FindPropertyRelative("name").stringValue = name;
            }

            EditorGUI.PropertyField(f3Rect, property.FindPropertyRelative("name"));
            EditorGUI.PropertyField(f4Rect, property.FindPropertyRelative("component"));


            //当前挂载位置
            var parent = property.serializedObject.targetObject.GetComponent<Transform>();
            var curgo = go.GetComponent<Transform>();
            types.Clear();
            while (curgo != parent && curgo != null)
            {
                types.Add(curgo.name);
                curgo = curgo.parent;
            }
            string path = "";
            for (int i = types.Count - 1; i >= 0; i--)
            {
                path += (types[i] + (i != 0 ? "/" : ""));
            }
            property.FindPropertyRelative("path").stringValue = path;
            EditorGUI.PropertyField(f5Rect, property.FindPropertyRelative("path"));
 
        }
        else
        {
            EditorGUI.PropertyField(f2Rect, property.FindPropertyRelative("go"));
        }
    }
}


[Serializable]
public class OperateSetting
{
}

[CustomPropertyDrawer(typeof(OperateSetting))]
public class OperateSettingAEditor : PropertyDrawer
{
    private Dictionary<string, ComponentInfo> keyValuePairs = new Dictionary<string, ComponentInfo>();
    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        return base.GetPropertyHeight(property, label) + addHeight;
    }
    private float addHeight;
    private string repeatname;
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        //UnityEditor.EditorGUILayout.Space(60);
        var uiCollector = property.serializedObject.targetObject.GetComponent<UICollector>();
        if (string.IsNullOrEmpty(uiCollector.GenerateClassName))
        {
            uiCollector.GenerateClassName = $"_D_{uiCollector.transform.name.Replace("_d_", "")}";
        }

        if (GUI.Button(new Rect(position.x, position.y, position.width, 30), "生成CSharp"))
        {
            uiCollector.GenerateMainClass();
        }

        if (uiCollector.components.Count > 0)
        {
            keyValuePairs.Clear();
            bool isRepeat = false;
            foreach (var item in uiCollector.components)
            {
                if (!keyValuePairs.ContainsKey(item.name))
                {
                    keyValuePairs.Add(item.name,item);
                }
                else
                {
                    //GUI.color = Color.red; // 设置错误文本颜色为红色
                    repeatname = item.name;
                    isRepeat = true;
                    break;
                }
            }
            if (isRepeat)
            {
                GUI.Label(new Rect(position.x, position.y + 30, position.width, 40), "重复提示:" + repeatname + "字段重复", new GUIStyle());
                addHeight = 40;
            }
            else
            {
                addHeight = 30;
            }
        }
    }
}



#endregion
相关推荐
变身缎带1 小时前
Unity中的NetworkManager基于protobuf, Socket-TCP
tcp/ip·unity·游戏引擎
AllBlue9 小时前
unity调用安卓方法
android·unity·游戏引擎
金融小师妹10 小时前
基于LSTM趋势预测的白银价格突破58美元阈值,年度累计涨幅超100%的强化学习驱动分析
大数据·人工智能·编辑器·1024程序员节
郝学胜-神的一滴10 小时前
Horse3D游戏引擎研发笔记(十):在QtOpenGL环境下,视图矩阵与投影矩阵(摄像机)带你正式进入三维世界
c++·3d·unity·游戏引擎·godot·图形渲染·unreal engine
AllBlue12 小时前
unity导出成安卓工程,集成到安卓显示
android·unity·游戏引擎
Sator115 小时前
Unity的FishNet相关知识
网络·unity·游戏引擎
AllBlue15 小时前
安卓调用unity中的方法
android·unity·游戏引擎
Xiaok101816 小时前
VSCode 报错 “No module named ‘torch‘“
ide·vscode·编辑器
大江东去浪淘尽千古风流人物16 小时前
【MSCKF】StateHelper 学习备注
vscode·学习·性能优化·编辑器·dsp开发
李岱诚16 小时前
epic商城下载,ue4报错处理
游戏引擎·ue4