不能将InvokeRepeating与方法参数一起使用。我该如何解决这个问题?

时间:2016-01-02 14:27:53

标签: c# unity3d

我试图通过时间系统实施损坏,但是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%,这太快了。我该如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

你不能将InvokeRepeatingOnTriggerEnter一起使用,因为它是一个触发器,这意味着当它的持有者进入时会触发一次。 同样InvokeRepeating意味着你想继续不断地重复一个动作,这不是这里的情况。您希望触发器发生一次,然后随着时间的推移删除health points

解决方案 - Coroutine

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")停止所有现在处于活动状态的协同程序。