Unity 2D平台游戏:将E键箱子抓取功能改为UI按钮实现
修改方案:将按键触发改为UI按钮触发
核心修改点
- 新增状态变量跟踪是否正持有箱子
- 提取抓取/释放逻辑为公共方法,供UI按钮直接调用
- 修复原脚本中潜在的空引用错误
- 调整射线检测时机,仅在点击抓取按钮时执行
修改后的完整脚本
using UnityEngine; public class trigger : MonoBehaviour { private PlayerMovement1 move; [SerializeField] public LayerMask jumpableGround; private PlayerPush grab; public float distance = 1f; public LayerMask boxmask; [SerializeField] private Animator anim; [SerializeField] private Rigidbody2D rb1, rb2; private GameObject currentHeldBlock; private bool isHoldingBlock = false; void Start() { anim = GetComponent<Animator>(); rb1 = GetComponent<Rigidbody2D>(); move = GetComponent<PlayerMovement1>(); grab = GetComponent<PlayerPush>(); } // 供UI抓取按钮调用的方法 public void OnGrabButtonPressed() { if (isHoldingBlock) return; // 避免重复抓取 Physics2D.queriesStartInColliders = false; RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.right * transform.localScale.x, distance, boxmask); if (hit.collider != null && hit.collider.gameObject.CompareTag("block")) { currentHeldBlock = hit.collider.gameObject; // 确保箱子有FixedJoint2D组件,没有则自动添加 FixedJoint2D joint = currentHeldBlock.GetComponent<FixedJoint2D>(); if (joint == null) { joint = currentHeldBlock.AddComponent<FixedJoint2D>(); } // 切换玩家状态 move.enabled = false; grab.enabled = true; anim.SetBool("Push_idle", true); anim.SetBool("player_idle", false); joint.enabled = true; joint.connectedBody = rb1; rb2.constraints = RigidbodyConstraints2D.None; isHoldingBlock = true; } } // 供UI释放按钮调用的方法 public void OnReleaseButtonPressed() { if (!isHoldingBlock || currentHeldBlock == null) return; FixedJoint2D joint = currentHeldBlock.GetComponent<FixedJoint2D>(); if (joint != null) { joint.enabled = false; } // 恢复玩家原状态 anim.SetBool("player_push", false); anim.SetBool("Push_idle", false); anim.SetBool("player_idle", true); move.enabled = true; grab.enabled = false; rb2.constraints = RigidbodyConstraints2D.FreezePositionX | RigidbodyConstraints2D.FreezeRotation; isHoldingBlock = false; currentHeldBlock = null; } void OnDrawGizmos() { Gizmos.color = Color.yellow; Gizmos.DrawLine(transform.position, (Vector2)transform.position + Vector2.right * transform.localScale.x * distance); } }
Unity编辑器中设置UI按钮
- 在Canvas下创建两个Button(例如命名为"GrabButton"和"ReleaseButton")
- 选中抓取按钮,在Inspector的
On Click()列表中:- 点击
+号,拖拽玩家对象到对象槽 - 在下拉菜单中选择
trigger->OnGrabButtonPressed()
- 点击
- 对释放按钮重复上述操作,选择
trigger->OnReleaseButtonPressed()
关键细节说明
- 新增
isHoldingBlock和currentHeldBlock变量,防止重复抓取和空引用崩溃 - 修复原脚本中先调用组件再赋值对象的顺序错误
- 添加自动创建FixedJoint2D的逻辑,避免箱子缺少组件时出错
- 射线检测仅在点击按钮时执行,减少不必要的性能消耗
内容的提问来源于stack exchange,提问作者Yusril
相关产品推荐
相关产品推荐

