您的位置 首页 自媒体

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

在上一篇我们收集了一个 屏幕分辨率检测的一个小工具。今天呢再往下接着探索。 问题 我们今天在接着探索。不管是写 UI 还是写 GamePlay,多多少少都需要操作 Transfor…

在上一篇我们收集了一个 屏幕分辨率检测的一个小工具。今天呢再往下接着探索。

问题

我们今天在接着探索。不管是写 UI 还是写 GamePlay,多多少少都需要操作 Transform。

而在笔者刚接触 Unity 的时候有一个非常不习惯的地方。就是对 transform 的位置、角度、缩放进行赋值。

比如,如果仅仅是对 transform.localPosition.x 进行赋值。

代码要这样写。

var localPosition = transform.localPosition;
localPosition.x = 5.0f;
transform.localPosition = localPosition;

或者这样写

transform.localPosition = new Vector3(5.0f,transform.localPosition.y,transform.localPosition.z)

原因是因为 Vector3 是 struct 类型的。我们可以把它理解成值类型,在接收 Vector3 对象的时候是值的拷贝,而不是引用的赋值。这个是 C# 的一点语法细节,如果不明白的童鞋,建议搜索一下。

而在 Quick-Cocos2dx 中只需要一行代码就够了。

self:setPositionX(5)

注意:这是 Lua 代码。

而笔者呢,在接触 Unity 之前,从学校开始算起就做了 2 年 Cocos2dx,自然很难改掉这个习惯。由于原理很简单就索性自己写一个。

代码如下:

#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。

代码的执行结果如下图所示:

结果是正确的。

支持 Y 和 Z

除了对 transform 支持 X 之外,我们还要支持 Y 和 Z。因为他们同样使用很频繁。

代码如下:

		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. 逻辑全部实现

第一种好处就是代码能够复用,但是每次进行一次调用,其实是一次值类型的复制操作。所以从性能的角度来讲不推荐。

第二种的好处就是性能相对更好一点,但是代码量会增多。

综合考虑,选择第二种。

代码如下:

		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;
		}

代码没啥难点。

全部代码如下:

#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 的位置、旋转、缩放值进行重置。

代码如下:

transform.localPosition = Vector3.zero;
transform.localScale = Vector3.one;
transform.localRotation = Quaternion.identity;

代码大家应该经常会写到。

我们提取后的方法如下:

#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);
		}

		/// <summary>
		/// 重置操作
		/// </summary>
		/// <param name="trans">Trans.</param>
		public static void Identity(Transform transform)
		{
			transform.localPosition = Vector3.zero;
			transform.localScale = Vector3.one;
			transform.localRotation = Quaternion.identity;
		}
	}
}

代码的执行结果是正确的。

那么有人会问 Identity 是什么意思呢?Identity 其实是一个矩阵的类型,对角线全部是 1 而其他的部分全部是 0,如下图所示。

实际上 Transform 本质是一个 4×4 的矩阵,这个矩阵可以记录矩阵的位置、旋转和缩放值。而 Identity 矩阵对应的 Transform 就是位置为 0、缩放为 1、Rotation 值为 Quaternion.identity 这样的矩阵。

这里不太理解的同学不要紧,重点还是以上代码中的 Identity 方法的实现。

OK,到这里,我们又可以进行一次导出了。

到今天为止,我们收集了十一个示例了。收获满满,大家应该收集了更多的示例了吧?

今天的内容就这些。

转载请注明地址:凉鞋的笔记:liangxiegame.com

更多内容

本文来自网络,不代表媒体资讯网立场,转载请注明出处:http://meiti.org/archives/1195.html

作者: vmayfuture

为您推荐

发表评论

电子邮件地址不会被公开。 必填项已用*标注

返回顶部