Unity2D开发入门-物体的运动和朝向

物体的运动

在Unity中,有多种方式可以让物体运动。

改变位置

通过修改物体的位置:
你可以直接修改物体的Transform组件的位置属性来实现运动。

例如,通过修改物体的transform.position属性来让物体在场景中移动。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using UnityEngine;

public class MoveObject : MonoBehaviour
{
public float speed = 5f;

// 更新物体的位置
void Update()
{
// 获取当前位置
Vector3 currentPosition = transform.position;

// 计算新的位置
currentPosition.x += speed * Time.deltaTime;

// 更新物体的位置
transform.position = currentPosition;
}
}

线性插值

Vector3.Lerp是Unity中的一个很实用的方法,它的全称是Linear Interpolation,即线性插值。它的主要作用是在两个向量之间进行线性插值。
Lerp方法的语法是:

1
public static Vector3 Lerp(Vector3 a, Vector3 b, float t);

参数说明:

  • a: 开始向量
  • b: 结束向量
  • t: 插值比例,范围为0~1

Lerp会根据t值,在a和b之间按照直线进行插值。
当t=0时,返回a;当t=1时,返回b。当t=0.5时,返回a和b的中间向量。
Lerp的示例:

1
2
3
4
5
Vector3 start = Vector3.zero; 
Vector3 end = new Vector3(10, 20, 30);
Vector3 mid = Vector3.Lerp(start, end, 0.5f);

// mid = (5, 10, 15)

Lerp常见的使用场景有:

  • 在两个位置之间进行平滑移动
  • 根据进度在两个颜色或值之间插值
  • 计算球体上均匀分布的顶点
  • 图像处理中的颜色过渡等

总结:

Lerp是非常基础和常用的数学方法,可以实现两点间的线性插值计算,在Unity游戏开发中有大量应用。

是摄像机移动、颜色渐变等效果的基础。

球面线性插值

Vector3.Slerp 也是一个非常有用的方法, 它代表 Spherical Linear intERPolation, 即球面线性插值.
Slerp与Lerp的区别在于:

  • Lerp进行的是直线插值, 而Slerp进行的是球面插值.
  • 当进行3D旋转插值时, 使用Slerp可以获得比较自然的弧形插值.

Slerp的基本语法是:

1
public static Vector3 Slerp(Vector3 a, Vector3 b, float t);

参数与Lerp类似. t为0-1区间的插值比例.
一个Slerp的使用示例:

1
2
3
4
5
6
// 开始角度为0度, 结束角度为90度
Vector3 start = Vector3.zero;
Vector3 end = Vector3.up * 90;

Vector3 mid = Vector3.Slerp(start, end, 0.5f);
// mid会得到大约45度的旋转角度

Slerp常见的使用场景有:

  • 计算摄像机的平滑旋转
  • 实现对象的平滑方向转向
  • 计算动画关键帧之间的旋转插值

总结:

Slerp适用于对3D旋转进行插值的场景, 可以获得更自然的弧形插值结果.

在Unity中, 一般会搭配Quaternion使用. 是实现平滑旋转动画的重要方法之一.

目标移动

1
2
3
4
5
6
7
8
Vector3 position = transform.position;
Vector3 pos = Vector3.MoveTowards
(
position,
position + Vector3.right * speed * Time.deltaTime,
speed * Time.deltaTime
);
transform.position = pos;

三个参数分别为

  • 起始位置
  • 目标位置
  • 最大距离

返回从起始位置到目标位置不超过最大距离的位置。

平滑阻尼

Vector3.SmoothDamp是一个非常有用的方法,它可以实现对象向目标位置平滑移动和减速的效果。
SmoothDamp方法的主要作用是:

  1. 计算对象当前至目标位置的方向和距离
  2. 对移动进行平滑处理,实现渐进式的速度变化
  3. 返回处理后的移动后的新位置

SmoothDamp的基本语法是:

1
2
3
4
5
6
public static Vector3 SmoothDamp(
Vector3 current,
Vector3 target,
ref Vector3 currentVelocity,
float smoothTime
);

参数说明:

  • current:对象当前的位置
  • target:目标位置
  • currentVelocity:对象的当前速度
  • smoothTime:到达目标位置的平滑时间

使用 SmoothDamp 进行对象移动的示例:

1
2
3
4
5
6
7
8
9
public class SmoothDampExample : MonoBehaviour {

public Transform target;
Vector3 velocity;
public float smoothTime = 0.3F;
private void Update() {
transform.position = Vector3.SmoothDamp(transform.position, target.position, ref velocity, smoothTime);
}
}

这样就可以使对象向target位置进行平滑移动。smoothTime参数控制移动的平滑程度和速度变化。
总结:
SmoothDamp是一个非常实用的方法,通过准确控制速度变化,可以实现很多平滑移动的效果,如追踪camera、 third person控制等。

是游戏开发中移动类问题的一大利器。

transform.Translate

相对于自己

1
transform.Translate(Vector2.right * speed * Time.deltaTime, Space.Self);

相对于世界

1
transform.Translate(Vector2.right * speed * Time.deltaTime, Space.World);

施加力

通过使用刚体组件:
刚体组件 Rigidbody 可以给物体施加力或应用力来实现运动。

例如,使用AddForce()方法来施加一个力使物体移动。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using UnityEngine;

public class MoveObject : MonoBehaviour
{
public float speed = 5f;
private Rigidbody rb;

void Start()
{
// 获取物体的刚体组件
rb = GetComponent<Rigidbody>();
}

void Update()
{
// 在X轴方向施加一个力
rb.AddForce(new Vector3(speed, 0f, 0f));
}
}

设置速度

1
2
3
4
private void FixedUpdate()
{
transform.GetComponent<Rigidbody2D>().velocity = Vector2.right * speed;
}

使用动画

通过使用动画组件:
动画组件 Animator 可以用来创建复杂的物体动画,包括移动。例如,通过设置Animator组件中的参数来控制物体的动画。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using UnityEngine;

public class MoveObject : MonoBehaviour
{
private Animator animator;

void Start()
{
// 获取物体的Animator组件
animator = GetComponent<Animator>();
}

void Update()
{
// 根据参数值控制播放动画
animator.SetFloat("Speed", 1f);
}
}

以上是Unity中让物体运动的几种常见方式及其示例。

根据实际需求和场景,你可以选择合适的方式来实现物体的运动。

朝向

如下bullet是子弹 nestEmemy是敌人

我们想让子弹的朝向为敌人的方向

1
2
3
4
Vector2 v = nestEmemy.transform.position - bullet.transform.position;
var angle = Mathf.Atan2(v.y, v.x) * Mathf.Rad2Deg;
var trailRotation = Quaternion.AngleAxis(angle, Vector3.forward);
bullet.transform.rotation = trailRotation;

敌人的位置减去子弹的位置能获取到子弹到敌人的向量。

Mathf.Atan2是Unity中的一个数学函数,用于计算给定y和x坐标之间的反正切(弧度值)。

它返回的是一个角度值,可以用来表示从x轴正向到从原点到指定点的射线之间的夹角。

Mathf.Atan2函数的原型如下:

1
public static float Atan2(float y, float x);

参数y代表射线的y坐标,参数x代表射线的x坐标。