在蛮牛上看的总结,讲的很细致。转过来自己看,也分享给大家。
原文链接:Unity知识总结系列(一):物体移动方法
http://www.manew.com/thread-114623-1-1.html
(出处: -【游戏蛮牛】-ar增强现实,虚拟现实,unity3d,unity3d教程下载首选u3d,unity3d官网)
在
中,有多种方式可以改变物体的坐标,实现移动的目的,其本质是每帧修改物体的position
。
一、Transform类 (两种)
Transform
组件用于描述物体在空间中的状态,它包括 位置
(position)
, 旋转
(rotation)
和 缩放
(scale)
。 其实所有的移动都会导致
position
的改变
1、transform.position += new Vector3 ( 0,0,3 );
这里所说的通过Transform
组件来移动物体,指的是直接操作
Transform
来控制物体的位置
(position)
。
改变方式可以是自定义的三位向量,也可以是transform
的自身方向,也可以是
vector3
的世界坐标方向
局部(自身)坐标,只有坐标轴的正方向没有负方向
Transform.forward
向前
Transform.right
向右
Transform.up
向上
世界坐标
Vector3.forward
向前
Vector3.back
向后
Vector3.left
向左
Vector3.right
向右
Vector3.up
向上
Vector3.down
向下
Vector3.zero
零点
Vector3.one
指向(
1,1,1
)的单位向量
void
Update
(){
//局部坐标 Local
//transform.position += transform.forward * Time.deltaTime;
//transform.position += transform.right * Time.deltaTime;
//transform.position += transform.up * Time.deltaTime;
//世界坐标 Global
//transform.position += new Vector3(0, 0, 2) * Time.deltaTime;
//transform.position += Vector3.forward * Time.deltaTime;
//transform.position += Vector3.back * Time.deltaTime;
//transform.position += Vector3.left * Time.deltaTime;
//transform.position += Vector3.right * Time.deltaTime;
//transform.position += Vector3.up * Time.deltaTime;
//transform.position += Vector3.down * Time.deltaTime;
//transform.position += Vector3.one * Time.deltaTime;
}
2、Transform.Translate ( transform.forward * Time.deltaTime );
该方法可以将物体从当前位置,移动到指定位置,并且可以选择参照的坐标系。
当需要进行坐标系转换时,可以考虑使用该方法以省去转换坐标系的步骤。
void
Update
(){
//在使用transform自身局部坐标时,第二个参数的作用不大
//transform.Translate(transform.forward * Time.deltaTime);
//transform.Translate(transform.forward * Time.deltaTime, Space.Self);
//transform.Translate(transform.forward * Time.deltaTime, Space.World);
//不写第二个参数,默认局部坐标,使用第二个参数设置为世界坐标时使用世界坐标系
//transform.Translate(Vector3.forward * Time.deltaTime);
//transform.Translate(Vector3.forward * Time.deltaTime, Space.Self);
//transform.Translate(Vector3.forward * Time.deltaTime, Space.World);
}
二、Vector3类 (四种)
Vector3
既可以表示三维空间中的一个点,也可以表示一个向量。
这三个方法均为插值方法, Lerp
为线性插值,
Slerp
为球形插值,
MoveTowards
在
Lerp
的基础上增加了限制最大速度功能。
当需要从指定A
点移动到
B
点时
,
可以考虑时候这些方法。
1、Vector3.MoveTowards();匀速移动到目标点
void
Update
(){
//参数1,自身position。 参数2,目标点position,
//参数3,移动速度, 0不动,>0朝向目标移动,
//<0朝向目标点的向量相反方向移动
,
这时,物体只有运动方向,不再有目标点
transform.position =
Vector3
.MoveTowards
(
transform.position,
new
Vector3
(
0, 0, 5
)
, speed *
Time
.deltaTime
)
;
}
2、Vector3.Lerp();线性插值
void
Update
(){
//参数1,自身position。 参数2,目标点position,
//参数3,移动剩余距离的百分比距离 ,赋值范围(0,1)
数值越大运动越快
transform.position =
Vector3
.Lerp
(
transform.position,
new
Vector3
(
0, 0.5f, 20
)
, speed
)
;
}
3、Vector3.Slerp();球形(弧形)插值
void
Update
(){
//参数1,自身position。 参数2,目标点position,
//参数3,移动剩余距离的百分比距离 ,赋值范围(0,1)
数值越大运动越快
transform.position =
Vector3
.Slerp
(
transform.position,
new
Vector3
(
0, 0.5f, 20
)
, speed
)
;
}
注意:因为插值移动需要不止一帧的时间才能到达目标,所以不要把插值移动放到Update中执行,尽量不要设置限制条件。
4、Vector3.SmoothDamp();平滑阻尼
该方法是可以平滑的从A
逐渐移动到
B
点,并且可以控制速度,最常见的用法是相机跟随目标。
public
static
Vector3 SmoothDamp(
Vector3 current, //当前物体位置
Vector3 target, //目标位置
ref Vector3 currentVelocity, //当前速度,这个值由你每次调用这个函数时被修改
//虽然使用ref关键字,不过函数运行时会自动修改
//一般传入参数值为0
float smoothTime, //到达目标的大约时间,较小的值将快速到达目标 ,数值越大走的越慢
float maxSpeed = Mathf.Infinity,//选择允许你限制的最大速度(默认为正无穷)
float deltaTime = Time.deltaTime//自上次调用这个函数的时间(默认为Time.deltaTime) );
例如:
using
UnityEngine;
public
class
CameraTest2
:
MonoBehaviour
{
public
Transform
player;
Vector3
distance;
public
float
speed;
Vector3 ve;
void
Start
(){
distance = transform.position - player.position;
}
void
LateUpdate
(){
transform.position =
Vector3
.SmoothDamp
(
transform.position, player.position + distance,
ref
ve, 0
)
;
}
}
三、Rigidbody类 (三种)
Rigidbody
组件用于模拟物体的物理状态,比如物体受重力影响,物体被碰撞后的击飞等等。
注意:
1、
关于Rigidbody
的调用均应放在
FixedUpdate
方法中,该方法会在每一次执行物理模拟前被调用。
2、使用加速度有两种方式,
(1)
、第一是rigid.velocity += transform.forward * 100;
(2)
、第二是rigid.AddForce(transform.forward * speed, ForceMode.Acceleration);
1、Rigidbody.velocity 物理速度
设置刚体速度可以让物体运动并且忽略静摩擦力,这会让物体快速从静止状态进入运动状态。
using
UnityEngine;
public
class
MoveTest
:
MonoBehaviour
{
Rigidbody
rigid;
void
Start
(){
rigid = GetComponent<
Rigidbody
>
()
;
}
void
FixedUpdate
(){
//加速运动
//rigid.velocity += transform.forward * 100;
//瞬间速度
//if (Input.GetKeyDown(KeyCode.Space))
// rigid.velocity = transform.forward * 100;
}
}
2、Rigidbody.AddForce();添加力
给刚体添加一个方向的力,这种方式适合模拟物体在外力的作用下的运动状态。
using
UnityEngine;
public
class
MoveTest
:
MonoBehaviour
{
Rigidbody
rigid;
public
float
speed;
void
Start
(){
rigid = GetComponent<
Rigidbody
>
()
;
}
void
FixedUpdate
(){
//添加默认类型的力
//rigid.AddForce(transform.forward * speed);
//ForceMode.Acceleration 向刚性物体增加一个连续的加速度,忽略它的质量。
//rigid.AddForce(transform.forward * speed, ForceMode.Acceleration);
//ForceMode.Force 用它的质量,给刚性体增加一个连续的力。
//rigid.AddForce(transform.forward * speed, ForceMode.Force);
//ForceMode.Impulse 用它的质量,给刚体增加一个瞬间的力。
//rigid.AddForce(transform.forward * speed, ForceMode.Impulse);
//ForceMode.VelocityChange 在刚开始的时候增加一个瞬时速度变化,忽略它的质量。
//rigid.AddForce(transform.forward * speed, ForceMode.VelocityChange);
}
}
3、Rigidbody.MovePosition();移动位置
刚体受到物理约束的情况下,移动到指定点。
using
UnityEngine;
public
class
MoveTest
:
MonoBehaviour
{
Rigidbody
rigid;
public
float
speed;
void
Start
(){
rigid = GetComponent<
Rigidbody
>
()
;
}
void FixedUpdate(){
//移动到(0,0,1)的位置
rigid.MovePosition
(
transform.forward
)
;
}
}
四、CharacterController类 (两种)
CharacterController
用于控制第一人称或第三人称角色的运动,使用这种方式可以模拟人的一些行为,比如限制角色爬坡的最大斜度
,
步伐的高度等。
1、CharacterController.SimpleMove();
按m/s
运动,用于模拟简单运动,并且自动应用重力,返回值表示角色当前是否着地。
using
UnityEngine;
public
class
MoveTest
:
MonoBehaviour
{
CharacterController
character;
public float speed;
void
Start
(){
character = GetComponent<
CharacterController
>
()
;
}
void
FixedUpdate
(){
character.SimpleMove
(
transform.forward * speed
)
;
}
}
2、CharacterController.Move();
按帧运动,模拟更复杂的运动,
重力需要通过代码实现,返回值表示角色与周围的碰撞信息。
using
UnityEngine;
public
class
MoveTest
:
MonoBehaviour
{
CharacterController
character;
public
float
speed;
void
Start
(){
character = GetComponent<
CharacterController
>
()
;
}
void
FixedUpdate
(){
character.Move
(
transform.forward * speed
)
;
}
}