【Unity】关于属性重绘PropertyDrawer的一些吐槽(文明人不臭骂)[Unity版本:2018.3.7f1]

【未经本人同意不得私自转载!】
【文章发布于CSDN,原文链接:https://blog.csdn.net/weixin_44733774/article/details/124527137




1、若属性在List里头的话,PropertyDrawer类只会构造出一个对象

你可以对PropertyDrawer类设置构造函数,设置成员数据,这的确有用,表面看上去没问题,但一旦装进了List里头的话哪怕那列表里头有几十个元素,构造函数都只会调用一次,或者说PropertyDrawer对象就只生成了一个,这就造成了“明明单个试的时候还好好的为啥一装进容器里立马出错”的问题(惊不惊喜意不意外?),被坑害无数次的孩子在此发出幽怨的低吼声。

当时出问题时debug了几小时最后发现是这种莫名其妙的bug,我能怎么办?我也只能嘤嘤乱叫。神tm装进列表后PropertyDrawer对象只生成一个(而不是根据列表内的元素多少来生成多少个对象),它到底有啥顾忌。不知道新版unity有没有把这破事解决掉


【代码示例】

    随便定义了个可序列化类(也就是有[Serializable]修饰的类),并挂在Mono脚本上,
    然后在Inspector中能看得出来,数据显示得非常难看,所以才有必要写这个可序列化类的对应PropertyDrawer进行重绘


    对这个序列化类写了个绘制类(有[CustomPropertyDrawer(typeof(XXXXX))]修饰的类并且继承PropertyDrawer) 然后在OnGUI里头简单写写。
    能看到我代码里把数据直接存进对象里头了吧,当时觉得没问题才这么做,后来被Unity的神仙行为整个半死。
    看到那列表元素里的数据整齐得像军队一样吧,改一个,其他也跟着变。如果在这个类里头再定义个构造函数并Debug.Log一下的话就知道怎么回事了[笑]。


    说“直接用EditorGUI.PropertyField(position,property.FindPropertyRelative("XXX”))就好了啊为啥还存起来”,其实,嘛,非常有道理(我也不知道为啥脑短路非得就存起来,可能单纯是杠上了),只能说,这真skr…美丽的东西呢


    如果非得要往PropertyDrawer对象里存点东西方便自己使用的话怎么办?解决方法?有的,不正常而已。没办法毕竟这个PropertyDrawer都奇奇怪怪的,我感觉就是个半成品,不知道新版unity有没有完善。
    我的方法是存进字典里,以property.propertyPath为键,这样的话就能变相达到自己存取数据的目的。



    十分感慨能顶着这po玩意儿开发Inspector编辑器的巨佬(例如可序列化字典SerializableDictionary),太有英雄气概了,反正我当时debug出是这种病症时直接气疯然后爽玩一两天游戏。
    哦我还试过一次内存泄漏,在浏览器开新标签时直接提示崩溃,想着我平时也没干啥这几天也就一直弄Unity的Inspector的所以对浏览器的警告认为是误报就没有去理会并继续用浏览器结果屏幕黑了(等了几分钟没恢复只能重启)。可能是我哪些操作有问题吧造成了内存泄漏,只不过Unity居然没进行垃圾回收的确是有点不理解了(不知道触发机制,等再碰到这问题时再仔细研究)。
    还有就是我记得官方还是哪的好像说过:“别在Inspector中显示过于复杂的数据”,其中之一的原因是复杂数据的序列化代价太大,其二嘛,自己写写都懂的了,连“字典”、“列表”这东西都得自己去完成实现而不是unity默认实现,能感受到那开发压力有多大了吧。






2、折页标签EditorGUI.Foldout所需的折叠状态不知道往哪存

以我这金鱼脑的脑力我只会存进序列化类里头(也就是类里面得额外设置个bool来记录折叠状态),想不到像样的方法。(小声bb:本来耦合程度就高了居然还往里头添乱






3、被嵌套的话绘制结果会莫名其妙地变得难看

如果被嵌套的话,绘制时的Rect区域,左边界位置会被强制右移,但右边界位置不变。这个问题当时还以为是我调用方式有问题,后来不断debug不断尝试,几小时,嗯,试出来,就是“智能绘制”,ta很“善解人意”地帮你把所有属性的绘制区域的左边界全部调了调,我特么,真…真好样的!我倒想看看是哪个大触写的,这真的难以理解。
我为了修正这个偏移问题我用了不合理的方法(根据property.depth判断该属性是否被嵌套显示,然后又用了魔法数字),也就是我不能保证我这代码是健壮的,可能会在其他地方又出现绘制不理想的问题。没办法,我不懂它,我不懂PropertyDrawer,它是在是太高深了。


【代码示例】

    很标准的“最大值”、“最小值”、“当前值”。
    然后在被扔进列表里的时候,能看得出来,绘制结果莫名变得非常丑陋


    根据property.depth来判断是否被嵌套。
    如果被嵌套的话就得提前把矩形左值position.x进行修改,但矩形右值position.xMax得保持原样,可以说是相当魔幻了。
    可以看到被修正后显示的内容非常好看,不会像上面一样狰狞。






4、系统在调用OnGUI之前会先调用GetPropertyHeight获取绘制区域高度

我就很不理解,额,就,怎么说呢,额不知道怎么说,就,额,很无奈。
也就是我本身在OnGUI里头逐个数据绘制出来的时候,我的属性高度也就顺便确定好了,然后,嗯,我,我还得在这个GetPropertyHeight里头再顺着OnGUI的绘制逻辑把我所需的高度给获取一遍。我,额,额,算了(当你在绘制可变高度的属性时你就会发现这有多难以形容的莫名其妙)。

反正我嫌麻烦我直接在绘制类里头添加个数据成员float height=200,
在OnGUI里头对这个值进行修改,
在GetPropertyHeight里头则是直接返回height这个值。
这方法又不是不能用,管它呢。






摸了,一时还想不到还有啥吐槽的。
上面截图里的代码我传到gayhub里头(unity项目):https://github.com/Ls-Jan/Unity_Demo_PropertyDrawer
(我已经不想再碰这玩意儿了,很心累的

猜你喜欢

转载自blog.csdn.net/weixin_44733774/article/details/124527137