Unity 3D脚本编程与游戏开发(2.5)

这篇具有很好参考价值的文章主要介绍了Unity 3D脚本编程与游戏开发(2.5)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

4.3.4 向量的点积

        两个向量的点积是⼀个标量,其数值为两者⻓度相乘,再乘以两者夹⾓的余弦:
a·b=|a|·|b|cosθ⽤坐标表⽰,公式为
(x1,y1,z1)·(x2,y2,z2)=x1x2+y1y2+z1z2
        注意到,两个向量的点积是⼀个数(标量),只有⼤⼩,没有⽅向。⽽且点乘满⾜交换律,如向量a·b=b·a。数学中的所有运算规则都有着深刻的内涵。向量加减法的定义是⽐较直观的,那么点乘为什么这么定义,⼜有什么⽤呢?⾸先⽐较明显的⼀点是,由于夹⾓的余弦具有正负值,因此通过两个向量的点积正负,可以快速判断两个向量的夹⾓。
若点积等于0,则两者垂直;
若点积⼤于0,则两者夹⾓⼩于90°;
若点积⼩于0,则两者夹⾓⼤于90°。

        不⽤考虑夹⾓⼤于180°的情况,读者可以想想为什么(提⽰:点乘满⾜交换律)。
点积还有⼀个重要含义——投影距离。考虑⼀个问题:如图4-10所⽰,⻋辆正在沿向量b的⽅向⾏进,前⾯有⼈拉⻋,但拉⻋的⼒为向量a,向量a与向量b存在30°夹⾓。很明显,拉⼒a并没有全部转化为对⻋的牵引⼒,垂直于⻋辆前进⽅向的⼒被抵消了,真正对⻋辆⾏进有贡献的⼒是a',那么a'如何计算呢?直接⽤点乘即可。但是,如果直接⽤a点乘b,结果会受b的⻓度影响。为了去除b⻓度的影响,只取b的⽅向,将b标准化即可。

Unity 3D脚本编程与游戏开发(2.5),Unity实战开发指南,机器学习,算法,人工智能,unity,Unity游戏开发,3D游戏开发,Unity 3D脚本编程

上述算法⽤如下代码表达:
Vector3 a=new Vector3(2,1,0);
Vector3 b=new Vector3(3,0,0);
Vector3 dir_b=b.nomalized; //dir_b是标准化的向量b
float pa=Vector3.dot(a,dir_b); //pa即是向量a在向量b⽅向的投影⻓度

4.3.5 向量的叉积

        为结合实际,本⼩节只讨论三维向量的叉积。两个向量的叉积是⼀个新的向量,新向量垂直于原来两个向量所构成的平⾯,如图4-11所⽰。叉积的⽅向⽤左⼿定则判断(⽤左⼿还是右⼿与坐标系有关)。

Unity 3D脚本编程与游戏开发(2.5),Unity实战开发指南,机器学习,算法,人工智能,unity,Unity游戏开发,3D游戏开发,Unity 3D脚本编程

        ⼿掌沿第1个向量放平,向第2个向量握拳,拇指的指向即叉积⽅向。当向量a与向量b共线(同向或反向)时,叉积为0向量。可以看出,两个向量叉乘的顺序不同,⼿掌转向会不同,结果⽅向相反,因此叉乘不满⾜交换律。在游戏开发中也经常会使⽤叉积,因为叉积有着⼀个重要的⽤途——求法线,如图4-12所⽰。

Unity 3D脚本编程与游戏开发(2.5),Unity实战开发指南,机器学习,算法,人工智能,unity,Unity游戏开发,3D游戏开发,Unity 3D脚本编程

        简单来说,法线就是垂直于平⾯的线,⽤法线可以⽅便地指代平⾯的朝向。在游戏开发中,平⾯要区分正反两⾯,因此法线⽤向量表⽰,法线⽅向就是平⾯的⽅向。⼀般法线⻓度固定为1以便计算。有了叉积,很多时候可以⽅便地获取法线。例如,玩家站在地形的⼀个平⾯上,想要获取平⾯法线,需要先⽤其他⽅法获得平⾯上的任意两个向量,只要这两个向量夹⾓不为0°或180°,取它们的叉积就可以获得法线向量(也可以将叉积结果标准化)。其对应的脚本写法如下。

Vector3 a=new Vector3(2,1,1); //a和b是某个平⾯上的任意两个向量
Vector3 b=new Vector3(3,0,2);
Vector3 n=Vector3.Cross(a,b); //n是该平⾯的法线
n=n.nor m alized; //将n标准化
4.3.6 Vector3结构体

        提⽰:C#中有类(class)和结构体(struct)区别,虽然它们都具有字段、属性和⽅法,但是前者是引⽤类型,后者是值类型,在使⽤时区别不⼩。Vector2和Vector3属于结构体,详情可参考C#语⾔与结构体相关的语法。在Unity中,与向量有关的结构体有Vector2、Vector3,分别⽤来表⽰⼆维向量和三维向量,其中Vector3最为常⽤。下⾯列举Vector3的属性(表4-1)、⽅法(表4-2)和运算符(表4-3)。

Unity 3D脚本编程与游戏开发(2.5),Unity实战开发指南,机器学习,算法,人工智能,unity,Unity游戏开发,3D游戏开发,Unity 3D脚本编程

Unity 3D脚本编程与游戏开发(2.5),Unity实战开发指南,机器学习,算法,人工智能,unity,Unity游戏开发,3D游戏开发,Unity 3D脚本编程

Unity 3D脚本编程与游戏开发(2.5),Unity实战开发指南,机器学习,算法,人工智能,unity,Unity游戏开发,3D游戏开发,Unity 3D脚本编程

4.3.7 位置与向量的关联

        在数学中,点的坐标与向量是不同的概念,如图4-13所⽰。

Unity 3D脚本编程与游戏开发(2.5),Unity实战开发指南,机器学习,算法,人工智能,unity,Unity游戏开发,3D游戏开发,Unity 3D脚本编程

        在数学符号系统中,点⽤⼤写字⺟表⽰,向量会以两个点的名称再加顶上箭头表⽰,或者⽤⼩写字⺟加顶上箭头表⽰,印刷品会以⿊斜体⼩写字⺟表⽰。总之在表⽰向量时,有特定的符号和记法,以使读者能够⽐较清楚地区分向量和点。⽽在程序中,向量和坐标位置的记法就⽐较模糊,这可能会引起混淆。
        向量和坐标可以混合计算,这也代表它们本质上是有联系的。A点的坐标既是⼀个位置坐标,⼜是向量 的值(O是坐标原点,坐标为(0,0),所以⽤A点的坐标减去O点的坐标就得到了向量 )。换句话说,任何⼀个点的坐标都可以看成从原点到该点的向量。由于向量是⾃由向量,它的起点可以任意平移,因此它更多地表⽰⼀个相对关系。
        在脚本中,向量和位置都是以Vector3表⽰的,那如何区分坐标和向量呢?实际上,仅从字⾯上⽆法区分,关键是代码的意图决定了Vector3的意义。

//这是当前物体的A坐标
Vector3 p1=transform.position;
//这是物体B的坐标
Vector3 p2=gameObjectB.transform.position;
//这是从当前物体A到B的向量
Vector3 diff=p2-p1;
//获得了⼀个新的坐标C,位于⽐B远离当前物体A⼀倍的位置
Vector3 p3=p2+diff;
//从物体C的位置出发,发⽣从A到B的位移,得到新的坐标
Vector3 p3=gameObjectC.transform.position+diff;
//调整向量的⻓度为⼀半
Vector3 diffHalf=diff*0.5f;

以上代码中,坐标和向量不仅都⽤Vector3表⽰,⽽且它们之间还会发⽣运算,常⽤的情况如表4-4所⽰。
表4-4 坐标与向量的关系
Unity 3D脚本编程与游戏开发(2.5),Unity实战开发指南,机器学习,算法,人工智能,unity,Unity游戏开发,3D游戏开发,Unity 3D脚本编程

向量的加减法看似⾮常简单,但是在游戏开发中⾮常常⽤,例如以下问题。
问题1:在玩家⾓⾊头顶1⽶处添加粒⼦。
问题2:在玩家⾓⾊前⽅1⽶处⽣成炮塔。
问题3:敌⼈瞄准玩家前⽅0.5⽶处(射击的提前量)。
问题4:敌⼈⼀边朝玩家移动,⼀边躲开危险区域。
前3个问题⽤“坐标+向量”的⽅法即可解决。问题4代表了⼀类游戏AI问题,了解了向量的基本运算就不难解决了。

4.3.8 向量坐标系的转换

        在Unity中,可以使⽤transform.TransformPoint()⽅法将局部坐标转换为世界坐标,也可以使⽤transform.InverseTransformPoint()⽅法将世界坐标转换为局部坐标transform.TransformDirection()和transform.InverseTransformDirection()⽅法则⽤于向量的全局坐标系和局部坐标系之间的转换。两者的差异在于TransformPoint()是转换坐标专⽤的,TransformDirection()是转换向量专⽤的。以下通过⽰例讲解如何通过全局坐标系和局部坐标系改变物体的运动⽅向。01 在Unity场景中,新建⼀个⽴⽅体,并将旋转的Y值改为300,也就是沿y轴旋转300°。02 新建脚本CoordinateLocal.cs,其内容如下。

using UnityEngine;
public class CoordinateLocal:MonoBehaviour{
void Upd ate(){
transform.Translate(Vector3.forward*Time.deltaTime);
}
}

将该脚本挂载到⽴⽅体上,运⾏游戏,会看到⽴⽅体沿着⾃⾝的z轴⽅向慢慢移动。
03 新建脚本CoorindateWorld.cs,其内容如下。
 

using UnityEngine;
public class CoordinateWorld:MonoBehaviour{
void Upd ate(){
Vector3
v=transform.InverseTransformDirection(Vector3.forward);
transform.Translate(v*Time.deltaTime);
}
}

        将新建的脚本挂载到⽴⽅体上,并取消勾选原来的脚本CoordinateLocal.cs,因此就只有新的脚本发挥作⽤了。可以通过取消勾选或勾选的⽅式在两个脚本之间切换。这时运⾏游戏,就会发现⽴⽅体沿着世界坐标系的z轴⽅向移动了。下⾯解释⼀下以上结果。
        transform.Translate()函数默认是以局部坐标系为基准的,因此在第1个脚本中,虽然Translate()函数参数为Vector3.forward,但是依然会以局部坐标系的前⽅为准。Vector3.forward的值是常数(0,0,1),它在不同的坐标系代表不同的“前⽅”。
        第2个脚本稍微复杂⼀点,由于Translate()函数默认以局部坐标系为准,因此就要把世界坐标系的“前⽅”转化为局部坐标系的向量v。这⾥认为Vector3.forward是世界坐标系的“前⽅”,⽤
InverseTransformDirection()⽅法将向量(0,0,1)以局部坐标系表⽰(也就是向量v),然后以v作为参数执⾏Translate()⽅法,就会使⽴⽅体朝世界坐标系的前⽅移动了。

4.4 矩阵简介

        与向量⼀样,矩阵也是3D数学的基础。矩阵就像⼀个表格,具有若⼲⾏和列。要正确进⾏物体的位移、旋转和缩放变换,就必须要⽤到矩阵。3D游戏中的向量⼀般只有3个维度,但矩阵要使⽤4×4 矩阵,主要原因是要⽤矩阵实现平移,3×3矩阵是不够的。4×4 矩阵是能够正常进⾏所有常⽤变换的最⼩矩阵。

4.4.1 常⽤矩阵介绍

        介绍3D游戏中矩阵算法的问题远超出了本书的介绍范围,以下仅展⽰单独的平移、旋转和缩放矩阵,让读者对矩阵有⼀个直观的认识,消除陌⽣感。

Unity 3D脚本编程与游戏开发(2.5),Unity实战开发指南,机器学习,算法,人工智能,unity,Unity游戏开发,3D游戏开发,Unity 3D脚本编程

2. 旋转矩阵
Unity 3D脚本编程与游戏开发(2.5),Unity实战开发指南,机器学习,算法,人工智能,unity,Unity游戏开发,3D游戏开发,Unity 3D脚本编程

        缩放矩阵可以对向量的各个分量进⾏缩放,向量v与S(q)相乘后,v的3个分量分别缩放qx、qy、qz倍。矩阵变换最强⼤的地⽅在于,它可以通过矩阵乘法进⾏组合,组合以后通过⼀个矩阵就可以表⽰⼀组连续的变换操作,假设有3个矩阵S、R、T分别进⾏缩放、旋转、位移操作,三者相乘得到了M矩阵。那么vSRT=vM⽤向量v依次乘以S、R、T矩阵以进⾏变换,得到的结果和向量v直接乘以M矩阵得到的结果是⼀致的。
        虽然矩阵的作⽤很强⼤,但是由于其使⽤有⼀定门槛,因此Unity封装了⼀些矩阵和变换函数,⽤户可以直接使⽤。旋转相关的问题还可以⽤四元数(Quaternion)来解决,进⼀步降低了直接操作矩阵的必要性。

4.4.2 ⻬次坐标

        在3D数学中,⻬次坐标就是将原本的三维向量(x, y, z)⽤四维向量(x, y, z, w)来表⽰。引⼊⻬次坐标有如下⽬的。更好地区分坐标点和向量。在三维空间中,(x, y, z)既可以表⽰⼀个点,也可以表⽰⼀个向量。如果采⽤⻬次坐标,则可以使⽤(x, y, z,1)代表坐标点,⽽⽤(x, y, z, 0)代表向量。在进⾏⼀些错误操作时,例如将两个坐标点相加,会⽴即得到⼀个错误的结果,避免引起混乱。
        统⼀⽤矩阵乘法表⽰平移、旋转和缩放变换。3×3的矩阵可以⽤于表⽰旋转和缩放矩阵,但是⽆法表⽰平移。⽤4×4的矩阵就可以表⽰所有的常⽤变换,包括平移、旋转、缩放、斜切,以及它们的组合。⻬次坐标是计算机图形学中⼀个⾮常重要的概念,但在游戏逻辑开发中很少考虑⻬次坐标的问题,只在处理渲染问题或编写着⾊器时会⽤到。

4.5 四元数

        在场景窗⼝中旋转物体是⼀项基本操作。可以⽤旋转⼯具改变物体⾓度,也可以在Inspector窗⼝中改变物体的X、Y、Z值(欧拉⾓)来改变物体⾓度,如图4-14所⽰。

Unity 3D脚本编程与游戏开发(2.5),Unity实战开发指南,机器学习,算法,人工智能,unity,Unity游戏开发,3D游戏开发,Unity 3D脚本编程

        ⽤欧拉⾓表⽰⾓度和旋转,简单⼜直观。但⼀般⼈想不到,物体在三维空间中的旋转并不是⼀个简单问题,⽤3个⾓度表⽰是远远不够的。

4.5.1 万向节锁定

        要说明三维物体旋转的复杂性,从“万向节锁定”这⼀问题⼊⼿最有说服⼒。虽然可以调整欧拉⾓到任意⾓度,但欧拉⾓的3个轴并不是独⽴的,x轴、y轴和z轴之间存在嵌套结构,如图4-15所⽰,这种嵌套结构被称为“万向节”,意思是可以转到任意⾓度的关节。

Unity 3D脚本编程与游戏开发(2.5),Unity实战开发指南,机器学习,算法,人工智能,unity,Unity游戏开发,3D游戏开发,Unity 3D脚本编程

        当中层轴旋转时,会带动内层的轴跟着旋转。通常三维软件的欧拉⾓,从外层到内层是按照y轴→x轴→z轴的顺序,也就是说沿x轴的旋转会影响z轴。
        万向节锁定的详细介绍在⽹上资料很多,感兴趣的读者可以多看⼀些资料深⼊理解。下⾯⽤Unity演⽰怎样让万向节锁定。
01 在场景中新建⼀个⽴⽅体。
02 ⽤⿏标在Inspector窗⼝中朝向的X、Y、Z这3个字⺟上拖曳,不要在场景中⽤⿏标直接旋转物体,这样可以看到3个轴分别是如何旋转的。
03 将绕x轴的旋转改为90°,y轴和z轴的旋转改为0。
04 ⽤⿏标在旋转的Y和Z字⺟上拖曳,修改绕y轴和z轴的旋转。这时会发现,绕y轴和z轴的旋转⽅向变成⼀样了,缺少了⼀个⾃由度,如图4-16所⽰。

Unity 3D脚本编程与游戏开发(2.5),Unity实战开发指南,机器学习,算法,人工智能,unity,Unity游戏开发,3D游戏开发,Unity 3D脚本编程

⼩提⽰
        Unity引擎内部并没有万向节锁定问题值得说明的是,Unity内部是⽤四元数表⽰物体的旋转,这⾥并不会真的遇到锁定问题,只是在编辑器界⾯上模拟了万向节锁定的效果。如果⽤旋转⼯具在场景⾥直接旋转物体,就跳过了编辑窗⼝的限制,物体仍然可以⾃由旋转。
        按照上述步骤操作,会顺利进⼊“万向节锁定”的状态。⼀旦进⼊此状态,物体旋转就会受限制。如果游戏系统是基于欧拉⾓设计的,那么在主⾓会俯仰运动的游戏,特别是空战游戏中,万向节锁定问题会显得⾮常严重,如⻜机在俯冲时的操纵就会变得很奇怪,⽽且在其他类型游戏中也会带来各种各样的问题。讲到这⾥,读者可能还没有完全理解3D旋转的奥妙,但它具有的复杂性已经⽏庸置疑了。幸运的是,爱尔兰数学家、物理学家哈密尔顿在1843年提出的“四元数”能够让我们跨越欧拉⾓,彻底解决旋转难题。文章来源地址https://www.toymoban.com/news/detail-776741.html

到了这里,关于Unity 3D脚本编程与游戏开发(2.5)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • Unity 3D脚本编程与游戏开发(3.5)

    Unity 3D脚本编程与游戏开发(3.5)

    6.2.8 总结和拓展         本节利⽤Unity官⽅素材,以有限的篇幅解释了动画状态机的原理,以及动画制作中最基本但最重要的步骤。总的来看,⽬前的动画只做了4种状态——站⽴、⾛、跑和跳跃,还缺少下蹲、下蹲移动和落地缓冲等动作。好在这些动作只是对现有动作的

    2024年04月10日
    浏览(15)
  • Unity 3D脚本编程与游戏开发(3.4)

    Unity 3D脚本编程与游戏开发(3.4)

    6.2.3 动画的制作步骤         接下来为⾓⾊配上动画,整体思路分以下3个部分。⼀是准备好单个的动画素材,包含站⽴、跑和跳等动作。也就是说,把原始素材中的图⽚串联起来,形成⼏个单独的动画。⼆是⽤Animator把这些单独的动作有机地组合起来,形成⼀张状态转移

    2024年04月26日
    浏览(12)
  • Unity 3D脚本编程与游戏开发(2.6)

    Unity 3D脚本编程与游戏开发(2.6)

    4.5.2 四元数的概念         四元数包含⼀个标量分量和⼀个三维向量分量,四元数Q可以记作Q=[w,(x,y,z)]         在3D数学中使⽤单位四元数表⽰旋转,下⾯给出四元数的公式定义。对于三维空间中旋转轴为n,旋转⾓度为a的旋转,如果⽤四元数表⽰,则4个分量分别为

    2024年02月03日
    浏览(13)
  • Unity 3D脚本编程与游戏开发【4.1】

    Unity 3D脚本编程与游戏开发【4.1】

    7.2.5 后期处理举例 Post Processing(后期处理)并不属于特效,但现代的特效表现离不开后期处理的⽀持。本⼩节以眩光(Bloom)为例,展⽰⼀种明亮的激光的制作⽅法,其效果如图7-13所⽰。 1. 安装后期处理扩展包         较新的Unity版本(如2018.4版本)已经内置了新版的后

    2024年04月26日
    浏览(17)
  • Unity 3D脚本编程与游戏开发【4.2】

    Unity 3D脚本编程与游戏开发【4.2】

    8.2.3 ⾳频管理器         在实际游戏开发中,⾳效既是⼀个相对独⽴的部分,⼜与其他游戏逻辑密切关联。也就是说,与⾳效相关的代码会插⼊很多细节代码中。         ⽽且在⾳效⾮常丰富的情况下,如果每⼀个游戏模块都单独播放⾳效,那么可能会带来⼀些问题。

    2024年04月24日
    浏览(10)
  • Unity 3D脚本编程与游戏开发【3.8】

    Unity 3D脚本编程与游戏开发【3.8】

    6.4.5 动画层         图6-42显⽰了动画层设置窗⼝。在动画状态机⾥可以添加很多层,层之间可以是覆盖关系也可以是叠加关系,当然也可以随时屏蔽⼀些层、启⽤另⼀些层。 每⼀个动画层可以有单独的设置,其选项解释如下。 ①Weight(权重),本层对总体动画效果的影

    2024年04月16日
    浏览(13)
  • Unity 3D脚本编程与游戏开发(2.2)

    Unity 3D脚本编程与游戏开发(2.2)

    3.2.7 修改物理材质         每个物体都有着不同的摩擦⼒。光滑的冰⾯摩擦⼒很⼩,⽽地毯表⾯的摩擦⼒则很⼤。另外每种材料也有着不同的弹性,橡⽪表⾯的弹性⼤,硬质地⾯的弹性⼩。在Unity中这些现象都符合⽇常的理念。         虽然从原理上讲,物体的摩擦⼒

    2024年02月04日
    浏览(12)
  • Unity 3D游戏开发+脚本编程完整指南:Unity脚本概览-控制物体的运动

    Unity 3D游戏开发+脚本编程完整指南:Unity脚本概览-控制物体的运动

    教程相关资源 Unity 3D游戏开发+脚本编程完整指南(工程文件+PPT).zip Unity 脚本概览 脚本编写并不困难,但是如果直接从细节开始讲起,会让 读者难以看到脚本编程的全貌。因此本章不急于阐述脚本编写 的细节,只介绍简单的修改物体位置、处理用户输入和检测碰 撞的方法

    2024年02月21日
    浏览(58)
  • Unity 3D游戏开发+脚本编程完整指南:制作第一个游戏:3D滚球跑酷

    Unity 3D游戏开发+脚本编程完整指南:制作第一个游戏:3D滚球跑酷

    教程相关资源 Unity 3D游戏开发+脚本编程完整指南(工程文件+PPT).zip 本节利用前面的知识来实现第一个较为完整的小游戏,如 图 1-21 所示。 图1-21 3D滚球跑酷游戏完成效果 1. 功能点分析 游戏中的小球会以恒定速度向前移动,而玩家控制着小球 左右移动来躲避跑道中的黄色障

    2024年02月21日
    浏览(19)
  • 游戏引擎支持脚本编程有啥好处

    游戏引擎支持脚本编程有啥好处

    很多游戏引擎都支持脚本编程。Unity、Unreal Engine、CryEngine等大型游戏引擎都支持使用脚本编写游戏逻辑和功能。脚本编程通常使用C#、Lua或Python等编程语言,并且可以与游戏引擎的API进行交互来控制游戏对象、设置变量、执行行为等。使用脚本编程,游戏开发者可以更加灵活

    2024年02月03日
    浏览(16)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包