博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Unity3D之空间转换学习笔记(三):3D数学
阅读量:7049 次
发布时间:2019-06-28

本文共 2986 字,大约阅读时间需要 9 分钟。

3D数学基础

向量

向量可以看做具有方向和大小的一条线段。

比如:我们如果用点A减去点B,则可以得到一个向量,该向量的方向为点B面向点A的方向,而大小为两点的距离。这个方法在游戏开发中经常用到,比如我们要让物体B面向物体A,一般都是使用物体B的位置减去物体A的位置,得到的向量取模。

点积

向量的点积表示一个向量在另一个向量上的投影,如下:

而相互垂直的两个向量点积为0:

我们可以使用这个特性来判断两个向量是否垂直。

Unity提供的计算点积的方法如下:

public static float Dot(Vector3 lhs, Vector3 rhs);

叉积

向量的叉积可以得到垂直于两个向量的第3个向量,如下:

而得到的向量的方向是根据我们使用的是左手坐标系还是右手坐标系来决定的。

Unity提供的计算叉积的方法如下:

public static Vector3 Cross(Vector3 lhs, Vector3 rhs);

3D数学在Unity3D中的应用

Vector3取模

  1. Vector.normalized:返回当前向量的模,向量本身的值不变;
  2. 静态方法Vector.Normalize(Vector3):返回参数向量的模,参数本身的值不变;
  3. Vector.Normalize:没有返回值,向量本身编程自己的模;

Demo06

下面我们的这个例子是制作一个指北针,我们需要先制作一个小星球和一个在这个小星球上走动的小人,然后在制作一个指北针,该指北针始终指向小星球的北极。

小星球制作

小星球的制作我使用了一款插件:Maoots(点击下载),下面我们一步一步来实现小星球和在这个星球上漫步的小人。

1.首先导入Maoots插件;

2.为场景添加一个线性光源;

3.添加一个空物体Man,然后找到MagicBoots\FBX\penelopeFBX预制件,将其作为该空物体的子项添加(注意一定要使用插件提供的模型,因为插件的代码中有模型动画控制的代码,如果使用自己的模型运行时会因为动画问题报错导致无法正常运行);

4.为Man添加CapsuleCollider和Rigidbody并调整一个碰撞体的位置(参数请设置和截图一致,如下:

5.为Main Camera添加MagicBoots\Scripts\MagicCamera并将Man下的penelopeFBX设置为Target Character,并设定参数如下:

6.添加一个名为“Level”的Layer;

7.添加一个球体,这个球体就是我们的小星球了,设置其图层为“Level”,并为其添加一个碰撞体(自带的就行),调整一下Man和小星球的位置,如下:

8.为Man添加MagicBoots\Scripts\MagicBoots脚本,并进行如下的设置:

9.好了,现在可以运行一下看看了,不出意外的话我们的角色就可以在小星球上奔跑了;

10.在小星球的顶部添加一个小旗杆表示为北极,同时在人物头顶添加一个小箭头表示指北针,我们的指北针会始终指向小旗杆,再添加天空盒子和地面贴图美化一下场景就可以了。

注意:由于我是使用的Unity5,在持续移动人物时会出现倾斜的问题,该问题在Unity4上是没有的。

指北针制作

主要使用到叉积的运算,我们添加下面的代码到摄像机即可:

1 using UnityEngine; 2 using System.Collections; 3  4 public class Demo06Script : MonoBehaviour 5 { 6     ///  7     /// 小人. 8     ///  9     public Transform player;10 11     /// 12     /// 星球.13     /// 14     public Transform planet;15 16     /// 17     /// 每秒旋转速度.18     /// 19     public float rotateSpeed = 45;20 21     //对应的上方向22     private Vector3 playerUp;23     private Vector3 planetUp;24 25     //指北针26     private Transform compass;27 28     void Awake()29     {30         playerUp = player.up;31         planetUp = planet.up;32 33         compass = GameObject.Find("Man/compass").transform;34     }35     36     void Update()37     {38         playerUp = player.up;39         planetUp = planet.up;40 41         //求星球和小人上方向向量的叉积, 得到了一个平面42         Vector3 crossValue = Vector3.Cross(planetUp, playerUp).normalized;43 44         //求小人和上方获得的叉积的叉积, 这条线段指向北极45         Vector3 northValue = Vector3.Cross(playerUp, crossValue).normalized;46 47         //绘制线段48         Debug.DrawLine(player.position, player.position + player.up * 100, Color.black);49         Debug.DrawLine(player.position, player.position + planet.up * 100, Color.green);50         Debug.DrawLine(player.position, player.position + crossValue * 100, Color.blue);51         Debug.DrawLine(player.position, player.position + northValue * 100, Color.red);52 53         //旋转指北针54         Quaternion target = Quaternion.LookRotation(northValue, playerUp);55         //每帧旋转一定角度56         compass.transform.rotation = Quaternion.RotateTowards(compass.transform.rotation, target, rotateSpeed * Time.deltaTime);57     }58 }

运行即可查看效果。

工程文件下载

转载地址:http://sfdol.baihongyu.com/

你可能感兴趣的文章
小程序组件封装
查看>>
Flutter教程-自定义无限滚动轮播器infinity_slider
查看>>
Glide 使用Transformation 时 placeholder、error 无效解决方法
查看>>
StudyFlutter——我的第一个APP
查看>>
基于three.js的3D粒子动效实现
查看>>
swift中 Selector的使用
查看>>
自用ES6笔记
查看>>
Spring源码解析-applicationContext.xml加载和bean的注册
查看>>
没有产生强烈“化学反应”的物联网产业,缺的究竟是什么?
查看>>
vue[源码]之数组处理与拦截变异
查看>>
实现promise.all方法
查看>>
前后端分离与Node和NPM的那些事
查看>>
移动端响应式
查看>>
日本公司争相打造遥控机器人抗核辐射
查看>>
AS插件利器,实现依赖库自动补全,支持变量提取和JetPack
查看>>
iOS面试题05-数据结构算法篇
查看>>
微信小程序 跳坑
查看>>
五个你可能不了解的killall选项
查看>>
编程小技巧
查看>>
微服务间的方法调用和应用内方法调用有啥区别
查看>>