一个美术需求引发的Custom Inspector
需求
- Editor模式下,在运行或者非运行状态下,能够按照指定的变化率来自动改变material中属性数值。
需求分析
如何在Editor模式下获得一个游戏对象及其组件,尤其是在非运行状态下?我们知道在Unity IDE运行起来后是很容易获得一个对象和组件的,在GameObject上挂一个脚本即可。但是在非运行状态下呢,
transform.GetComponent这样的方法怎么执行?好在unity已经为我们考虑到了这个问题,提供了[ExecuteInEditMode]Attribute,通过指定这个attribute使得组件类中的方法可以在edit模式下执行,并且是在非运行状态下的。如何在非运行状态下匀速改变数值呢?update方法中配合
Time.deltaTime是一个完美的方案,但是即使设置了[ExecuteInEditMode],update的表现在非运行和运行时也是完全不同的,查资料看到is only called when something in the scene changed.这句话时也有种吐槽的冲动。好在unity又为大家考虑到了这个问题(话说unity editor确实功能强大,AssetAtore里面那些插件真是厉害),Edit模式下提供了EditorApplication.update,这是一个事件,我们注册一个自己的方法就可以在非运行状态下实现update的功能。我个人比较推荐使用EditorCoroutine,一个基于EditorApplication.update的协程实现。
功能实现
- 使用一个自定义组件来实现material中数值的修改,这个类在UI上要体现出能够设置变化速率和初始值。并且在UI上通过点击按钮的形式来触发改变。
- 使用Custom Inspector来实现组件UI的自定义。
- 在运行状态下通过使用默认的update来实现匀速变化,在非运行状态下通过使用EditorCoroutine来实现。
代码实现
using UnityEngine;
using System.Collections;
using UnityEditor;
public class UVAnimation : MonoBehaviour
{
public Vector2 TilingSpeed = new Vector2(1, 1);
public Vector2 OffsetSpeed = new Vector2(0.1f, 0.1f);
public Vector2 Tiling = new Vector2(1, 1);
public Vector2 Offset = new Vector2(0, 0);
float rate = 0.02f;
EditorCoroutine coroutineOffset;
EditorCoroutine coroutineTiling;
bool isOffset = false;
bool isTiling = false;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
}
void FixedUpdate()
{
if (isOffset)
{
transform.GetComponent<Renderer>().sharedMaterials[0].mainTextureOffset += OffsetSpeed * Time.deltaTime;
}
if (isTiling)
{
transform.GetComponent<Renderer>().sharedMaterials[0].mainTextureScale += TilingSpeed * Time.deltaTime;
}
}
public void ChangeOffset()
{
if (EditorApplication.isPlaying)
{
isOffset = true;
}
else
{
if (coroutineOffset != null)
{
coroutineOffset.stop();
}
coroutineOffset = EditorCoroutine.start(ChangeOffsetCoroutine());
}
}
IEnumerator ChangeOffsetCoroutine()
{
while (true)
{
yield return new WaitForSeconds(rate);
transform.GetComponent<Renderer>().sharedMaterials[0].mainTextureOffset += OffsetSpeed * rate;
}
}
public void ChangeTiling()
{
if (EditorApplication.isPlaying)
{
isTiling = true;
}
else
{
if (coroutineTiling != null)
{
coroutineTiling.stop();
}
coroutineTiling = EditorCoroutine.start(ChangeTilingCoroutine());
}
}
IEnumerator ChangeTilingCoroutine()
{
while (true)
{
yield return new WaitForSeconds(rate);
transform.GetComponent<Renderer>().sharedMaterials[0].mainTextureScale += TilingSpeed * rate;
}
}
public void SetOffset()
{
transform.GetComponent<Renderer>().sharedMaterials[0].mainTextureOffset = Offset;
}
public void SetTiling()
{
transform.GetComponent<Renderer>().sharedMaterials[0].mainTextureScale = Tiling;
}
public void Reset()
{
isOffset = false;
isTiling = false;
transform.GetComponent<Renderer>().sharedMaterials[0].mainTextureScale = new Vector2(1, 1);
transform.GetComponent<Renderer>().sharedMaterials[0].mainTextureOffset = new Vector2(0, 0);
if (coroutineOffset != null)
{
coroutineOffset.stop();
}
if (coroutineTiling != null)
{
coroutineTiling.stop();
}
}
}
using UnityEngine;
using System.Collections;
using UnityEditor;
[CustomEditor(typeof(UVAnimation))]
public class UVAnimationBuilderEditor : Editor {
public override void OnInspectorGUI ()
{
base.OnInspectorGUI ();
//DrawDefaultInspector ();
UVAnimation uva = (UVAnimation)target;
if (GUI.changed) {
uva.SetTiling ();
uva.SetOffset ();
}
if (GUILayout.Button("Change Tiling")) {
uva.ChangeTiling ();
EditorUtility.SetDirty (target);
}
if (GUILayout.Button("Change Offset")) {
uva.ChangeOffset ();
}
if (GUILayout.Button("Reset")) {
uva.Reset ();
}
}
}
代码解析
[CustomEditor(typeof(UVAnimation))]为UVAnimation创建的Editor类,在这个类里面可以修改UVAnimation类的UI,可以调用UVAnimation类中的方法。OnInspectorGUI方法,顾名思义在里面可以对UI进行编程,注意一下这个方法会自己生产一句代码base.OnInspectorGUI ();,我所注释掉的DrawDefaultInspector ();这句代码都是用来绘制默认UI的,二者只可留其一。transform.GetComponent<Renderer>().sharedMaterials在edit模式下获取材质球的对象需要用sharedMaterials。mainTextureScale对应的就是UI上的Tiling。命名这让人吐槽。
一个美术需求引发的Custom Inspector的更多相关文章
- 由一个项目需求引发的 - textarea中的换行和空格
当我们使用 textarea 在前台编辑文字,并用 js 提交到后台的时候,空格和换行是我们最需要考虑的问题.在textarea 里面,空格和换行会被保存为/s和/n,如果我们前台输入和前台显示的文字 ...
- Spring之LoadTimeWeaver——一个需求引发的思考---转
原文地址:http://www.myexception.cn/software-architecture-design/602651.html Spring之LoadTimeWeaver——一个需求引 ...
- Unity编辑器扩展 Chapter3--Create Custom Inspector
一.Create Custom Inspector 重绘inspector面板一方面是我们的挂在脚本的窗口变得友好,另一方面可以让其变得更强大,比如添加一些有效性验证. 二.重要说明 1.Editor ...
- 一个purge参数引发的惨案——从线上hbase数据被删事故说起
在写这篇blog前,我的心情久久不能平静,虽然明白运维工作如履薄冰,但没有料到这么一个细小的疏漏会带来如此严重的灾难.这是一起其他公司误用puppet参数引发的事故,而且这个参数我也曾被“坑过”. ...
- 【深入浅出.Net IL】1.一个For循环引发的IL
.Net底层剖析目录章节 1.[深入浅出.Net IL]1.一个For循环引发的IL 2.[.Net底层剖析]2.stfld指令-给对象的字段赋值 3.[.Net底层剖析]3.用IL来理解属性 1.准 ...
- Mysql中where条件一个单引号引发的性能损耗
日常写SQL中可能会有一些小细节忽略了导致整个sql的性能下降了好几倍甚至几十倍,几百倍.以下这个示例就是mysql语句中的一个单引号('')引发的性能耗损,我相信很多朋友都遇到过,甚至还在这样写. ...
- Spring 循环引用(一)一个循环依赖引发的 BUG
Spring 循环引用(一)一个循环依赖引发的 BUG Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) Spring 循环 ...
- Linux Framebuffer驱动剖析之中的一个—软件需求
嵌入式企鹅圈将以本文作为2015年的终结篇,以回应第一篇<Linux字符设备驱动剖析>.嵌入式企鹅圈一直专注于嵌入式Linux和物联网IOT双方面的原创技术分享,稍后会公布嵌入式企鹅圈的2 ...
- 一个由正则表达式引发的血案 vs2017使用rdlc实现批量打印 vs2017使用rdlc [asp.net core 源码分析] 01 - Session SignalR sql for xml path用法 MemCahe C# 操作Excel图形——绘制、读取、隐藏、删除图形 IOC,DIP,DI,IoC容器
1. 血案由来 近期我在为Lazada卖家中心做一个自助注册的项目,其中的shop name校验规则较为复杂,要求:1. 英文字母大小写2. 数字3. 越南文4. 一些特殊字符,如“&”,“- ...
随机推荐
- Delphi之静态方法,虚方法virtual,动态dynamic,抽象abstract,消息
Delphi之静态方法,虚方法virtual,动态dynamic,抽象abstract,消息 http://www.cnblogs.com/zhwx/archive/2012/08/28/266055 ...
- 封装jdbc 单例模式的应用
实现增删该查的jdbc封装 import java.io.IOException; import java.io.InputStream; import java.sql.Connection; im ...
- HDU5838 Mountain(状压DP + 容斥原理)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5838 Description Zhu found a map which is a N∗M ...
- Solr DIH JDBC 源码解析
Solr DIH 源码解析 DataImportHandler.handleRequestBody()中的importer.runCmd(requestParams, sw) if (DataImpo ...
- 【填坑】bzoj3224 splay裸题
人生第一道splay不出所料是一道裸题,一道水题,一道2k代码都不到的题 #include <cstdio> ,n,p,q; ],c[][],size[],sp[]; void rot(i ...
- Notepad++ 默认快捷键
Notepad++绝对是windows下进行程序编辑的神器之一,要更快速的使用以媲美VIM,必须灵活掌握它的快捷键,下面对notepad++默认的快捷键做个整理(其中有颜色的为常用招数): 1 ...
- VMware Workstation 12序列号
VMware Workstation 12序列号:5A02H-AU243-TZJ49-GTC7K-3C61N 就好像之前微软,让大家用盗版一样,这样可以更快的拥有市场占有率.事实上,输入key即可永久 ...
- 复习排序with javascript
最近又翻看了一下数据结构(数据结构学渣). 以前总是看不懂,连冒泡和选择排序都要纠结半天,后来才慢慢有意识能区分开来. 当真的理解了快速排序之后,才觉得,这是个很赞的排序,很容易理解. 于是简单的,模 ...
- [LintCode] Merge Two Sorted Lists 混合插入有序链表
Merge two sorted (ascending) linked lists and return it as a new sorted list. The new sorted list sh ...
- <十二>JDBC_批量处理
import java.sql.Connection;import java.sql.PreparedStatement;import org.junit.Test;import com.kk.jdb ...