0

基本上我想制作一个玩家可以在用户按下开机按钮时随意变身为恶魔,但是我希望转换在 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;
    }
}
4

2 回答 2

3

@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;
}

希望这可以帮助,

于 2017-04-04T12:41:51.340 回答
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());,您可以将其设置_interrupttrue. 例如:

public void Interrupt()
{
    _interrupt = true;
}

// in some update :
if ( gotHitThisFrame == true )
    Interrupt();
于 2017-04-04T12:26:24.123 回答