【问题标题】:How to set the yield wait for seconds back to 60 seconds when the player gets hit by an enemy?当玩家被敌人击中时,如何将等待秒数设置为 60 秒?
【发布时间】:2017-04-04 12:05:54
【问题描述】:

基本上,我想制作一个玩家可以在用户按下加电按钮时随意变身为恶魔,但是我希望转换在 60 秒后结束(当转换结束时,我希望玩家恢复到原来的状态状态)。如果玩家被敌人击中,我还希望结束转换。到目前为止,我已经编写了这段代码并且它可以工作,但是当玩家被敌人击中并且用户决定按下按钮将玩家变回来时,我无法将收益等待秒数重置为 60 秒变成恶魔。谁能帮我解决这个问题?

在我的层次结构中,我的玩家作为父母,我的恶魔玩家作为孩子。附加到播放器的 playermovement 脚本以及下面的转换脚本:

  public GameObject demon;
  public BoxCollider2D col;
  public Renderer rend;
  public ParticleSystem par1;
  public static Vector3 target;


    void Start () {
        target = transform.position;
    }

    void Update () {
         target.z = transform.position.z;
    }

    public void DemonCharacter() {
    StartCoroutine (PowerUpCoroutine ());
}

     private IEnumerator PowerUpCoroutine() {

      yield return new WaitForSeconds (0.3f);

      par1.Play (); // particle system animation to cover transformation happening
  par1.transform.position = target;

      yield return new WaitForSeconds (0.2f);

      demon.SetActive (true); // activates demon gameobject

      rend.enabled = false; // deactivate players spriterenderer 

      col.enabled = false;

      yield return new WaitForSeconds (60f);

      demon.SetActive (false); // deactivates demon gameobject

      rend.enabled = true; // activate players spriterenderer

      col.enabled = true;

      par1.Stop ();
   }

在我的恶魔播放器上,我附上了这个脚本; 我可以工作,但是当用户单击按钮以转换为恶魔时,yield waitforseconds 不会停止,因此当玩家在几秒钟后变成恶魔时,恶魔玩家会变回玩家,而不是重置 yield wait 秒。

    public BoxCollider2D Playercol;
    public Renderer PlayerRend;

void Start()
{

}

void Update ()
{

}

void OnTriggerEnter2D(Collider2D col) {
    if (col.tag == "enemy") {
        demon.SetActive (false);
        PlayerRend.enabled = true;
        Playercol.enabled = true;
    }
}

【问题讨论】:

  • 您说您遇到了麻烦,但您能否更清楚地说明(告诉我们)您的代码现在做什么以及您实际期望或希望它做什么?另外,我在您的问题中没有看到太多的研究工作,您能告诉我们您已经尝试过什么吗?您是否在网上搜索过解决方案?如果是这样,你能告诉我们你发现了什么,它是否对你有用,为什么?或许还可以再看看How to Askminimal reproducible example
  • var demonRoutine = StartCoroutine(DemonCharacter()); if (takeDamage) { StopCoroutine(demonRoutine); } 这样的东西可能对你有用。

标签: c# unity3d unity2d


【解决方案1】:

@m.rogalski 建议的另一种方法是使用简单的浮点变量作为计时器:

public GameObject demon;
public BoxCollider2D col;
public Renderer rend;
public ParticleSystem par1;
public static Vector3 target;

private float demonTimer;

void Start()
{
    target = transform.position;
    demonTimer = 0.0f;
}

void Update()
{
    target.z = transform.position.z;

    if (demonTimer > 0.0f)
    {
        demonTimer -= Time.deltaTime;
        if (demonTimer <= 0.0f)
        {
            demon.SetActive(false);
            rend.enabled = true;
            col.enabled = true;
        }
    }
}

public void DemonCharacter()
{
    par1.Play();
    par1.transform.position = target;
    demon.SetActive(true);
    rend.enabled = false;
    col.enabled = false;

    demonTimer = 60.0f;
}

public void CancelDemon()
{
    demonTimer = 0.0f;
}

希望对你有帮助,

【讨论】:

    【解决方案2】:

    我的建议是您将Coroutine 修改为不使用WaitForSeconds,而是使用它自己的计时计算。

    // create the flag indicating interruption
    bool _interrupt = false;
    
    // create your coroutine
    IEnumerator PowerUpCoroutine()
    {
        // set the time you want to hold transformation
        const float TRANSFORMATION_INTERVAL = 60.0f;
    
        // currently elapsed time 
        float currentlyElapsed = 0.0f;
    
        // add your logic for pre-transformation 
    
        while ( currentlyElapsed < TRANSFORMATION_INTERVAL && !_interrupt )
        {
            yield return null;
            currentlyElapsed += Time.deltaTime;
        }
    
        // add post-transformation logic
    
        // revert transformation process
    
        _interrupt = false;
    }
    

    现在,如果你运行这个调用StartCoroutine(PowerUpCoroutine()); 的协程,你可以将_interrupt 标志设置为true 来中断它。例如:

    public void Interrupt()
    {
        _interrupt = true;
    }
    
    // in some update :
    if ( gotHitThisFrame == true )
        Interrupt();
    

    【讨论】:

    • 如果您将 currentElapsed 提升为成员变量并在您的 Interrupt 方法中将 currentElapsed 设置为 TRANSFORMATION_INTERVAL,您甚至可以去掉一个单独的 _interrupt 标志。
    • 感谢您对我的问题的帮助,我真的很感激 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-11
    • 1970-01-01
    • 2017-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多