我试图通过时间系统实施损坏,但是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%,这太快了。我该如何解决这个问题?
答案 0 :(得分:0)
你不能将InvokeRepeating
与OnTriggerEnter
一起使用,因为它是一个触发器,这意味着当它的持有者进入时会触发一次。
同样InvokeRepeating
意味着你想继续不断地重复一个动作,这不是这里的情况。您希望触发器发生一次,然后随着时间的推移删除health points
。
Unity3D
自定义使用名为IEnumerable
的{{1}}和yield
关键字,该关键字始终返回Coroutine
。这个怎么运作?它会在IEnumerator
中的每个yield
上返回控制权,然后返回到它返回控制的确切位置,而不是从头开始执行函数。
Coroutine
这个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
中的任何其他方法一样。您还可以实现其他非硬编码的invervals。上面的代码只是一个关于如何处理这种情况的简单示例。
C#
要从代码中停止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")
停止所有现在处于活动状态的协同程序。