Unity Actions/事件/委托使用困惑:UI按钮驱动玩家移动求助
Unity UI按钮绑定静态Actions实现玩家移动方案
一、UI按钮绑定触发方法
- 在场景中创建前后左右四个UI按钮,选中按钮后在Inspector面板找到
On Click()事件区域。 - 创建空物体命名为
UIManager,挂载如下脚本:
using UnityEngine; public class UIManager : MonoBehaviour { // 向前按钮触发方法 public void onMoveForwardClicked() { Actions.OnPlayerMoved?.Invoke(Directions.Forward); } // 向后按钮触发方法 public void onMoveBackwardClicked() { Actions.OnPlayerMoved?.Invoke(Directions.Backward); } // 向左按钮触发方法 public void onMoveLeftClicked() { Actions.OnPlayerMoved?.Invoke(Directions.Left); } // 向右按钮触发方法 public void onMoveRightClicked() { Actions.OnPlayerMoved?.Invoke(Directions.Right); } }
- 将
UIManager物体拖拽到每个按钮的On Click()事件对象槽中,分别选择对应方向的触发方法。
二、注册Actions监听逻辑
在Player脚本中注册对Actions.OnPlayerMoved的监听,确保触发时执行移动逻辑,同时在销毁时移除监听避免内存泄漏:
using UnityEngine; public class Player : MonoBehaviour { private Vector2Int currentPos; private void Awake() { // 从Map类获取初始位置 currentPos = Map.Instance.playerStartPos; // 注册监听:移动事件触发时执行MovePlayer Actions.OnPlayerMoved += MovePlayer; } private void OnDestroy() { // 移除监听,防止内存泄漏 Actions.OnPlayerMoved -= MovePlayer; } public void MovePlayer(Directions direction) { Vector2Int newPos = currentPos; // 根据方向计算新位置 switch (direction) { case Directions.Forward: newPos += Vector2Int.up; break; case Directions.Backward: newPos += Vector2Int.down; break; case Directions.Left: newPos += Vector2Int.left; break; case Directions.Right: newPos += Vector2Int.right; break; } // 调用Map类方法更新地图中的玩家位置 Map.Instance.setNewPlayerPositions(currentPos, newPos); // 更新玩家当前位置 currentPos = newPos; } }
三、完善Map类核心逻辑
通过单例模式提供全局访问,正确处理位置更新和边界检查:
using UnityEngine; public class Map : MonoBehaviour { public static Map Instance; public int[,] grid; public Vector2Int playerStartPos; private void Awake() { Instance = this; // 初始化10x10地图 grid = new int[10, 10]; // 设置玩家初始中心位置 playerStartPos = new Vector2Int(5, 5); // 标记初始位置为玩家所在 grid[playerStartPos.x, playerStartPos.y] = 1; } public void setNewPlayerPositions(Vector2Int oldPos, Vector2Int newPos) { // 边界检查:防止玩家移出10x10地图范围 if (newPos.x < 0 || newPos.x >= 10 || newPos.y < 0 || newPos.y >= 10) return; // 重置旧位置标记 grid[oldPos.x, oldPos.y] = 0; // 设置新位置标记 grid[newPos.x, newPos.y] = 1; } }
四、关键细节说明
- 空引用防护:使用
?.Invoke()触发Action,避免在无监听者时抛出空引用异常。 - 多监听机制:静态Action支持多个脚本同时监听,比如后续添加移动音效、动画触发逻辑,只需在对应脚本中注册
Actions.OnPlayerMoved += 目标方法,无需修改现有代码。 - 参数传递:
Action<Directions>的泛型定义实现了方向参数的传递,触发时传入的方向会被所有监听方法接收。
内容的提问来源于stack exchange,提问作者colossalchrist97
相关产品推荐
相关产品推荐

