协程的嵌套和调用模式
通过yield return 嵌套,子协程执行完之后父进程才继续执行12345678910111213141516171819202122232425262728293031using System.Collections;using UnityEngine; public class test2 : MonoBehaviour { void Start () { Debug.Log("Start0"); StartCoroutine(test()); Debug.Log("Start1"); } IEnumerator test() { Debug.Log("test0"); yield return StartCoroutine(testzz()); Debug.Log("test1"); } IEnumerator testzz( ...
通用预备知识
使用协程分解复杂逻辑在Unity中,协程可以处理一些异步任务。例如,假设某一个角色有“饱食度”和“困倦值”两个属性,这两个属性会不断衰减,当角色饿了会自己寻找食物,困了时会去睡觉。
不用状态机,借助协程解决:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687using System.Collections;using UnityEngine;namespace ACTBook{ public class VillagerFSM : MonoBehaviour { public const float FATIGUE_DEFAULT_VALUE = 12f;//疲倦默认值 public const float SATIATION_DEFAULT_VAL ...
3D开发实战技巧
头顶显示文字、冒血数字、合并网格、合并贴图等实战技巧
Text Mesh 3D头顶文字我们在“摄像机——3D坐标转换UI坐标”中学到了通过RectTransformUtility.ScreenPointToLocalPointInRectangle来显示血条和文字,这种做法其实并不太好。因为只要人物移动或者摄像机移动,就需要一直换算坐标,这将带来一定开销。
创建Test Mesh组件并将其直接挂载角色身上,这样头顶文字就会自动跟着角色移动,只要将此组件绑为角色的子对象即可。
其中characterSize = targetSizeInWorldUnits * 10.0f / fontSize。FontSize是加载的字体形状大小,characterSize是渲染出的网格大小,不过两者共同控制网格
Text Mesh图文混排如果显示文字的同时还需要显示图标,那么可以使用Rich Text的功能。将需要参与图文混排的图片放入一个新材质中,并且绑定在Text Mesh的Materials数组中,写入富文本支持的tag即可
<quad material=1&g ...
Unity四元数和向量相乘作用及其运算规则
作用:四元数和向量相乘表示这个向量按照这个四元数进行旋转之后得到的新的向量。
Unity - Scripting API: Quaternion.operator * (unity3d.com)
比如:向量vector3(0,0,10),绕着Y轴旋转90度,得到新的向量是vector3(10,0,0)。
在unity中表示为:
123456789101112using UnityEngine;public class QuaternionMultVector : MonoBehaviour{ void Start() { Vector3 v = new Vector3(0, 0, 10); Quaternion q = Quaternion.Euler(0, 90, 0); Vector3 nv = q * v; // Quaternion必须在Vector前面乘,因为只有Quaternion重载了*运算符 Debug.Log(nv); }}
复合旋转就是四元数依次相乘 ...
C# 枚举的位运算
在使用Unity时,发现了if ((controller.collisionFlags & CollisionFlags.Sides) != 0)代码,发现是使用了C#枚举位运算,遂记录。
一、枚举枚举是是名称与值的集合,枚举类型是值类型。
123456789public enum Options{ Insert, // =0 Update, // =1 Save, // =... Delete, Query}
编译器会自动补充枚举,从零开始依次赋值。
二、位运算我们可能需要多个枚举的组合来满足我们的需要。
位运算是针对二进制位进行的运算,常用的位运算主要有与(&), 或(|)和非(~)
12//e.m:1 & 0 = 0, 1 | 0 = 1, ~1 = 0
要使枚举类型具有位运算的能力,需要加上特性[FlagsAttribute]简写[Flags]。有些位处于on状态,有些处于off状态。所以通常在定义一个None=0的枚举符 ...
输入事件和物理碰撞
Unity中的输入事件可分为两种,一种是全局触发的,需要在更新每一帧来判断;还要一种是监听式触发的,就是监听点击的事件回调从而处理后面的逻辑。
全局事件全局输入事件需要使用Input这个类,它可以监听键盘、鼠标、手势以及移动设备上的3D Touch事件等。
例如点击事件,它只能监听屏幕中的事件,并不能判断是点在了3D模型上还是点在了UI上。并且它没有提供触发事件,需要在Update()中通过每一帧去判断。
123456789101112131415161718192021222324252627282930313233343536using UnityEngine;public class UnityInputTest : MonoBehaviour{ void Update() { //按下Horizontal指定的键,并且有平滑 Input.GetAxis("Horizontal"); //按下Horizontal指定的键,并且无平滑 Input.GetAxisRaw(&qu ...
场景管理
切换场景场景切换的原则是删除当前场景,切换新场景
1234//同步切换场景SceneManager.LoadScene("scenename");//异步切换场景SceneManager.LoadSceneAsync("scenename")
DontDestroyOnLoad切换新场景会自动卸载老场景,不过UI节点和主角并不需要删除,需要标记为DontDestroyOnload。
1GameObject.DontDestroyOnLoad(gameObject);
异步加载场景以及进度Unity的某些主要异步方法都会返回AsyncOperation,它属于一种协程。 常见的异步方法:SceneManager.LoadSceneAsync, AssetBundle.LoadAssetAsync, Resources.LoadAsync.
Unity - Scripting API: AsyncOperation (unity3d.com)
首先,封装一下加载的管理器类:
123456789101112131415161718192021222 ...
C# 中的协变和逆变
一、可变性的概念C# 一开始就支持数组的协变,听说是为了和 Java 竞争于是就把 Java 的这个不怎么样的特性给实现了。
1object[] myArray = new string[] { "abc", "def", "ghi", // ... };
所谓协变性指的就是,在一个使用宽泛类型的地方,可以传入一个具体类型的对象。那么,最基本的协变就是面向对象中的多态——使用基类型对象的地方,都可以传入派生类对象。
但是,上面这个数组的协变性还是很特别的。首先,在 C# 的类型系统中,派生类型的数组并不继承自基类型的数组(别的语言也是如此吧)。所以,它的确是一种新的协变性。其次,如果你做一个如下操作,你就会收到运行时错误,告诉你数组类型不匹配:
1myArray[0] = 3;
也就是说,CLR 还是知道 myArray 到底是什么类型的,并且不许改变。
逆变就是反过来的概念——在一个使用具体类型的地方,可以传入宽泛类型的对象。
二、委托中的可变性在 C# 1 中,如果我们定义一个委托类型,那么用于它的 ...
摄像机
摄像机之间的管理、排序、3D坐标与平面坐标之间的转换等
3D坐标转换屏幕坐标Unity的屏幕坐标系规定左下角是原点、X轴向右为正,Y轴向上为正。
Unity IMGUI坐标系规定左上角是原点,X轴向右为正,Y轴向下为正,如果我们想把转换的屏幕坐标用IMGUI在相同的位置显示出来,就需要用屏幕高度减去鼠标点击屏幕的Y轴坐标。
123456789101112131415161718192021222324252627using UnityEngine;public class D3CoordinateToScreenCoordinate : MonoBehaviour{ private Vector2 m_ScreenPotin = Vector3.zero; // Update is called once per frame void Update() { if (Input.GetMouseButtonDown(0)) { Ray ray = Camera.main.Scr ...
PS消失点滤镜和混合颜色带
使用Photoshop消失点滤镜来快速贴图
打开PhotoShop,拉取一张楼梯图片
打开滤镜——消失点(Alt+Ctrl+V)
在内部根据楼梯的走向先创建一个平面,然后使用创建平面工具将平面完全延展覆盖
打开一个需要贴上去的图片,然后Ctrl+A、Ctrl+C复制
回到阶梯文件,新建一个图层,然后再打开滤镜——消失点,Ctrl+V粘贴并移动图片到创建的平面区域内
接下来是一些后期工作,我们可以使用混合颜色带来让贴图下方的图层来控制贴图的显示范围,其中的下一图层是下方所有图层的意思,按住Alt键来拖动滑块可以产生平滑的过度,除了灰色以外,还可以红绿蓝三色分别控制。