需求

  • 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的更多相关文章

  1. 由一个项目需求引发的 - textarea中的换行和空格

    当我们使用 textarea 在前台编辑文字,并用 js 提交到后台的时候,空格和换行是我们最需要考虑的问题.在textarea 里面,空格和换行会被保存为/s和/n,如果我们前台输入和前台显示的文字 ...

  2. Spring之LoadTimeWeaver——一个需求引发的思考---转

    原文地址:http://www.myexception.cn/software-architecture-design/602651.html Spring之LoadTimeWeaver——一个需求引 ...

  3. Unity编辑器扩展 Chapter3--Create Custom Inspector

    一.Create Custom Inspector 重绘inspector面板一方面是我们的挂在脚本的窗口变得友好,另一方面可以让其变得更强大,比如添加一些有效性验证. 二.重要说明 1.Editor ...

  4. 一个purge参数引发的惨案——从线上hbase数据被删事故说起

    在写这篇blog前,我的心情久久不能平静,虽然明白运维工作如履薄冰,但没有料到这么一个细小的疏漏会带来如此严重的灾难.这是一起其他公司误用puppet参数引发的事故,而且这个参数我也曾被“坑过”.   ...

  5. 【深入浅出.Net IL】1.一个For循环引发的IL

    .Net底层剖析目录章节 1.[深入浅出.Net IL]1.一个For循环引发的IL 2.[.Net底层剖析]2.stfld指令-给对象的字段赋值 3.[.Net底层剖析]3.用IL来理解属性 1.准 ...

  6. Mysql中where条件一个单引号引发的性能损耗

    日常写SQL中可能会有一些小细节忽略了导致整个sql的性能下降了好几倍甚至几十倍,几百倍.以下这个示例就是mysql语句中的一个单引号('')引发的性能耗损,我相信很多朋友都遇到过,甚至还在这样写. ...

  7. Spring 循环引用(一)一个循环依赖引发的 BUG

    Spring 循环引用(一)一个循环依赖引发的 BUG Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) Spring 循环 ...

  8. Linux Framebuffer驱动剖析之中的一个—软件需求

    嵌入式企鹅圈将以本文作为2015年的终结篇,以回应第一篇<Linux字符设备驱动剖析>.嵌入式企鹅圈一直专注于嵌入式Linux和物联网IOT双方面的原创技术分享,稍后会公布嵌入式企鹅圈的2 ...

  9. 一个由正则表达式引发的血案 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. 一些特殊字符,如“&”,“- ...

随机推荐

  1. C++-数据库【1】-C++连接MSSQL数据库

    测试环境—— 系统:Win7 64bit 编译器:VC++ 2015 数据库:MSSQL 2008 R2 #include <Windows.h> #include <stdio.h ...

  2. 蜻蜓FM笔试题目,求两个点的最近父节点

    这个博客写的特别好. http://blog.csdn.net/kangroger/article/details/40392925

  3. [DataMining]WEEK1 - text-retrieval and search engine

    What does a computer have to do in order to understand a natural language sentence? What is ambiguit ...

  4. DateTable利用NPOI导出Excel 公共方法

    protected void Export_Excel(DataTable dt) { string filename = "学生基本信息.xls"; ) { filename = ...

  5. JNI使用问题记录

    此文章包含Android JNI学习过程中的遇到的各种错误记录和学习总结. 1.错误:java.lang.UnsatisfiedLinkError: Native method not found: ...

  6. noi往届题目泛做

    noi2015 Day1 t1 程序自动分析  离散化+并查集 t2 软件包管理器  裸树链剖分 t3 寿司晚宴  状压dp Day2 t1 荷马史诗 哈夫曼多叉树 t2 品酒大会 后缀数组按照hei ...

  7. linux进程后台运行及输出重定向

    本机环境为ubuntu 14.04 以ping www.baidu.com为例: 1.程序的前台运行 ping www.baidu.com 可以看到,屏幕上输出了baidu返回的结果 2.实现程序后台 ...

  8. css3 filter的十种特效

    filter默认值是none,他不具备继承性,其中filter-function具有一下属性: grayscale灰度 sepia褐色(求专业指点翻译) saturate饱和度 hue-rotate色 ...

  9. 2014 summer training总结篇

    还有一周暑期集训就要结束了,从7月份结束军训到现在一个多月的时间,收获也是有的只不过与之前预想的相比显得十分微薄. 无论是前两天的两场个人赛还是之前的组队赛自己始终是在ranklist的后半部分.一开 ...

  10. Jenkins中构建Testcomplete项目的方法介绍

    Jenkins的部署在上一篇随笔中已经和大家介绍了,下面我们介绍一下再Jenkins中构建testcomplete项目.我这里使用的是Testcomplete11,下面详细介绍一下构建步骤. 1.Je ...