主要技术:射线判断鼠标位置,鼠标添加事件,ShaderGraph,Cinemachine,Post Postcessing

鼠标管理器

事件:通过点击或其他判定实现一个函数方法

创建鼠标点击事件

定义完事件之后,优先想将什么函数加进去

  • public event Action<Vector3> OnMouseClickedOnMouseClicked是一个事件,在里面添加函数
    • 添加方法:在PlayerController中将位移函数MoveToTarget 注册到事件中,MouseManager.Instance.OnMouseClicked += MoveToTarget
    • 添加方法:在PlayerController中将移动到敌人位置函数EventAttack 注册到事件中,MouseManager.Instance.OnEnemyClicked += EventAttack;
  • 选中 NavMeshAgent - Destination 就是 agent 的目标点,将目标点传给 NavMeshAgent 的位置移动

射线判断鼠标点击位置

射线是通过碰撞体判断的

  • Camera.ScreenPointToRay:屏幕上的点转换为射线,得到射线 Ray

    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition)

  • Physics.Raycast:先有一条射线Ray,通过起点和方向碰撞到RaycastHit类型的值

    RaycastHit hitInfo

    返回类型 = Physics.Raycast(ray, out hitInfo)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # MouseManager
    public class MouseManager : Singleton<MouseManager>
    {
    // 射线碰撞到的物体信息
    RaycastHit hitInfo;
    // 鼠标碰到地面 移动到点击位置
    public event Action<Vector3> OnMouseClicked;
    // 鼠标点击到敌人 敌人碰撞体遮住了地面 单独设置鼠标点击敌人事件
    public event Action<GameObject> OnEnemyClicked;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    # MouseManager
    //鼠标点击位置 有返回值 用tag判断点击的物体
    if (Input.GetMouseButtonDown(0) && hitInfo.collider != null)
    {
    // 鼠标射线碰撞体为地面 点击地面的点传到事件,人物移动到点击位置
    if (hitInfo.collider.gameObject.CompareTag("Ground"))
    {
    // 点击鼠标之后 触发 OnMouseClicked 事件 该事件添加的方法都要执行
    // hitInfo.point 传给位移终点 MoveToTarget(Vector3 target)
    OnMouseClicked?.Invoke(hitInfo.point); // ?为是否
    }
    // 鼠标射线碰撞体为敌人 触发事件
    if (hitInfo.collider.gameObject.CompareTag("Enemy"))
    {
    OnEnemyClicked?.Invoke(hitInfo.collider.gameObject);
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # PlayerController
    // 生成人物鼠标才开始注册方法
    void OnEnable()
    {
    // OnMouseClicked 事件添加一个方法 点击地面
    MouseManager.Instance.OnMouseClicked += MoveToTarget;
    // OnEnemyClicked 事件添加一个方法 点击敌人
    MouseManager.Instance.OnEnemyClicked += EventAttack;
    }
    public void MoveToTarget(Vector3 target)
    {
    agent.destination = target;
    }

鼠标指针设置

  • 鼠标纹理传入:public Texture2D point, doorway, attack, target, arrow

  • 根据Tag判断用什么图标

    • 指针图标API:Cursor.SetCursor(图标名, 大小, CursorMode.Auto)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 获得摄像机到鼠标点击坐标的射线 
    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    // 画出该条射线
    if (Physics.Raycast(ray, out hitInfo))
    {
    // 切换鼠标贴图
    switch (hitInfo.collider.gameObject.tag)
    {
    case "Ground":
    Cursor.SetCursor(target, new Vector2(16, 16),CursorMode.Auto);
    break;
    }

鼠标射线被遮挡

  • 方案一:将遮挡物的Layer设置为Ignore Raycast
  • 方案二:取消遮挡物的collider

Cinemachine & Post Processing

Cinemachine

插件:设置跟踪距离等

FreeLook:鼠标滚轮控制视角

Cinemachine 的一种

  • 调用Project setting -> Input -> 两个控制

    QQ截图20220905123144

Post Processing(Global volume)

MainCamera -> Rendering -> Post Processing先开启才有效果

新建 -> Volume -> Global volume,先新建Prefab

QQ截图20220904020922