Unity中Button调用方法启动协程仅执行Debug.Log逻辑不生效
问题根因
这个故障是Unity UI按钮回调绑定的典型错误:你给Button的OnClick事件绑定回调时,拖入的是Project资源面板里的玩家预制体,不是Hierarchy窗口里放置的场景玩家运行实例。
症状匹配逻辑
- 键盘触发完全正常的原因:键盘输入检测是场景中激活的玩家物体上挂载的脚本在
Update生命周期内执行的,调用的是当前实例自己的Jump协程,修改的是当前场景玩家的位置、自身脚本的testint和onGround变量,逻辑链路完全正确。 - 点击按钮只有Debug.Log能输出的原因:
- 按钮点击后会调用你绑定的「预制体上挂载的脚本实例」的
ButtonUp方法,预制体上的onGround默认值为true,所以Debug.Log("wtf")会正常打印。 - 紧接着预制体实例上的
StartCoroutine(Jump())被调用,协程第一次执行会同步跑完第一个yield return之前的所有代码,所以Debug.Log("wtf 2")也会被打印。
- 按钮点击后会调用你绑定的「预制体上挂载的脚本实例」的
- 玩家不跳跃、
testint数值不变的原因:- 所有位移逻辑、
testint++的修改,全都是作用在「Project里的预制体资源」关联的脚本实例上,你在Play模式下盯着观察的是Hierarchy里场景玩家的testint数值和位置,当然看不到变化。 - 预制体资源本身不属于场景里激活的运行时对象,协程跑到
yield return new WaitForSeconds(.62f)这行之后,Unity的协程调度器不会对这个非运行时实例的协程做后续帧驱动,后续逻辑完全不会执行。 - 左右移动按钮触发完全相同的故障,也是因为同一个绑定错误。
- 所有位移逻辑、
修复步骤
- 选中场景内对应的UI Button,在Inspector面板找到
On Click ()事件配置栏 - 删除之前绑定的、引用自Project面板预制体的错误事件条目
- 从Hierarchy窗口把场景中存在的玩家对象拖到事件的对象选择槽中,不要选Project里的预制体资源
- 下拉选择对应脚本组件下的
ButtonUp(以及左右移动的对应公开方法)作为回调函数 - 进入Play模式测试即可恢复正常
可选代码优化参考
你自己也提到当前写法效率低,除了绑定错误外,现有代码还有两个隐性问题:一是new Vector3(0, .5f, 0 * Time.deltaTime)里z轴计算完全无意义,6次位移在同一帧执行完本质是瞬移,没有跳跃过渡;二是没有协程重叠防护,快速多次触发会导致多个协程同时运行,onGround状态错乱。可以参考以下写法调整:
private Coroutine _jumpCoroutine; public void ButtonUp() { if (onGround && _jumpCoroutine == null) { _jumpCoroutine = StartCoroutine(Jump()); } } IEnumerator Jump() { onGround = false; float jumpUpDuration = 0.3f; float jumpHeight = 3f; float fallDuration = 0.32f; // 和原逻辑总时长0.62s对齐 Vector3 startPos = player.position; Vector3 topPos = startPos + new Vector3(0, jumpHeight, 0); // 上升过渡 float timer = 0; while (timer < jumpUpDuration) { timer += Time.deltaTime; player.position = Vector3.Lerp(startPos, topPos, timer / jumpUpDuration); yield return null; } // 下落过渡 timer = 0; while (timer < fallDuration) { timer += Time.deltaTime; player.position = Vector3.Lerp(topPos, startPos, timer / fallDuration); yield return null; } player.position = startPos; onGround = true; _jumpCoroutine = null; }
内容的提问来源于stack exchange,提问作者Mirazz_Boi
相关产品推荐
相关产品推荐

