分类: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文件):

using UnityEngine;
using System.Collections;
public class DistanceTest : MonoBehaviour
{
public Transform other;
void Start()
{
if (other != null)
{
var dist = Vector3.Distance(other.position, transform.position);
print("Distance to other: " + dist);
}
}
}

3、示例2(Demo7_2_DirectionMove.unity)

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

DirectionMove.cs的代码如下:

using UnityEngine;
using System.Collections;
public class DirectionMove : MonoBehaviour
{
public Vector3 direction = Vector3.forward;//移动方向
public float speed = 5.0f;//速度 void Update()
{
transform.position += direction * speed * Time.deltaTime;
}
}

4、示例3(Demo7_3_SqrMagnitude.unity)

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

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

using UnityEngine;
using System.Collections;
public class SqrMagnitude : MonoBehaviour
{
public Transform other; //目标物体的Transform
public double closeDistance = 5.0; // 触发距离
void Update()
{
if (other)
{
var sqrLen = (other.position - transform.position).sqrMagnitude;
// 使用Vector3.sqrMagnitude比Vector3.magnitude计算速度要快
if (sqrLen < closeDistance * closeDistance)
{
print("目标物体已靠近!");
}
}
}
}

5、示例4(Demo7_4_MoveToTarget.unity)

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

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

using UnityEngine;
using System.Collections;
public class MoveToTarget : MonoBehaviour
{
public Transform start; //初始位置
public Transform end; //终点位置
void Update()
{
transform.position = Vector3.Lerp(start.position, end.position, Time.time);
}
}

6、示例5(Demo7_5_SunRiseAndDown.unity)

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

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

using UnityEngine;
using System.Collections;
public class SunAndRise : MonoBehaviour
{
public Transform sunrise;//升起位置
public Transform sunset; //落下位置
public float journeyTime = 10.0f; //从升起到落下需要的时间,以秒为单位
private float startTime; //用于记录开始的时间 void Start()
{
startTime = Time.time; // 设置开始的时间
} void Update()
{
var center = (sunrise.position + sunset.position) * 0.5f;//计算运行轨迹的圆心点
center -= new Vector3(0, 1, 0);
var riseRelCenter = sunrise.position - center;//升起位置到圆心的向量
var setRelCenter = sunset.position - center; //落下位置到圆心的向量
var fracComplete = (Time.time - startTime) / journeyTime;//计算用于插值的系数
transform.position = Vector3.Slerp(riseRelCenter, setRelCenter, fracComplete);//Slerp插值
transform.position += center;
}
}

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

四、矩阵

相向量一样,矩阵也是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. testNG retry 失败的testcase只需要在xml中配置一个listener即可

    问题情况                                                  先说下问题情况,最近在做testNG与selenium集成做自动化测试的问题. 因为如果将t ...

  2. 使用正态分布变换(Normal Distributions Transform)进行点云配准

    正态分布变换算法是一个配准算法,它应用于三维点的统计模型,使用标准优化技术来确定两个点云间的最优的匹配,因为其在配准过程中不利用对应点的特征计算和匹配,所以时间比其他方法快.下面是PCL官网上的一个例 ...

  3. &lt;图形图像,动画,多媒体&gt; 读书笔记 --- 音效

    音频多媒体文件主要是存放音频数据信息,音频文件在录制的过程中把声音信号,通过音频编码,变成音频数字信号保存到某种格式文件里.在播放过程中在对音频文件解码,解码出的信号通过扬声器等设备就能够转成音波.音 ...

  4. 删除草稿信息之后 threads表的数据没有发生变化

    现象描述: 无论是用_id来删除草稿信息,还是用thread_id和type来删除草稿,草稿都可以删除掉,但是threads表中的数据都没有发生变化. private void removeDraft ...

  5. Android网络开发之蓝牙

    蓝牙采用分散式网络结构以及快调频和短包技术,支持点对点及点对多点通信,工作在全球通用的2.4GHz ISM(I-工业.S-科学.M-医学)频段,其数据速率为1Mbps,采用时分双工传输方案.   蓝牙 ...

  6. Ubuntu 13.04有线连接异常

    最近安装了Ubuntu 13.04 64位版,发现有线连接经常会掉线,通常在连接上一段时间(或长或短)就无法上网,ping不通,但是ifconfig显示一切正常,重启NetworkManager也不行 ...

  7. [转]GFS架构分析

    Google文件系统(Google File System,GFS)是构建在廉价的服务器之上的大型分布式系统.它将服务器故障视为正常现象,通过软件的方式自动容错,在保证系统可靠性和可用性的同时,大大减 ...

  8. c++ remove_if

    #include <algorithm> 函数remove_if()移除序列[start, end)中所有应用于谓词p返回true的元素. 此函数返回一个指向被修剪的序列的最后一个元素迭代 ...

  9. 第一次使用Mac

    Mac禁用掉默认输入法 搜狗输入法已经包含中文.英文输入法了,其余输入法可以删除掉.按ctrol键的时候本来应该是搜狗输入法中英文切换,结果却是搜狗输入法和ABC输入法之间互相切换. 打开键盘偏好设置 ...

  10. Intel Galileo驱动单总线设备(DHT11\DHT22)(转)

    Intel Galileo一代的IO翻转速度不够,无法直接驱动单总线设备,二代听说改进了,但没有库,于是国外开发者想出了另一种法子,转过来给大家学习下.如果后面有时间,再来翻译.原文地址:http:/ ...