unity编辑器扩展高级用法

news2024/11/18 12:27:46

在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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

P6维护:P6 数据库迁移Step by Step

前言 根据大家的近期给的提议&#xff0c;这里简单介绍如何迁移P6数据库&#xff0c;场景选取为从将P6从ORACLE迁移到SQLServer。 Oracle Primavera P6 PPM 以及 EPPM 均有其自带的migrate工具完成数据库迁移&#xff0c;整个操作也较为傻瓜式&#xff0c;只要有基本的数据库…

[MAUI]集成高德地图组件至.NET MAUI Blazor项目

文章目录 前期准备&#xff1a;注册高德开发者并创建 key登录控制台创建 key获取 key 和密钥 创建项目创建JS API Loader配置权限创建定义创建模型创建地图组件创建交互逻辑 项目地址 地图组件在手机App中常用地理相关业务&#xff0c;如查看线下门店&#xff0c;设置导航&…

【MySQL】深入解析事务与MVCC

文章目录 1、事务四大特性1.1、原子性1.2、一致性1.3、隔离性1.4、持久性 2、并发事务带来问题2.1、脏读2.2、不可重复读2.3、幻读 3、事务隔离级别3.1、读未提交3.2、读已提交3.3、可重复读3.4、串行化 4、MVCC4.1、InnoDB隐藏字段4.2、undo log版本链4.3、ReadView4.4、MVCC工…

『K8S 入门』三:资源调度

『K8S 入门』三&#xff1a;资源调度 一、Label 和 Selector 可以通过 Selector 基于 Label 匹配需要的资源 Label 标签 配置文件中&#xff08;metadata.labels&#xff09;配置 metadata: # Pod相关的元数据&#xff0c;用于描述Pod的数据name: nginx-demo #Pod的名称lab…

阅读笔记(ICIP2023)Rectangular-Output Image Stitching

“矩形输出”图像拼接 Zhou, H., Zhu, Y., Lv, X., Liu, Q., & Zhang, S. (2023, October). Rectangular-Output Image Stitching. In 2023 IEEE International Conference on Image Processing (ICIP) (pp. 2800-2804). IEEE. 0. 摘要 图像拼接的目的是将两幅视场重叠的…

GDC期间LayaAir启动全球化战略

3 月 18 日至 3 月 22 日&#xff0c;一年一度的游戏开发者大会&#xff08;GDC&#xff09;在美国旧金山举行。在此期间&#xff0c;Layabox宣布LayaAir引擎启动全球扩张战略&#xff0c;这标志着引擎将步入快速发展的新阶段。此举旨在利用公司先进的3D引擎技术&#xff0c;将…

力扣每日一题 2024/3/23 统计桌面上的不同数字

题目描述 用例说明 思路讲解 给定整数n&#xff0c;找出循环十亿天后桌上的数字。可以先通过一天来找找规律。 第一天 n%i1 &#xff08;1<i<n&#xff09;只有n-1符合.加入桌面 第二天(n-1)%i1 &#xff08;1<i<n-1&#xff09;只有n-2符合 加入桌面 依次类推…

RHEL9部署Docker环境

华子目录 Docker引擎架构docker引擎架构示意图执行过程示例 RHEL9上安装Docker1.系统要求2.安装yum-utils工具包3.yum安装docker-ce4.配置docker镜像加速docker拉取镜像的过程配置阿里云镜像仓库重新加载守护进程重启Docker服务 5.拉取并运行hello-world镜像6.测试是否安装成功…

【LabVIEW FPGA入门】FPGA 存储器(Memory)

可以使用内存项将数据存储在FPGA块内存中。内存项以2kb为倍数引用FPGA目标上的块内存。每个内存项引用一个单独的地址或地址块&#xff0c;您可以使用内存项访问FPGA上的所有可用内存。如果需要随机访问存储的数据&#xff0c;请使用内存项。 内存项不消耗FPGA上的逻辑资源&…

stm32平衡车

目录 一.所需材料 二.PID算法&#xff08;简单说明&#xff09; 直立环 速度环 串级PID 三.使用到的外设 1.定时器输出比较-PWM 2.定时器编码器模式 3.编码器读取速度 4.电机驱动函数 5.外部中断 四、小车 调试 一.所需材料 1.陀螺仪MPU6050--读取三轴的加速度…

C++类和对象进阶

CSDN成就一亿技术人 C类的6个默认成员函数(构造)-CSDN博客https://blog.csdn.net/lh11223326/article/details/136917667?spm1001.2014.3001.5502 目录 一.再谈构造函数 1.构造函数体赋值&#xff1a; 在创建对象时&am…

# Maven Bom 的使用

Maven Bom 的使用 文章目录 Maven Bom 的使用概述BOM特点优点缺点 MavenMaven 安装安装步骤settingx.ml常用仓库地址Idea 使用maven常见坑 SpringBoot 项目Bom使用案例项目结构主项目 zerocode-back-servezc-dependency&#xff08;第三方jar管理&#xff09;子模块zc-serve子模…

Qt creator构建DLL库

文章目录 一、构建DLL库二、隐式调用DLL库 一、构建DLL库 Qt creator创建DLL项目。 实现功能函数。 运行代码&#xff0c;debug目录下会有.dll和.lib文件。 二、隐式调用DLL库 QT新建控制台项目。将.lib文件和与之关联的头文件赋值到项目文件夹。 3. 添加头文件和外部依赖库…

目标检测——YOLOR算法解读

论文&#xff1a;YOLOR-You Only Learn One Representation: Unifified Network for Multiple Tasks 作者&#xff1a;Chien-Yao Wang, I-Hau Yeh, Hong-Yuan Mark Liao 链接&#xff1a;https://arxiv.org/abs/2105.04206 代码&#xff1a;https://github.com/WongKinYiu/yolo…

Python界面库Flet(1)介绍和快速使用

Python界面库Flet(1)快速上手使用 Author&#xff1a;Once Day Date&#xff1a;2024年3月19日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文章可参考专栏: Pyt…

利用sealos安装k8s集群

1. 环境准备 准备三台干净&#xff08;未安装过k8s环境&#xff09;的虚拟机 # 所有的主机都要配置主机名和域名映射 # 设置主机名 hostnamectl set-hostname k8s-master01 # vim /etc/hosts 192.168.59.201 k8s-master01 192.168.59.202 k8s-worker01 192.168.59.203 k8…

飞鸟写作能用吗 #笔记#笔记

飞鸟写作是一个强大的论文写作工具&#xff0c;不仅可以帮助用户高效、准确地完成论文写作&#xff0c;还能帮助用户对论文进行查重和降重。那么&#xff0c;飞鸟写作能用吗&#xff1f;答案是肯定的&#xff0c;飞鸟写作非常好用&#xff01; 首先&#xff0c;飞鸟写作拥有强大…

视频记录历史播放位置效果

简介 每次打开页面视频从上一次的播放位置开始播放 利用lodash库做节流 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-sca…

MySQL | 视图

视图是一个虚拟表&#xff0c;其内容由查询定义。同真实的表一样&#xff0c;视图包含一系列带有名称的列和行数据。视图的数据变化会影响到基表&#xff0c;基表的数据变化也会影响到视图。 1. 基本使用 1.1. 创建视图 create view 视图名 as select语句&#xff1b; 创建测…

自动驾驶轨迹规划之时空语义走廊(一)

欢迎大家关注我的B站&#xff1a; 偷吃薯片的Zheng同学的个人空间-偷吃薯片的Zheng同学个人主页-哔哩哔哩视频 (bilibili.com) 目录 1.摘要 2.系统架构 3.MPDM 4.时空语义走廊 ​4.1 种子生成 4.2 具有语义边界的cube inflation ​4.3 立方体松弛 本文解析了丁文超老师…