Menu
CoddyTech

用挡板瞄准

Coddy Unity 游戏:打砖块 课程的第 4 课,共 19 课。

如果反弹完全遵循物理规律,玩家就无法瞄准。《打砖块》游戏让挡板决定方向:球击中左端附近时,会向左上方飞;击中中间时,会笔直向上飞。

把击中位置转换成一个从左端的 -1 到右端的 1 的数值:球的 x 坐标与挡板中心 x 坐标的偏移量,除以挡板宽度的一半。挡板宽 4,中心位于 x 2,在 x 3 处被击中:偏移量是 1,宽度的一半是 2,所以数值是 0.5,球会沿着经过归一化的方向 (0.5, 1, 0) 飞出。要对它进行钳制,因为球有时会碰到超出边缘一点的角落。

OnCollisionEnter 会在物理系统算出反弹结果后运行,因此在其中设置的速度会替代原来的速度。球也会撞到墙并保持普通反弹,所以要先检查标签。collision.collider.bounds.size.x 是挡板在世界坐标中的宽度。

challenge icon

挑战

简单

用球拍控制球的方向:球落下的位置决定角度。

  1. 在 Ball 中添加 OnCollisionEnter(Collision collision);如果碰撞对象没有标记为 Paddle,就返回。
  2. 计算 float x:用球的 x 坐标减去球拍的 x 坐标,再除以 collision.collider.bounds.size.x 的一半,并将结果限制在 -1 到 1 之间。
  3. 设置 rb.linearVelocity = new Vector3(x, 1f, 0f).normalized * speed;

按下“开始”,让球落在球拍的左端接住它:球会向左飞出。然后点击“检查”。

亲手试试

using UnityEngine;
using UnityEngine.InputSystem;

public class Ball : MonoBehaviour
{
    public Transform paddle;
    public float speed = 9f;

    Rigidbody rb;
    bool launched;

    void Awake()
    {
        rb = GetComponent<Rigidbody>();
        PhysicsMaterial bouncy = new PhysicsMaterial("Bouncy");
        bouncy.bounciness = 1f;
        bouncy.dynamicFriction = 0f;
        bouncy.staticFriction = 0f;
        bouncy.bounceCombine = PhysicsMaterialCombine.Maximum;
        bouncy.frictionCombine = PhysicsMaterialCombine.Minimum;
        GetComponent<Collider>().material = bouncy;
    }

    void Update()
    {
        if (launched) return;
        transform.position = paddle.position + Vector3.up * 0.5f;
        if (Keyboard.current.spaceKey.wasPressedThisFrame) Launch(new Vector3(0.3f, 1f, 0f));
    }

    public void Launch(Vector3 direction)
    {
        launched = true;
        rb.linearVelocity = direction.normalized * speed;
    }

    void FixedUpdate()
    {
        if (!launched) return;
        rb.linearVelocity = rb.linearVelocity.normalized * speed;
    }
}

Unity 游戏:打砖块中的所有课

自己练习: Unity 在线编辑器