亲宝软件园·资讯

展开

Unity 游戏框架搭建 2019 (十六、十七) localPosition 简化与Transform 重置

凉鞋的笔记 人气:0
在上一篇我们收集了一个 屏幕分辨率检测的一个小工具。今天呢再往下接着探索。 ### 问题 我们今天在接着探索。不管是写 UI 还是写 GamePlay,多多少少都需要操作 Transform。 而在笔者刚接触 Unity 的时候有一个非常不习惯的地方。就是对 transform 的位置、角度、缩放进行赋值。 比如,如果仅仅是对 transform.localPosition.x 进行赋值。 代码要这样写。 ```cs var localPosition = transform.localPosition; localPosition.x = 5.0f; transform.localPosition = localPosition; ``` 或者这样写 ```cs transform.localPosition = new Vector3(5.0f,transform.localPosition.y,transform.localPosition.z) ``` 原因是因为 Vector3 是 struct 类型的。我们可以把它理解成值类型,在接收 Vector3 对象的时候是值的拷贝,而不是引用的赋值。这个是 C# 的一点语法细节,如果不明白的童鞋,建议搜索一下。 而在 Quick-Cocos2dx 中只需要一行代码就够了。 ```lua self:setPositionX(5) ``` 注意:这是 Lua 代码。 而笔者呢,在接触 Unity 之前,从学校开始算起就做了 2 年 Cocos2dx,自然很难改掉这个习惯。由于原理很简单就索性自己写一个。 代码如下: ```lua #if UNITY_EDITOR using UnityEditor; #endif using UnityEngine; namespace QFramework { public class TransformLocalPosImprovements { #if UNITY_EDITOR [MenuItem("QFramework/10.Transform 赋值优化")] #endif private static void GenerateUnityPackageName() { var transform = new GameObject("transform").transform; SetLocalPosX(transform, 5.0f); } public static void SetLocalPosX(Transform transform, float x) { var localPos = transform.localPosition; localPos = x; transform.localPosition = localPos; } } } ``` 代码很容易理解,由于考虑到一个 方法名的长度,所以将 Position 缩写成了 Pos。 代码的执行结果如下图所示: ![006tNc79gy1fzdi1ise58j31aa0e2n06.jpg](http://file.liangxiegame.com/eba64ab4-36bf-4491-ae2c-7372b10b4dd7.png) 结果是正确的。 ### 支持 Y 和 Z 除了对 transform 支持 X 之外,我们还要支持 Y 和 Z。因为他们同样使用很频繁。 代码如下: ```cs public static void SetLocalPosY(Transform transform, float y) { var localPos = transform.localPosition; localPos.y = y; transform.localPosition = localPos; } public static void SetLocalPosZ(Transform transform, float z) { var localPos = transform.localPosition; localPos.z = z; transform.localPosition = localPos; } ``` ### 支持 XY、XZ 和YZ 当然还 XY、XZ 和 YZ 也是同样需要支持的。但是这里呢,其实可以有两个选择: 1. 调用 SetPositionX、SetPositionY 、SetPositionZ 2. 逻辑全部实现 第一种好处就是代码能够复用,但是每次进行一次调用,其实是一次值类型的复制操作。所以从性能的角度来讲不推荐。 第二种的好处就是性能相对更好一点,但是代码量会增多。 综合考虑,选择第二种。 代码如下: ```cs public static void SetLocalPosXY(Transform transform, float x, float y) { var localPos = transform.localPosition; localPos.x = x; localPos.y = y; transform.localPosition = localPos; } public static void SetLocalPosXZ(Transform transform, float x, float z) { var localPos = transform.localPosition; localPos.x = x; localPos.z = z; transform.localPosition = localPos; } public static void SetLocalPosYZ(Transform transform, float y, float z) { var localPosition = localPos; localPos.y = y; localPos.z = z; transform.localPosition = localPos; } ``` 代码没啥难点。 全部代码如下: ```cs #if UNITY_EDITOR using UnityEditor; #endif using UnityEngine; namespace QFramework { public class TransformLocalPosImprovements { #if UNITY_EDITOR [MenuItem("QFramework/10.Transform 赋值优化")] #endif private static void GenerateUnityPackageName() { var transform = new GameObject("transform").transform; SetLocalPosX(transform, 5.0f); SetLocalPosY(transform, 5.0f); SetLocalPosZ(transform, 5.0f); } public static void SetLocalPosX(Transform transform, float x) { var localPos = transform.localPosition; localPos.x = x; transform.localPosition = localPos; } public static void SetLocalPosY(Transform transform, float y) { var localPos = transform.localPosition; localPos.y = y; transform.localPosition = localPos; } public static void SetLocalPosZ(Transform transform, float z) { var localPos = transform.localPosition; localPos.z = z; transform.localPosition = localPos; } public static void SetLocalPosXY(Transform transform, float x, float y) { var localPos = transform.localPosition; localPos.x = x; localPos.y = y; transform.localPosition = localPos; } public static void SetLocalPosXZ(Transform transform, float x, float z) { var localPos = transform.localPosition; localPos.x = x; localPos.z = z; transform.localPosition = localPos; } public static void SetLocalPosYZ(Transform transform, float y, float z) { var localPos = transform.localPosition; localPos.y = y; localPos.z = z; transform.localPosition = localPos; } } } ``` 这个呢,是我们的第十个示例。 我们又可以进行导出了。 ## Transform 重置 今天我们再往下接着探索,我们的 Transform。 我们经常要写这样的逻辑,对一个 Transform 的位置、旋转、缩放值进行重置。 代码如下: ```cs transform.localPosition = Vector3.zero; transform.localScale = Vector3.one; transform.localRotation = Quaternion.identity; ``` 代码大家应该经常会写到。 我们提取后的方法如下: ```cs #if UNITY_EDITOR using UnityEditor; #endif using UnityEngine; namespace QFramework { public class TransformIdentity : MonoBehaviour { #if UNITY_EDITOR [MenuItem("QFramework/11.Transform 归一化")] #endif private static void MenuClicked() { var transform = new GameObject("transform").transform; Identity(transform); } /// /// 重置操作 /// /// Trans. public static void Identity(Transform transform) { transform.localPosition = Vector3.zero; transform.localScale = Vector3.one; transform.localRotation = Quaternion.identity; } } } ``` 代码的执行结果是正确的。 那么有人会问 Identity 是什么意思呢?Identity 其实是一个矩阵的类型,对角线全部是 1 而其他的部分全部是 0,如下图所示。 ![006tNc79gy1fzdi20inapj302b03lgle.jpg](http://file.liangxiegame.com/cc202d0a-3bcd-4892-8080-799d0cf783d3.png) 实际上 Transform 本质是一个 4x4 的矩阵,这个矩阵可以记录矩阵的位置、旋转和缩放值。而 Identity 矩阵对应的 Transform 就是位置为 0、缩放为 1、Rotation 值为 Quaternion.identity 这样的矩阵。 这里不太理解的同学不要紧,重点还是以上代码中的 Identity 方法的实现。 OK,到这里,我们又可以进行一次导出了。 到今天为止,我们收集了十一个示例了。收获满满,大家应该收集了更多的示例了吧? 今天的内容就这些。 转载请注明地址:凉鞋的笔记:[liangxiegame.com](http://liangxiegame.com) ## 更多内容 * QFramework 地址:[https://github.com/liangxiegame/QFramework](https://github.com/liangxiegame/QFramework) * QQ 交流群:[623597263](http://shang.qq.com/wpa/qunwpa?idkey=706b8eef0fff3fe4be9ce27c8702ad7d8cc1bceabe3b7c0430ec9559b3a9ce66) * **Unity 进阶小班**: * 主要训练内容: * 框架搭建训练(第一年) * 跟着案例学 Shader(第一年) * 副业的孵化(第二年、第三年) * 权益、授课形式等具体详情请查看[《小班产品手册》](https://liangxiegame.com/master/intro):https://liangxiegame.com/master/intro * 关注公众号:liangxiegame 获取第一时间更新通知及更多的免费内容。 ![](http://file.liangxiegame.com/38eccb55-40b2-4845-93d6-f5fb50ff9492.png)

加载全部内容

相关教程
猜你喜欢
用户评论