Unity3D之空间转换学习笔记(三):3D数学
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取模
- Vector.normalized:返回当前向量的模,向量本身的值不变;
- 静态方法Vector.Normalize(Vector3):返回参数向量的模,参数本身的值不变;
- 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上是没有的。
指北针制作
主要使用到叉积的运算,我们添加下面的代码到摄像机即可:
using UnityEngine;
using System.Collections; public class Demo06Script : MonoBehaviour
{
/// <summary>
/// 小人.
/// </summary>
public Transform player; /// <summary>
/// 星球.
/// </summary>
public Transform planet; /// <summary>
/// 每秒旋转速度.
/// </summary>
public float rotateSpeed = ; //对应的上方向
private Vector3 playerUp;
private Vector3 planetUp; //指北针
private Transform compass; void Awake()
{
playerUp = player.up;
planetUp = planet.up; compass = GameObject.Find("Man/compass").transform;
} void Update()
{
playerUp = player.up;
planetUp = planet.up; //求星球和小人上方向向量的叉积, 得到了一个平面
Vector3 crossValue = Vector3.Cross(planetUp, playerUp).normalized; //求小人和上方获得的叉积的叉积, 这条线段指向北极
Vector3 northValue = Vector3.Cross(playerUp, crossValue).normalized; //绘制线段
Debug.DrawLine(player.position, player.position + player.up * , Color.black);
Debug.DrawLine(player.position, player.position + planet.up * , Color.green);
Debug.DrawLine(player.position, player.position + crossValue * , Color.blue);
Debug.DrawLine(player.position, player.position + northValue * , Color.red); //旋转指北针
Quaternion target = Quaternion.LookRotation(northValue, playerUp);
//每帧旋转一定角度
compass.transform.rotation = Quaternion.RotateTowards(compass.transform.rotation, target, rotateSpeed * Time.deltaTime);
}
}
运行即可查看效果。
工程文件下载
http://pan.baidu.com/s/1sjQJ5j3
Unity3D之空间转换学习笔记(三):3D数学的更多相关文章
- Unity3D之空间转换学习笔记(一):场景物体变换
该系列笔记基于Unity3D 5.x的版本学习,部分API使用和4.x不一致. 目前在Unity3D中,除了新的UGUI部分控件外,所有的物体(GameObject)都必带有Transform组件,而 ...
- Unity3D之空间转换学习笔记(二):基础数学
这期笔记我们专注Unity提供的各种数学相关的类来学习. 时间Time API文档地址:http://docs.unity3d.com/ScriptReference/Time.html 时间加/减速 ...
- [Firefly引擎][学习笔记三][已完结]所需模块封装
原地址:http://www.9miao.com/question-15-54671.html 学习笔记一传送门学习笔记二传送门 学习笔记三导读: 笔记三主要就是各个模块的封装了,这里贴 ...
- Java IO学习笔记三
Java IO学习笔记三 在整个IO包中,实际上就是分为字节流和字符流,但是除了这两个流之外,还存在了一组字节流-字符流的转换类. OutputStreamWriter:是Writer的子类,将输出的 ...
- 学习笔记(三)--->《Java 8编程官方参考教程(第9版).pdf》:第十章到十二章学习笔记
回到顶部 注:本文声明事项. 本博文整理者:刘军 本博文出自于: <Java8 编程官方参考教程>一书 声明:1:转载请标注出处.本文不得作为商业活动.若有违本之,则本人不负法律责任.违法 ...
- muduo网络库学习笔记(三)TimerQueue定时器队列
目录 muduo网络库学习笔记(三)TimerQueue定时器队列 Linux中的时间函数 timerfd简单使用介绍 timerfd示例 muduo中对timerfd的封装 TimerQueue的结 ...
- angular学习笔记(三十一)-$location(1)
本篇介绍angular中的$location服务的基本用法,下一篇介绍它的复杂的用法. $location服务的主要作用是用于获取当前url以及改变当前的url,并且存入历史记录. 一. 获取url的 ...
- kvm虚拟化学习笔记(三)之windows kvm虚拟机安装
KVM虚拟化学习笔记系列文章列表----------------------------------------kvm虚拟化学习笔记(一)之kvm虚拟化环境安装http://koumm.blog.51 ...
- MYSQL学习笔记三:日期和时间函数
MYSQL学习笔记三:日期和时间函数 1. 获取当前日期的函数和获取当前时间的函数 /*获取当前日期的函数和获取当前时间的函数.将日期以'YYYY-MM-DD'或者'YYYYMMDD'格式返回 */ ...
随机推荐
- bzoj2432
被虐的体无完肤, 直接给题解地址吧:http://vfleaking.blog.163.com/blog/static/174807634201341721051604/ ; ..,..] of in ...
- UVa 253 Cube paiting
题意:输入两个骰子,判断是否等价 因为每一个面可以作顶面,共6*4种情况,枚举就可以了 #include<iostream> #include<cstdio> #include ...
- HDU 1710 Binary Tree Traversals
题意:给出一颗二叉树的前序遍历和中序遍历,输出其后续遍历 首先知道中序遍历是左子树根右子树递归遍历的,所以只要找到根节点,就能够拆分出左右子树 前序遍历是按照根左子树右子树递归遍历的,那么可以找出这颗 ...
- svn 提交失败 更新失败 提示 已经锁定
出现问题的原因:在上传的时候,由于网络掉线,导致svn提交到一半就没有反应了,这个时候我点击了取消,再之后无论是进行 更新还是提交,都提示 已经锁定 解决方法:在项目的空白地方,点击SVN 清理 ...
- HDU 4638 Group ★(树状数组)
题意 询问一段区间里的数能组成多少段连续的数. 思路 先考虑从左往右一个数一个数添加,考虑当前添加了i - 1个数的答案是x,那么可以看出添加完i个数后的答案是根据a[i]-1和a[i]+1是否已经添 ...
- UVA 658 It's not a Bug, it's a Feature! (最短路,经典)
题意:有n个bug,有m个补丁,每个补丁有一定的要求(比如某个bug必须存在,某个必须不存在,某些无所谓等等),打完出来后bug还可能变多了呢.但是打补丁是需要时间的,每个补丁耗时不同,那么问题来了: ...
- CSS HACK区别IE6、IE7、IE8、Firefox兼容性
相信不少人,都特别清楚CSS HACK,而其中也是区别IE6.IE7.IE8.Firefox兼容性问题用的,CSS hack由于不同的浏览器,对CSS的解析认识不一样,因此会导致生成的页面效果不一样. ...
- C# chart,有关如何在鼠标移动到Series上时显示节点及数据 (有待继续更新)
一.效果与思路 效果: 解决方案1 用chart的mousemove时间,实时跟踪鼠标最近的X轴的位置,然后把cursorX设置到那个位置上,让用户知道我是选的那一个X的值,同时用tooltip显示该 ...
- BaseAdapter中重写getview的心得以及发现convertView回收的机制
以前一直在用BaseAdapter,对于其中的getview方法的重写一直不太清楚.今天终于得以有空来探究它的详细机制. 下面先讲讲我遇到的几个问题: 一.View getview(int posit ...
- duilib中控件拖拽功能的实现方法(附源码)
转载请说明原出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/41144283 duilib库中原本没有显示的对控件增加拖拽的功能,而实际 ...