无法将InvokeRepeating与方法参数一起使用.我该如何解决? [英] Cannot use InvokeRepeating with method parameters. How do I work around this?
问题描述
我正在尝试实施随时间推移而造成的损害的系统,但是Unity一直在说试图调用方法...无法被调用."我想调用的方法使用参数"Collider coll",但是根据我的研究,如果该方法具有参数,则无法调用.
I'm trying to implement a damage over time system, but Unity keeps saying "Trying to Invoke method...Couldn't be Called." The method I want to call uses the parameters "Collider coll", but from my research you can't invoke if the method has said paremters.
这是我的代码:
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%,这太快了.我应该如何解决?
My goal is to get the OnTriggerEnter function to loop ever 1/4 of a second (or lower possibly). Current upon entering a collider my health is drained by 60% in about a second which is far too fast. How should I work around this?
推荐答案
您不能将InvokeRepeating
与OnTriggerEnter
一起使用,因为它是触发器,这意味着一旦其持有人进入,它将触发一次.
另外,InvokeRepeating
表示您要继续连续重复操作,而在这里情况并非如此.您希望触发一次,然后随着时间的推移删除health points
.
You can't use InvokeRepeating
with OnTriggerEnter
, because it's a trigger, which means it will trigger once when entrance of its holder occured.
Also InvokeRepeating
means that you want to keep repeating an action continously which is not the case here. You want your trigger to occur once and then remove health points
over time.
Unity3D
对IEnumerable
和称为Coroutine
的yield
关键字进行自定义用法,该关键字始终返回IEnumerator
.怎么运行的?它会在我们的Coroutine
中的每个yield
上返回控制权,然后返回到它提供控制权的确切点,而不是从头开始执行函数.
Unity3D
makes custom usage of IEnumerable
and yield
keyword called Coroutine
that always returns an IEnumerator
. How it works? It will return control on every yield
there is in our Coroutine
and then will go back to exact point where it gave back control instead of starting function execution from scratch.
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.上面的代码只是有关如何处理此类情况的简单示例.
There's of course room for improvement in this Coroutine
. You can pass parameters to it, same as you can to any other method in C#
. Also you can implement other invervals that are not hardcoded. Code above is just a simple example on how to deal with such scenarios.
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()
停止当前处于活动状态的所有协程.
To stop Coroutine
somewhere else from code use StopCoroutine("DamageOverTimeCoroutine")
to stop certain coroutine type or StopAllCoroutines()
to stop all coroutines that are active now.
这篇关于无法将InvokeRepeating与方法参数一起使用.我该如何解决?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!