Menu
CoddyTech

击退

本课属于 Coddy Unity 学习旅程的“物理与游戏玩法”单元。第 57 课,共 71 课。

击退就是把击中你的物体踢开:沿着从击打者到被击中物体的直线施加一次冲量。这个缓冲器会击退所有撞上它的物体:

[SerializeField] private float power = 8f;

void OnCollisionEnter(Collision collision)
{
    Vector3 away = collision.transform.position - transform.position;
    away.y = 0f;
    collision.rigidbody.AddForce(away.normalized * power, ForceMode.Impulse);
}

collision.transform.position - transform.position 指向从缓冲器到撞上它的物体的方向。将它的 y 设为 0,这样踢击就会保持水平;normalized 会让方向向量的大小保持不变,无论两个中心相距多远。ForceMode.Impulse 表示一次性的踢击:它会立刻将速度改变 power 除以质量的大小,因此质量为 2 的球飞出的速度是质量为 1 的球的一半。默认的 ForceMode.Force 适用于每一步都施加力,其效果只有一步的量,也就是小 50 倍。

只要没有东西覆盖速度,这次踢击就会持续生效。如果玩家的 FixedUpdate 在每一步都根据方向键设置 rb.linearVelocity,那么踢击效果会在一步后消失。因此,这样的脚本必须在受到击打后暂时不改动速度,或者用力来移动玩家。

challenge icon

挑战

中等

让玩家按下 Space 触发冲击波。

  1. 当 Input.GetKeyDown(KeyCode.Space) 时,遍历 foreach (Collider hit in Physics.OverlapSphere(transform.position, radius)),跳过玩家自己的碰撞体。
  2. 对于每个 hit.TryGetComponent(out Rigidbody body),使用 away = hit.transform.position - transform.position,并设置 away.y = 0f。
  3. 调用 body.AddForce(away.normalized * power + Vector3.up * lift, ForceMode.Impulse);。

按下“开始”,然后在箱子之间按下 Space。接着点击“检查”。

亲手试试

using UnityEngine;

public class Shockwave : MonoBehaviour
{
    [SerializeField] private float radius = 4f;
    [SerializeField] private float power = 6f;
    [SerializeField] private float lift = 2f;

    void Update()
    {
        // 按下 Space 时:将 radius 范围内的每个 Rigidbody 推离玩家
    }
}

物理与游戏玩法中的所有课

自己练习: Unity 在线编辑器