当玩家被敌人击中时,如何将 yield wait for seconds 设置回 60 秒?
How to set the yield wait for seconds back to 60 seconds when the player gets hit by an enemy?
基本上我想让一个玩家可以在用户按下启动按钮时随意变身为恶魔,但是我希望变身在 60 秒后结束(当变身结束时我希望玩家恢复到他的原始状态)。如果玩家被敌人击中,我还希望转换结束。到目前为止,我已经编写了这段代码并且它可以工作,但是当玩家被敌人击中并且用户决定按下按钮将玩家变回来时,我无法将 yield wait for seconds 重置为 60 秒成恶魔。谁能帮我解决这个问题?
在我的层次结构中,我的玩家是父级,恶魔玩家是子级。附加到玩家的玩家移动脚本以及下面的转换脚本:
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 for seconds。
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;
}
}
我的建议是您将 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();
@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;
}
希望对您有所帮助,
基本上我想让一个玩家可以在用户按下启动按钮时随意变身为恶魔,但是我希望变身在 60 秒后结束(当变身结束时我希望玩家恢复到他的原始状态)。如果玩家被敌人击中,我还希望转换结束。到目前为止,我已经编写了这段代码并且它可以工作,但是当玩家被敌人击中并且用户决定按下按钮将玩家变回来时,我无法将 yield wait for seconds 重置为 60 秒成恶魔。谁能帮我解决这个问题?
在我的层次结构中,我的玩家是父级,恶魔玩家是子级。附加到玩家的玩家移动脚本以及下面的转换脚本:
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 for seconds。
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;
}
}
我的建议是您将 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();
@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;
}
希望对您有所帮助,