不能将InvokeRepeating与方法参数一起使用.我该如何解决这个问题
本文关键字:何解决 解决 问题 InvokeRepeating 方法 参数 一起 不能 | 更新日期: 2023-09-27 18:28:39
我正试图实现一个随时间损坏的系统,但Unity一直在说"正在尝试调用方法…无法调用。"我想调用的方法使用参数"Collider coll",但根据我的研究,如果该方法说了参数,你就无法调用。
这是我的代码:
using UnityEngine;
using UnityEngine.SceneManagement;
using System.Collections;
public class DamageOverTime : MonoBehaviour
{
public int PHP; //PHP = Player Health from PlayerHealth.cs script.
public int Damage; //Amount of damage.
public int DamageOverTime; //Damage over time.
public float DamageInterval_DOT = .25f; //Damage interval for damage over time.
public string Level;
PlayerHealth player;
void Start()
{
player = GameObject.Find("Player").GetComponent<PlayerHealth>();
InvokeRepeating("OnTriggerEnter", DamageInterval_DOT, DamageInterval_DOT);
}
void Update()
{
PHP = GameObject.Find("Player").GetComponent<PlayerHealth>().PlayerHP;
if (PHP <= 0)
{
SceneManager.LoadScene(Level);
}
}
void OnTriggerEnter(Collider coll)
{
if (coll.gameObject.tag == "Player")
{
GameObject.Find("Player").GetComponent<PlayerHealth>().PlayerHP = PHP - Damage;
}
if (coll.gameObject.tag == "Ball")
{
gameObject.SetActive(false);
SceneManager.LoadScene(Level);
}
}
}
我的目标是让OnTriggerEnter函数循环1/4秒(或更低)。当电流进入对撞机时,我的健康在大约一秒钟内耗尽了60%,这太快了。我应该如何解决这个问题?
不能将InvokeRepeating
与OnTriggerEnter
一起使用,因为它是一个触发器,这意味着当其持有者进入时,它将触发一次。另外,InvokeRepeating
意味着你希望不断重复一个动作,而这里的情况并非如此。您希望触发器发生一次,然后随着时间的推移删除health points
。
解决方案-Coroutine
Unity3D
自定义使用IEnumerable
和yield
关键字Coroutine
,后者总是返回IEnumerator
。它是如何工作的?它将返回对Coroutine
中的每个yield
的控制,然后返回到它返回控制的确切点,而不是从头开始执行函数。
代码:
void OnTriggerEnter(Collider coll)
{
if (coll.gameObject.tag == "Player")
{
StartCoroutine("DamageOverTimeCoroutine");
}
if (coll.gameObject.tag == "Ball")
{
gameObject.SetActive(false);
SceneManager.LoadScene(Level);
}
}
public IEnumerator DamageOverTimeCoroutine()
{
var dotHits = 0;
while (dotHits < 4)
{
//Will remove 1/4 of Damage per tick
GameObject.Find("Player").GetComponent<PlayerHealth>().PlayerHP -= Damage / 4;
dotHits++;
//Will return control over here
yield return new WaitForSeconds(DamageInterval_DOT);
//And then control is returned back here once 0.25s passes
}
}
这个Coroutine
当然还有改进的空间。您可以将参数传递给它,就像传递给C#
中的任何其他方法一样。此外,您还可以实现其他非硬编码的inverval。上面的代码只是关于如何处理此类场景的一个简单示例。
随着时间的推移持续损坏
public IEnumerator DamageOverTimeCoroutine()
{
var dotHits = 0;
var player = GameObject.Find("Player").GetComponent<PlayerHealth>();
while (true)
{
//Stop removing damage, player is dead already
if (player.PlayerHP <= 0)
yield break;
//Will remove 5 Damage per tick
player.PlayerHP -= 5;
dotHits++;
//Will return control over here
yield return new WaitForSeconds(DamageInterval_DOT);
//And then control is returned back here once 0.25s passes
}
}
要从代码中的其他地方停止Coroutine
,请使用StopCoroutine("DamageOverTimeCoroutine")
停止某些协程类型,或使用StopAllCoroutines()
停止所有当前活动的协程。