分类:Unity、C#、VS2015

创建日期:2016-04-20

一、简介

在虚拟的游戏世界中,与3D有关的数学知识决定了游戏引擎如何计算和模拟出开发者以及玩家看到的每一帧画面。学习或者回想一下基础的3D有关的数学知识,可以帮助开发者对游戏引擎产生更深刻的了解。

二、向量

在数学中向量的定义是:既有大小又有方向的量叫作向量。在空间中,向量可以用一段有方向的线段来表示。

向量在游戏开发过程中的应用十分广泛,可用于描述具有大小和方向两个属性的物理量,例如物体运动的速度、加速度、摄像机观察方向、刚体受到的力等都是向量,因此向量是物理、动画、三维图形的基础。

1、向量相关概念

·模:向量的长度。

·标准化(Normalizing):保持方向不变,将向量的长度变为1。

·单位向量:长度为1的向量。

·零向量:各分量均为0的向量。

2、向量的运算

(1)加减

向量的加法(减法)为各分量分别相加(相减)。在物理上可以用来计算两个力的台力,或者几个速度分量的叠加。

(2)数乘

向量与一个标量相乘称为数乘。数乘可以对向量的长度进行缩放,如果标量大于0,那么向量的方向不变;若标量小于0,则向量的方向会变为反方向。

(3)点乘

两个向量点相乘得到一个标量,数值等于两个向量长度相乘后再乘以二者夹角的余弦值。如果两个向量a,b均为单位向量,那么a.b等于向量b在向量a方向上的投影的长度(也等于向量a在向量b方向的投影)

通过两个向量点乘结果的符号可以快速地判断两个向量的夹角情况:

若u·v = 0,则向量u、v相互垂直。

若u·v > 0,则向量u、v夹角小于90°。

若u·v <0,则向量u、v夹角大于90°。

(4)叉乘

两个向量的叉乘得到一个新的向量,新向量垂直于原来的两个向量,并旦长度等于原向量长度相乘后再乘夹角的正弦值。

可以通过左手摆出上图所示的手势来判断叉乘结果的方向(使用左手是因为Unity里用的是左手坐标系)。假设有向量Result=a×b,将拇指朝向a的方向,食指指向b的方向,则中指指向的方向为叉乘结果的方向。

注意:叉乘不满足交换律,即a× b≠ b× a。

三、Vector3类

在Unity中,和向量有关的类有Vector2、Vector3、Vector4,分别对应不同维度的向量,其中Vector3的使用最为广泛。

1、成员变量和方法

Vector3类的常用成员变量和方法如下:

x、y、z:向量的X分量、Y分量、Z分量。

normalized:获取单位化后的向量(只读)。

magnitude:获取向量长度(只读)。

sqrMagnitude获取向量长度的平方(只读)。

Cross():向量叉乘。

Dot():向量点乘。

Project():计算向量在另一向量上的投影。

Angle():返回两个向量之间的夹角。

Distance():返回两个向量之间的距离。

运算符:+、-、*、/、==、!=

下面是Vector3类的—些应用示例。

2、示例1(Demo7_1_DistanceTest.unity)

该例子演示了如何计算两个位置之间的距离。其中other变量绑定的游戏对象的坐标为(50,50,50),脚本绑定的目标对象的坐标为(-2,-3.3,-10)。

在Distance.unity场景中使用了本示例的源文件,运行效果如下:

下面是该场景中使用的C#脚本代码(DistanceTest.cs文件):

  1. using UnityEngine;
  2. using System.Collections;
  3. public class DistanceTest : MonoBehaviour
  4. {
  5. public Transform other;
  6. void Start()
  7. {
  8. if (other != null)
  9. {
  10. var dist = Vector3.Distance(other.position, transform.position);
  11. print("Distance to other: " + dist);
  12. }
  13. }
  14. }

3、示例2(Demo7_2_DirectionMove.unity)

该例子演示如何让游戏对象沿着指定的方向移动。

DirectionMove.cs的代码如下:

  1. using UnityEngine;
  2. using System.Collections;
  3. public class DirectionMove : MonoBehaviour
  4. {
  5. public Vector3 direction = Vector3.forward;//移动方向
  6. public float speed = 5.0f;//速度
  7.  
  8. void Update()
  9. {
  10. transform.position += direction * speed * Time.deltaTime;
  11. }
  12. }

4、示例3(Demo7_3_SqrMagnitude.unity)

该例子演示如何利用Vector3.sqrMagnitude来判断目标对象的距离是否小于触发距离,其中other变量的坐标为(-2,-3,-10),该脚本绑定的游戏对象的坐标为(-2,-3.3,-10)。

使用的脚本(SqrMagnitude.cs文件)代码如下:

  1. using UnityEngine;
  2. using System.Collections;
  3. public class SqrMagnitude : MonoBehaviour
  4. {
  5. public Transform other; //目标物体的Transform
  6. public double closeDistance = 5.0; // 触发距离
  7. void Update()
  8. {
  9. if (other)
  10. {
  11. var sqrLen = (other.position - transform.position).sqrMagnitude;
  12. // 使用Vector3.sqrMagnitude比Vector3.magnitude计算速度要快
  13. if (sqrLen < closeDistance * closeDistance)
  14. {
  15. print("目标物体已靠近!");
  16. }
  17. }
  18. }
  19. }

5、示例4(Demo7_4_MoveToTarget.unity)

该例子演示对象从初始点平滑移动到目标点的动画,其中start变量绑定的对象坐标为(-3,-3,-10),end变量绑定的坐标为(-3,-3,20)。

使用的脚本(MoveToTarget.cs文件)代码如下:

  1. using UnityEngine;
  2. using System.Collections;
  3. public class MoveToTarget : MonoBehaviour
  4. {
  5. public Transform start; //初始位置
  6. public Transform end; //终点位置
  7. void Update()
  8. {
  9. transform.position = Vector3.Lerp(start.position, end.position, Time.time);
  10. }
  11. }

6、示例5(Demo7_5_SunRiseAndDown.unity)

该例子演示如何利用Slerp插值方法模拟太阳升起和落下的过程。

使用的脚本(SunRiseAndDown.cs文件)代码如下:

  1. using UnityEngine;
  2. using System.Collections;
  3. public class SunAndRise : MonoBehaviour
  4. {
  5. public Transform sunrise;//升起位置
  6. public Transform sunset; //落下位置
  7. public float journeyTime = 10.0f; //从升起到落下需要的时间,以秒为单位
  8. private float startTime; //用于记录开始的时间
  9.  
  10. void Start()
  11. {
  12. startTime = Time.time; // 设置开始的时间
  13. }
  14.  
  15. void Update()
  16. {
  17. var center = (sunrise.position + sunset.position) * 0.5f;//计算运行轨迹的圆心点
  18. center -= new Vector3(0, 1, 0);
  19. var riseRelCenter = sunrise.position - center;//升起位置到圆心的向量
  20. var setRelCenter = sunset.position - center; //落下位置到圆心的向量
  21. var fracComplete = (Time.time - startTime) / journeyTime;//计算用于插值的系数
  22. transform.position = Vector3.Slerp(riseRelCenter, setRelCenter, fracComplete);//Slerp插值
  23. transform.position += center;
  24. }
  25. }

下面是该例子的运行效果:

四、矩阵

相向量一样,矩阵也是3D数学中十分重要基础。

1、矩阵的概念

m× n的矩阵是一个具有m行、n列的矩形数组,行数和列数分别为矩阵的维度。在游戏引擎中使用的矩阵通常为4×4矩阵,因为它可以描述向量的平移、旋转、缩放等所有的线性变换。

2、矩阵的计算

自己看其他参考资料吧。

3、Matrix4x4类

Unity使用Matrix4x4类来描述4×4矩阵。

更多介绍请参看其他参考资料。

五、奇次坐标

在3D数学中,齐次坐标就是将原本3维的向量(x,y,z)用4维向量(wx,wy,wz,w)来表示。引入齐次坐标的主要有如下目的:

1、可更好地区分向量和点。在三维空间中, (x,y,z)既可以表示点也可以表示分量,不便于区分,如果引入齐次坐标,则可以使用(x,y,z,1)来表示坐标点,使用(x,y,z,0)来表示向量。

2、统—用矩阵乘法表示平移、旋转、缩放变换。如果使用3×3的矩阵,矩阵乘法只能表示旋转和缩放变换,无法表示平移变换。而在4D齐次空间中,可以使用4×4的齐次矩阵来统一表示平移、旋转、缩放变换。

3、当分量w=0时可以用来表示无穷远的点。

齐次坐标是计算机图形学中一个非常重要的概念,但是在Unity中很少需要直接和它打交道,在编写一些shader可能会用到它,平时在脚本中主要还是使用三维向量Vector3。Unity通过便利的接口设计将这一重要概念隐藏在了引擎后面。

【Unity】6.7 向量和Vector3类的更多相关文章

  1. Unity学习之路——主要类

    学习https://blog.csdn.net/VRunSoftYanlz/article/details/78881752 1.Component类gameObject:组件附加的游戏对象.组件总是 ...

  2. 【Unity】6.6 Random类

    分类:Unity.C#.VS2015 创建日期:2016-04-20 一.简介 Unity引擎提供的Random类可以用来生成随机数.随机点或旋转角度. 1.成员变量 seed:设置用于随机数生成器的 ...

  3. Unity协程(Coroutine)管理类——TaskManager工具分享

    博客分类: Unity3D插件学习,工具分享 源码分析   Unity协程(Coroutine)管理类——TaskManager工具分享 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处 ...

  4. 【Unity】6.5 Time类、Mathf类、Coroutine类

    分类:Unity.C#.VS2015 创建日期:2016-04-20 一.Time类 Unity引擎提供的Time类可获取和时间有关的信息.计算帧速率.调整时间流逝速度等. 1.成员变量 2.示例 ( ...

  5. Unity 自动生成组件索引类工具

    Unity 自动生成组件索引类工具 需求由来 我们在写UI类时 需要获取预设中的组件 joystick = transform.Find("joystick"); backgrou ...

  6. 【转】【Unity】实现全局管理类的几种方式

    本文原作者未知,转载自:http://blog.csdn.net/ycl295644/article/details/42458477 如何在Unity中实现全局管理类?由于Unity脚本的运行机制和 ...

  7. Unity中实现全局管理类的几种方式

    (搬运自我在SegmentFault的博客) 如何在Unity中实现全局管理类?由于Unity脚本的运行机制和面向组件编程(COP)的思想,实现起来和普通的方式略有差别. 第一种方式是使用静态类.适合 ...

  8. Unity API 解析(13)—— Vector3 类

    三维向量或三维坐标点 normalized —— 单位化向量 返回方向相同模长为1的向量 sqrMagnitude —— 模长平方 Scale —— 向量缩放 Angle —— 两向量夹角 Cross ...

  9. 【Unity】6.8 Quaternion类(四元数)

    分类:Unity.C#.VS2015 创建日期:2016-04-20 一.四元数的概念 四元数包含一个标量分量和-个三维向量分量,四元数Q可以记作: Q=[w,(x,y,z)] 在3D数学中使用单位四 ...

随机推荐

  1. 【Linux】awk详细介绍

    awk简介 awk是一种使用方便且表现力很强的编程语言,它可以应用在多种不同的计算与数据处理任务中.由于awk天生提供对文件中文本分列进行处理,所以如果一个文件中的每行都被特定的分隔符(常见的是空格) ...

  2. V-rep学习笔记:机器人路径规划1

     Motion Planning Library V-REP 从3.3.0开始,使用运动规划库OMPL作为插件,通过调用API的方式代替以前的方法进行运动规划(The old path/motion ...

  3. 3299 有序数组合并求第K大问题

    题目描述 Description 给出两个有序数组A和B(从小到大有序),合并两个有序数组后新数组c也有序,询问c数组中第k大的数 假设不计入输入输出复杂度,你能否给出一个O(logN)的方法? 输入 ...

  4. Easyui入门视频教程 第10集---Messager的使用

    Easyui入门视频教程 第10集---Messager的使用 <script type="text/javascript"> function show(){ $.m ...

  5. Lua初学

    Lua很火啊,而且跟C,c++可以无缝结合,表示很给力,算是我的第三门语言吧,哈哈! 在官网上下载了源码了,和windows版的,表示编译器也很给力,直接可以用SciTE就可以写代码了. a = 1; ...

  6. 解决IE弹框提示“是否停止运行此脚本”问题

    有少数情况因为js处理内容较多,系统计算标红和刷新页面较慢,IE可能会弹框提示“是否停止运行此脚本”,若想要继续,点击“否”即可.并同时按照下面的设置更改一下注册表,即可解决弹框问题. http:// ...

  7. linux c学习笔记----线程创建与终止

    进程原语 线程原语 描述 fork pthread_create 创建新的控制流 exit pthread_exit 从现有的控制流中退出 waitpid pthread_join 从控制流中得到退出 ...

  8. k8s之Service

    一.概述 在k8s中暴露Service访问(无论内部还是外部),都要经过kube-proxy: 如下图:

  9. MongoDB 2.6配置副本集,支持端口号修改和用户登录认证

    mongoDB系列之(二):mongoDB 副本集 Mongodb2.6副本集验证部署和认证 副本集有以下特点: 1. 最小构成是:primary,secondary,arbiter,一般部署是:pr ...

  10. java-容器-ArrayList

    工作中经常会用到Java的集合类,最近不忙了,把相关知识总结一下,便于理解记忆. 打开java.util.ArrayList的源代码,首先映入眼帘的是@author  Josh Bloch(相对于源码 ...