[英]How do I use a timer and or a do while loop to make labels show up for a certain amount of time
[英]How to make a Power Up last for a certain amount of time after collision?
我正在制作一个怪异的小跑步游戏,并且尝试添加一种加电功能,使玩家可以跳跃一小段时间(也许10秒)。
using UnityEngine;
public class PlayerCollision : MonoBehaviour {
public PlayerMovement movement;
public GameObject PowerUp;
public float jumpUpForce = 5000f;
public float jumpBackForce = 1000f;
public Rigidbody rb;
void OnCollisionEnter(Collision collisionInfo)
{
if (collisionInfo.collider.tag == "Obstacle")
{
movement.enabled = false;
}
if (collisionInfo.collider.tag == "PowerUp")
{
PowerUp.SetActive(false);
JumpPower();
}
}
void JumpPower()
{
if (transform.position.y < 2)
{
if (Input.GetKey("left shift"))
{
rb.AddForce(0, jumpUpForce * Time.deltaTime, -jumpBackForce * Time.deltaTime);
}
}
}
我知道问题在于,当玩家与加电碰撞并运行JumpPower()函数时,它仅调用一次,因此无法检测到按下的左移行为(我认为)。
任何帮助表示赞赏。
您可以使用协程。 每次上电时,您都将取消已经存在的协程(如果存在)并开始新的协程,这将处理时间。 这是用我的方式来做的:
public PlayerMovement movement;
public GameObject PowerUp;
public float jumpUpForce = 5000f;
public float jumpBackForce = 1000f;
public Rigidbody rb;
bool doWeHaveJumpPowerUp;
Coroutine cor;
public float timer;
// Use this for initialization
void Start()
{
doWeHaveJumpPowerUp = false;
timer = 10.0f;
}
void OnCollisionEnter(Collision collisionInfo)
{
if (collisionInfo.collider.tag == "Obstacle")
movement.enabled = false;
if (collisionInfo.collider.tag == "PowerUp")
{
PowerUp.SetActive(false);
if(cor != null)
{
StopCoroutine(cor);
cor = null;
}
cor = StartCoroutine(JumpPower());
}
}
IEnumerator JumpPower()
{
doWeHaveJumpPowerUp = true;
yield return new WaitForSeconds(timer);
doWeHaveJumpPowerUp = false;
}
// Update is called once per frame
void Update()
{
if (doWeHaveJumpPowerUp)
if (transform.position.y < 2)
if (Input.GetKey("left shift"))
rb.AddForce(0, jumpUpForce * Time.deltaTime, -jumpBackForce * Time.deltaTime);
}
编辑:如果您想要更多类型的电源,这就是您想要添加它们的方式:
public PlayerMovement movement;
public GameObject PowerUp;
public float jumpUpForce = 5000f;
public float jumpBackForce = 1000f;
public Rigidbody rb;
bool doWeHaveJumpPowerUp;
Coroutine cor;
public float timer;
// 2nd power up
bool doWeHaveFlyPowerUp;
// Use this for initialization
void Start()
{
doWeHaveJumpPowerUp = false;
timer = 10.0f;
}
void OnCollisionEnter(Collision collisionInfo)
{
if (collisionInfo.collider.tag == "Obstacle")
movement.enabled = false;
if (collisionInfo.collider.tag == "PowerUpJump")
{
PowerUp.SetActive(false);
if (cor != null)
{
StopCoroutine(cor);
cor = null;
}
cor = StartCoroutine(JumpPower());
}
if (collisionInfo.collider.tag == "PowerUpFly")
{
PowerUp.SetActive(false);
if (cor != null)
{
StopCoroutine(cor);
cor = null;
}
cor = StartCoroutine(FlyPower());
}
}
IEnumerator JumpPower()
{
doWeHaveJumpPowerUp = true;
yield return new WaitForSeconds(timer);
doWeHaveJumpPowerUp = false;
}
IEnumerator FlyPower()
{
doWeHaveFlyPowerUp = true;
yield return new WaitForSeconds(timer);
doWeHaveFlyPowerUp = false;
}
// Update is called once per frame
void Update()
{
if (doWeHaveJumpPowerUp)
if (transform.position.y < 2)
if (Input.GetKey("left shift"))
rb.AddForce(0, jumpUpForce * Time.deltaTime, -jumpBackForce * Time.deltaTime);
if (doWeHaveFlyPowerUp)
{
//Fly power up logic
}
}
在这两个示例中,上电会取消已经存在的上电。 您应该计划上电的工作方式:
另外,此时您将只能进行一次通电。 如果您想要更多,则必须为它们编写一个生成器(如果您希望它们是随机的),或者如果您希望它们按某种顺序排列,请手动放置它们。
我不熟悉Unity编码,但是对于您要完成的工作,听起来好像您需要运行一个Timer。
我通常将以下代码放在Form.Load()中,但是,由于这不是实际的winforms应用程序,因此您可能会更好地知道在运行时将其放置在何处。
int t = 0; // Add this as a variable within the class to provide sufficient scope
Timer power_up_timer = new Timer();
power_up_timer.Interval = 1000; // 1000 ms = 1 second
power_up_timer.Tick += power_up_timer_Tick;
然后在班级内的任何地方添加Tick事件:
private void power_up_timer_Tick(object sender, EventArgs e)
{
if (t == 10) { /* End the power-up */ t = 0; power_up_timer.Stop(); }
else { t++; }
}
然后,在加电初始化块中添加:
power_up_timer.Start();
但是,您可以在代码中得到解决,这几乎就是它的完成方式。
您还可以运行协程!
// action is just a function or a method
// if you need that with arguments it would be System.Action< T > action
IEnumerator TimerRoutine(int seconds, System.Action action)
{
int sec = 0;
float delta = 0;
while (true)
{
delta += Time.deltaTime;
Debug.Log(delta);
if(delta >= 1f)
{
sec += 1;
delta = 0;
}
if (sec == seconds)
break;
else
yield return null;
}
// this will start your function at the end of the timer
action();
}
您可以调用StartCoroutine(TimerRoutine(args))从任何MonoBehaviour启动计时器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.