zoukankan      html  css  js  c++  java
  • Unity 游戏框架搭建 2019 (十六、十七) localPosition 简化与Transform 重置

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

    问题

    我们今天在接着探索。不管是写 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。

    代码的执行结果如下图所示:
    006tNc79gy1fzdi1ise58j31aa0e2n06.jpg

    结果是正确的。

    支持 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,如下图所示。
    006tNc79gy1fzdi20inapj302b03lgle.jpg

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

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

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

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

    今天的内容就这些。

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

    更多内容

  • 相关阅读:
    scala中List、Array、ListBuffer、ArrayList、Set
    Spark Pipeline
    Spark MLlib
    minikube
    proxychains 安装
    网络性能测试
    Flexvolume
    kubectl 获取信息
    centos7 莫名重起的问题
    fio 测试磁盘
  • 原文地址:https://www.cnblogs.com/liangxiegame/p/12617707.html
Copyright © 2011-2022 走看看