Unity中如何调用带参数的void方法实现延迟物品拾取功能
核心问题原因
Invoke 本身不支持传递参数,而你定义的 PickItem 方法要求必须传入一个 PickableItem 类型的物品实例,所以直接调用无参的 PickItem() 无法执行。
方法参数规则说明
你代码里 public void PickItem(PickableItem item) 括号内的 PickableItem item 就是方法的形参,作用是声明这个方法执行时需要调用方传入一个符合类型要求的实例,告诉方法你要操作的具体是哪个物品。你看到的 /// <param name="item">Item.</param> 是XML注释,仅用于给代码做标注说明,不影响实际运行逻辑。
方案1:用临时变量兼容现有Invoke逻辑
只需要少量修改即可适配你现在的写法:
- 新增类成员变量存储待拾取的物品,以及防止重复触发的标记:
// 原有变量保持不变,新增以下两个变量 private PickableItem pendingPickItem; private bool isPicking = false;
- 修改
OnTriggerStay里的触发逻辑:
private void OnTriggerStay(Collider other) { if (other.gameObject.tag == "Item") { inrange = true; if (inrange == true && (number % 2) == 1 && !isPicking) { var pickable = other.gameObject.GetComponent<PickableItem>(); if (pickable) { isPicking = true; pendingPickItem = pickable; Invoke("delay", 1f); } } } }
- 修改
delay方法:
public void delay() { number = number + 1; if (pendingPickItem != null && inrange) { PickItem(pendingPickItem); pendingPickItem = null; } isPicking = false; }
方案2:更稳定的协程实现(推荐)
协程天然支持传参,逻辑更可控,避免Invoke的不可控问题:
- 删除原来的Invoke调用和delay方法,在
OnTriggerStay里直接启动协程:
private void OnTriggerStay(Collider other) { if (other.gameObject.tag == "Item") { inrange = true; if (inrange == true && (number % 2) == 1 && !isPicking) { var pickable = other.gameObject.GetComponent<PickableItem>(); if (pickable) { isPicking = true; StartCoroutine(PickItemAfterDelay(pickable, 1f)); } } } }
- 新增协程方法:
IEnumerator PickItemAfterDelay(PickableItem item, float delayTime) { yield return new WaitForSeconds(delayTime); // 延迟结束后额外判断状态,避免玩家已经离开触发区还执行拾取 if (inrange && item != null && (number % 2) == 1) { number += 1; PickItem(item); } isPicking = false; }
内容的提问来源于stack exchange,提问作者Coding_Goose
相关产品推荐
相关产品推荐

