封装 Raycast 调用

如果你需要在将来更改碰撞矩阵,让脚本直接调用 Raycast 可能会导致问题,因为你必须跟踪每个 LayerMask 字段以适应更改。根据项目的规模,这可能会成为一项艰巨的任务。

封装 Raycast 调用可能会让你的生活更轻松。

SoC 原理来看,游戏对象真的不应该知道或关心 LayerMasks。它只需要一种扫描周围环境的方法。光线投射结果是否返回此对象或对游戏对象无关紧要。它应该只根据收到的信息采取行动,而不对其所处的环境做出任何假设。

解决此问题的一种方法是将 LayerMask 值移动到 ScriptableObject 实例,并将其用作你注入脚本的光线投射服务形式。

// RaycastService.cs
using UnityEngine;

[CreateAssetMenu(menuName = "StackOverflow")]
public class RaycastService : ScriptableObject
{
    [SerializeField]
    LayerMask layerMask;

    public RaycastHit2D Raycast2D(Vector2 origin, Vector2 direction, float distance)
    {
        return Physics2D.Raycast(origin, direction, distance, layerMask.value);
    }

    // Add more methods as needed

}
// MyScript.cs
using UnityEngine;

public class MyScript : MonoBehaviour
{
    [SerializeField]
    RaycastService raycastService;

    void FixedUpdate()
    {
        RaycastHit2D hit = raycastService.Raycast2D(Vector2.zero, Vector2.down, 1f);
    }
}

这允许你制作一些光线投射服务,所有这些服务都针对不同情况使用不同的 LayerMask 组合。你可以有一个只击中地面对撞机,另一个击中地面对撞机和单向平台。

如果你需要对 LayerMask 设置进行重大更改,则只需更新这些 RaycastService 资产。

进一步阅读