使用Unity新输入系统时如何让单个按钮在不同场景执行不同功能
Unity新输入系统点击UI不触发Gameplay开火事件的高效实现方案
方案1:触发Fire逻辑前检测UI悬停状态(中小项目首选)
直接利用Unity原生EventSystem接口判断鼠标是否点击在UI元素上,不需要维护全局UI状态,代码改动量最小:
using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.InputSystem; public class PlayerCombat : MonoBehaviour { // 绑定你的Fire输入动作 public InputAction fireAction; private void OnEnable() { fireAction.performed += HandleFire; fireAction.Enable(); } private void OnDisable() { fireAction.performed -= HandleFire; fireAction.Disable(); } private void HandleFire(InputAction.CallbackContext context) { // 核心判断:鼠标悬停在UI上时直接跳过开火逻辑 if (EventSystem.current.IsPointerOverGameObject()) return; // 正常开火业务逻辑 Debug.Log("触发开火"); } }
注意:触屏设备使用时需要传入对应触摸点ID,示例:
EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId);使用自定义3D/世界空间UI时,需要确保UI对象挂载了Graphic Raycaster组件,否则会出现检测失效的问题。
方案2:输入事件优先级拦截(中大型项目首选)
利用新输入系统的事件优先级和消耗机制,完全解耦Gameplay和UI的输入逻辑,不需要修改开火侧代码:
- 在输入动作资产中,给UI点击动作设置比Gameplay的Fire动作更高的Priority属性值(优先级越高越先收到输入事件)
- 在UI交互的回调逻辑末尾调用
context.Use(),标记当前输入事件已被消耗,后续低优先级的Fire动作将不会收到本次事件通知
方案3:动作组分层启用(适配复杂UI交互场景)
你之前切换完整动作映射表失效的核心原因是直接禁用了整个Gameplay映射,导致移动逻辑也被拦截,调整为按动作组控制启用状态即可:
- 将Gameplay映射表拆分多个动作组:比如保留「移动/跳跃」等通用动作组始终启用,仅将「开火/技能」等战斗相关动作划分为独立的战斗组
- 打开UI时仅禁用战斗动作组、启用UI动作组,关闭UI时恢复战斗组的启用状态,全程不会影响移动等基础Gameplay输入
内容的提问来源于stack exchange,提问作者itsgalsugarfree
相关产品推荐
相关产品推荐

