unity编辑器扩展高级用法

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

你需要

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

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


#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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/483492.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深入解析实时数仓Doris:介绍、架构剖析、应用场景与数据划分细节

码到三十五 &#xff1a; 个人主页 心中有诗画&#xff0c;指尖舞代码&#xff0c;目光览世界&#xff0c;步履越千山&#xff0c;人间尽值得 ! Doris是一款高性能、开源的实时分析数据仓库&#xff0c;旨在为用户提供毫秒级查询响应、高并发、高可用以及易于扩展的OLAP解决方…

P1563 [NOIP2016 提高组] 玩具谜题

题目传送门 这道题实在是一道水题 话不多说&#xff0c;上代码 #include<iostream> #include<cstring> using namespace std; struct a{int io;//in朝里 out朝外 小人的朝向 string name;//小人的名字 int number;//角色编号 }a[100000]; int main(){int n, m…

连续子数组的最大和

问题描述&#xff1a; 输入一个整型数组&#xff0c;数组里有正数也有负数。求连续子数组中的最大和为多少。 举例&#xff1a; 数组&#xff1a;arry{1 , 2 &#xff0c;-5 , 4 , 1 &#xff0c;-2} 输出&#xff1a;5&#xff0c;数组中连续的位置相加最大值为5, 41 方法…

yolov8目标检测数据集制作——make sense

背景 在前几天我进行了录制视频以准备足够多的数据集&#xff0c;同时使用利用python自定义间隔帧数获取视频转存为图片&#xff0c;所以今天我准备对我要训练的数据集进行标注。我要做的是一个基于yolo的检测项目&#xff0c;在搜索资料后得知大家多是用labelme或者make sens…

文心一言 VS 讯飞星火 VS chatgpt (221)-- 算法导论16.3 3题

三、如下所示&#xff0c;8个字符对应的出现频率是斐波那契数列的前8个数&#xff0c;此频率集合的赫夫曼编码是怎样的? a:1 b:1 c:2 d:3 e:5 f:8 g:13 h:21 你能否推广你的结论&#xff0c;求频率集为前 n 个斐波那契数的最优前缀码? 文心一言&#xff1a; 首先&#xff0…

pytorch中tensor类型转换的几个函数

目录 IntTensor转FloatTensor FloatTensor转IntTensor Tensor类型变为python的常规类型 IntTensor转FloatTensor .float函数&#xff1a; FloatTensor转IntTensor .int函数 Tensor类型变为python的常规类型 item函数

Matlab 2024a版本在Linux系统上的安装配置

目录 前言一、​Matlab 2024a安装总结 前言 Matlab是一种高级技术计算和编程环境&#xff0c;广泛应用于科学、工程和金融等领域。它提供了丰富的工具和函数库&#xff0c;用于数据分析、可视化、模型建立、算法开发和应用部署等任务。注&#xff1a;文末附有下载链接&#xf…

一文告诉你如何用 Python 操作 ChatGPT

ChatGPT 相信大家都用过&#xff0c;你觉得它给你的工作带来了多少帮助呢&#xff1f; 对这块感兴趣的&#xff0c;可以群里聊聊 目前我们使用 ChatGPT 的方式是通过浏览器访问 chat.openai.com&#xff0c;然后输入问题&#xff0c;就像下面这样。 除了网页之外&#xff0…

Qt打开已有工程方法

在Qt中&#xff0c;对于一个已有工程如何进行打开&#xff1f; 1、首先打开Qt Creator 2、点击文件->打开文件或项目&#xff0c;找到对应文件夹下的.pro文件并打开 3、点击配置工程 这样就打开对应的Qt项目了&#xff0c;点击运行即可看到对应的效果 Qt开发涉及界面修饰…

2024-03-22 问AI: 介绍一下深度学习中的 sigmoid函数

文心一言 Sigmoid函数是深度学习中常用的一种激活函数&#xff0c;主要用于将神经元的输出值压缩到0和1之间。这种特性使得sigmoid函数在二分类问题中特别有用&#xff0c;因为输出值可以被解释为属于某个类别的概率。 sigmoid函数的数学表达式为&#xff1a; σ(x) 1 / (1…

CMake笔记之将任意官方库作为third_party完整地包含在工程项目中使用的通用模板

CMake笔记之将任意官方库作为third_party完整地包含在工程项目中使用的通用模板 —— 杭州 2024-03-20 凌晨1:06 code review! 文章目录 CMake笔记之将任意官方库作为third_party完整地包含在工程项目中使用的通用模板1.通用CMakeLists.txt模板2.GPT4给出的改进建议3.git clon…

kubernetes负载均衡-service

一、service的概念 1、什么是service 在Kubernetes中&#xff0c;pod是应用程序的载体&#xff0c;当我们需要访问这个应用时&#xff0c;可以通过Pod的IP进行访问&#xff0c;但是这里有两个问题:1、Pod的IP地址不固定&#xff0c;一旦Pod异常退出、节点故障&#xff0c;则会…

Windows11 安装confluence 7.4.0

Windows11安装confluence:7.4.0 1.打开终端管理员(管理员权限的PowerShell)2.按顺序执行以下命令,安装confluence服务3.浏览器(如Microsoft Edge) 打开 http://127.0.0.1:8100/ 配置confluence4.图示 本文是Windows11 安装confluence 7.4.0的步骤 本文参考 1.打开终端管理员(管…

使用React搭建single-spa

自己搭建的Demo GitHub - ftao123/single-spa-react-demo: single-spa-react-demo 修改子应用的webpack配置 library: "app2"和libraryTarget: "umd"配置必须添加。 可以看到filename在开发环境下的地址是static/js/bundle.js&#xff0c;所以我们主应用…

PySide6-YOLO8目标检测、追踪可视化界面

目录 项目地址实现效果DetectTrack 项目地址 https://github.com/zhengjie9510/pyside-yolo 实现效果 Detect Track

MySQL 查询性能优化

优质博文&#xff1a;IT-BLOG-CN​ 如果把查询看作是一个任务&#xff0c;那么它由一些列子任务组成&#xff0c;每个子任务都会消耗一定的时间。如果要优化查询&#xff0c;实际上要优化其子任务&#xff0c;要么消除其中一些子任务&#xff0c;要么减少子任务的执行次数。通常…

matlab批量读取目录下的文件的方法

批量处理可以提高效率&#xff0c;这里提供一个可以批量读取nc文件的代码&#xff1a; address C:\Users\Hello World!!\DESKTOP\TerraClimate_ppt\; % Get the list of files udir address; form *.nc; % Get the list of station names files GetFiles(udir,form); [n,p…

Linux 进程通信:命名管道、共享内存

目录 一、命名管道 1、概念 2、特点 3、原理 4、创建 5、匿名管道与命名管道的区别 6、命名管道的打开规则 二、命名管道—实现客户端和服务器之间的通信 1、Makefile 2、comm.hpp 3、Log.hpp 4、server.cxx 5、client.cxx 运行测试&#xff1a; 三、system V…

模拟实现 atoi 函数

一、函数介绍 原型 int atoi(const char *nptr); 二、使用atoi 三、使用发现 可以发现&#xff1a;会先过滤掉空格&#xff0c;还能识别正负号&#xff0c;当第一次遇到正负号了&#xff0c;后面没接着是数字就返回0&#xff0c; 如果45 5aa 结果是45&#xff0c;说明前面识…

JavaScript代码执行原理

JavaScript代码是如何被机器理解并执行的呢&#xff1f; 作为 JavaScript 开发者&#xff0c;通常我们不需要关心JavaScript引擎是如何执行代码的。但是&#xff0c;了解 JavaScript 引擎的工作原理&#xff0c;知晓它如何处理我们编写的 JS 代码、肯定是有益的。 注意&#…