Unity 控制物体移动的一些方法

开坑, 回头慢慢补.
移动方法的总结.

1, 直接+=Vector3

transform.position += Vector3.forward * moveSpeed * Time.deltaTime;

简单直接, 向前方, 匀速运动.

说白了, Vector3.forward就是Vector3(0, 0, 1), 是z轴, 即3d游戏世界里的"前".
Vector3.up和down是(0,1,0)和(0,-1,0), 是Y轴, 即"上下".
Vector3.left和right是(-1,0,0)和(1,0,0), 是X轴, 即"左右".
另外还有Vecto3.zero是(0,0,0), Vecto3.one是(1,1,1).

需要注意的是Vector3.forward代表的"前"是世界坐标的"前", 并不是游戏中人物局部坐标的"前".
↓下面这样才是人物的"前":

transform.position += transform.forward * moveSpeed * Time.deltaTime;

那假如我想朝A物体的方向走, 怎么办呢?

//先得到一个从"我"指向"A"的向量
Vector3 direction = A.transform.position - transform.position;
//朝着向量走
transform.position += direction.normalized * moveSpeed * Time.deltaTime;

2, Vector3. MoveTowards( )

transform.position = Vector3.MoveTowards(startPoint.position, stopPoint.position, moveSpeed * Time.deltaTime);

Vector3.MoveTowards(起点, 终点, 速度);
厉害在于, 可以设置起点, 终点.

3, transform. Translate( )

//向世界坐标的"前"方移动
transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime, Space.World);
//或者写成这样//向我的"前"方移动
transform.Translate(new Vector3(0, 0, 1) * moveSpeed * Time.deltaTime);
//还有这样
float h = Input.GetAxis("Horizontal");//X轴控制左右移动
float v = Input.GetAxis("Vertical");//Z轴控制前后移动
transform.Translate(new Vector3(h, 0, v) * moveSpeed * Time.deltaTime);

Input.GetAxis()是一个从-1到1的值, 当你按下WASD或者↑↓←→, 就会从0渐变到1或-1, 感觉有一个起步速度.
用Input.GetAxisRow() , 没有渐变, 只有 -1, 0, 1这3个固定的值.

Space如果没有设置, 就默认为Space.Self, 即, 按照本地坐标系移动.
Space.World, 按照世界坐标系移动.
也可以设置一个 xxx.transform, 按它的坐标系移动.
(Unity里的各种坐标很坑)

4, Vector3. Lerp( )

//第一种方法
transform.position = Vector3.Lerp(transform.position, end.position, moveSpeed);
//第二种方法
transform.position = Vector3.Lerp(start.position, end.position, Time.deltaTime);

3个参数: 起点, 终点, 插值.
插值是一个0到1的数, 如果是0, 返回start.position, 如果是1, 返回end.position, 如果是0.1, 返回两者之间10%的位置点. 然后transform.position=这个点.
想要移动有2种方法:
1, 改变start的坐标点
2, 改变moveSpeed
像是被猛地推了一下, 然后在摩擦力的作用下减速.
Lerp你一定要学, 使运动看起来比较平滑

5, 使用DOTween插件

//花费0.5秒, 移动到111
transform.doMove(Vector3.one, 0.5f);

更多DOTween的使用↓


以下3个适用于刚体RigidBody, 我用小球测试的

6, MovePosition( )

Rigidbody rig = GetComponent<Rigidbody>();
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
rig.MovePosition(transform.position+ new Vector3(h, 0, v).normalized  * moveSpeed*Time.deltaTime);

给Position, 让刚体瞬间移到Position的位置, 不受惯性 ,不能上坡(因为y轴定死了等于0)

7, Volecity

Rigidbody rig = GetComponent<Rigidbody>();
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
rig.velocity = new Vector3(h,0,v).normalized *moveSpeed;

给一个速度, 立即改变物体的速度, 如果什么都不输入即h和v都是0, 物体立马就停了, 不受惯性, 能上坡

8, AddForce( )

Rigidbody rig = GetComponent<Rigidbody>();
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
rig.AddForce(new Vector3(h, 0, v).normalized *moveSpeed*10);

相当真实的模拟物理作用, 给一个力, 就像推一下, 会有惯性, 持续给力速度会越来越快, 能上坡(速度不够的话冲上不去)

以上3个适用于刚体. 实际做游戏中, 能不用刚体就尽量不用, 尽可能的自己写代码模拟物理效果. 用上了刚体就会在碰撞中受到各种奇怪的力, 比如吃鸡里的车会螺旋飞天.


9, transform.Rotate ( )

transform.rotate(Vector3.up, Space.Self);

地球自转, 也可以Space.World, 见第3条

10, transform.RotateAround( )

transform.rotateAround(Sun.position, Vector3.up, turnSpeed * Time.deltaTime);

绕太阳公转

11, 计算距离

float dis = Vector3.Distance(start.position, stop.position);
//或者
float dis = (start.position- stop.position).magnitude;

可以用距离<0.1f来让它停止移动

float dis = Vector3.Distance(transform.position, stop.position);
if(dis < 0.1f)
{
	transform.position += stop.position.normalized * moveSpeed * Time.deltaTime;
}

Vector3.normalized;返回这个向量的单位向量, 原向量的值不变;
Vector3.Normalized();这个方法把这个向量转化为单位向量, 会改变原向量的值;