Unity3D传送脚本问题:执行时地面抖动、角色后方持续震动
Unity传送脚本抖动问题修复方案
问题根源
- 持续重复触发:
Update中使用Input.GetKey(KeyCode.E),按住E会每帧调用teleport方法,频繁修改角色位置+持续扣除 mana,直接导致画面抖动。 - 物理引擎冲突:直接修改
transform.position时,若Player带有Rigidbody组件,物理系统会自动修正位置,引发角色周边的震动反馈。 - 状态标志未生效:
isteleporting变量仅在传送开始时设为true,但没有配套逻辑限制重复触发,无法阻止连续调用。
修复后的完整代码
public float range = 1000f; public float tprange = 100f; private Transform Destination; public int mana = 100; public int currentmana; public Camera Camera; public GameObject Player; public ManaBar ManaBar; bool isteleporting; void Start() { currentmana = mana; ManaBar.SetMaxMana(mana); isteleporting = false; } void Update() { // 改用GetKeyDown仅在按键按下瞬间触发一次,同时增加状态与 mana 校验 if (Input.GetKeyDown(KeyCode.E) && !isteleporting && currentmana >= 20) { teleport(20); } } void teleport(int consume) { isteleporting = true; currentmana -= consume; ManaBar.SetMana(currentmana); RaycastHit hit; // 增加射线距离限制,使用定义好的range变量 if (Physics.Raycast(Camera.transform.position, Camera.transform.forward, out hit, range)) { // 按标签判断地面(需给地面物体设置对应标签,比如"Ground") if (hit.collider.CompareTag("Ground")) { Rigidbody playerRb = Player.GetComponent<Rigidbody>(); if (playerRb != null) { // 暂时禁用物理模拟,避免位置突变引发抖动 playerRb.isKinematic = true; Player.transform.position = hit.point; // 延迟一帧恢复物理,确保位置稳定 Invoke(nameof(ResumePhysics), 0.01f); } else { Player.transform.position = hit.point; } } } // 重置传送状态 isteleporting = false; } void ResumePhysics() { Rigidbody playerRb = Player.GetComponent<Rigidbody>(); if (playerRb != null) { playerRb.isKinematic = false; } }
关键修改说明
- 触发逻辑优化:将
Input.GetKey替换为Input.GetKeyDown,确保传送只在按键按下的第一帧触发一次,避免连续调用。 - 触发条件校验:增加
!isteleporting和currentmana >= 20的判断,防止 mana 不足或传送过程中重复触发。 - 物理冲突解决:针对带Rigidbody的Player,先将其设为运动学状态,修改位置后延迟恢复物理,避免引擎自动修正位置导致的震动。
- 射线检测优化:给Raycast添加距离限制,减少无效检测;改用标签判断地面,避免误传送到其他带刚体的物体上。
内容的提问来源于stack exchange,提问作者The Flipper Stone 782
相关产品推荐
相关产品推荐

