Confused about waitforsconds and need help with making slowmotion only last for a certain number of seconds and then cool down
So I made a slow motion button, If you press E, time goes to .35 and stuff and then you press T to make it go back to normal (1). I want to make it so when you press E, it makes the game slow to .35 FOR 7 SECONDS and then go back to normal and then you have to wait 60 seconds (OR ON ESCAPE) for it to be available again. My script for the slowmo is this: (C# and the name is PauseGame1) using System.Collections; using System.Collections.Generic; using UnityEngine;
public class PauseGame1 : MonoBehaviour
{
void Update()
{
SlowMo();
}
void SlowMo()
{
if (Input.GetKey(KeyCode.E))
{
Time.timeScale = 0.35f;
Time.fixedDeltaTime = 0.02F * Time.timeScale;
}
if (Input.GetKey(KeyCode.T))
{
Time.timeScale = 1;
Time.fixedDeltaTime = 0.02F * Time.timeScale;
}
else if (Input.GetKey(KeyCode.Escape))
{
Time.timeScale = 1;
Time.fixedDeltaTime = 0.02F * Time.timeScale;
}
}
}
Thanks!
Answer by Davirtuoso · Apr 17, 2017 at 12:19 PM
@BenIV One way would be to make use of Coroutines. They are a nice way of counting time and then performing an action afterwards. This is done through the yield command, and would be done like so:
if (Input.GetKey(KeyCode.E))
{
Time.timeScale = 0.35f;
Time.fixedDeltaTime = 0.02F * Time.timeScale;
StartCoroutine(WaitThenCool(7.0f));
}
Then have your seperate Coroutine in an IEnumerator like so:
IEnumerator WaitThenCool(float waitTime)
{
yield return new WaitForSeconds(waitTime);
// Cooldown script here
}
The only issue is that this time is influenced by Time.timeScale, which means that 7 seconds of wait time here is actually 7 extended seconds in your time-slowed world, This leaves you with two options:
Work out how long 7 seconds is in your time-slowed world and use that (I think it's 2.45, but not sure), or
Rewrite the yield to instead use Time.realtimeSinceStartup to count actual real-world seconds, though it would be slightly more unfriendly.
Of those options, 1 would be the simplest to implement, though you'd need to consider future repercussions if you need to do the same thing again and write a new method that waits another specific amount of time adjusted by the slowed-world issue. 2 would be slightly more unfriendly to write, though once done you could use the same method for any number of waits providing you tell it what to cooldown afterwards.
As for the actual cooldown, you may already have ideas on this, but just in case a simple way of handling it would be having a boolean value, something like 'CanUse', then wrap all your E input code in whether or not this is true. When the ability is cooling down, it would set 'CanUse' to false, wait 60 seconds and then set it to true again. This could also be done using Coroutines so it's more of what i've already said just adjusted.
Hopefully this helps - good luck!
Well first you'd need to define the variable at the top of your class. Something like:
bool CanUse = true;
After that you then put an if statement that checks if CanUse is true, only running the keypress check within it, like so:
If (CanUse == true)
{
if (Input.Get$$anonymous$$ey($$anonymous$$eyCode.E))
{
Time.timeScale = 0.35f;
Time.fixedDeltaTime = 0.02F * Time.timeScale;
CanUse = false;
StartCoroutine(WaitThenCool(2.45f));
}
}
Then within your 'WaitThenCool' coroutine you can call another coroutine the handle the cooldown for you. There is most likely a more efficient way to do this, but as I don't think a single coroutine can be paused twice this is a simple way around it:
IEnumerator WaitThenCool(float waitTime)
{
yield return new WaitForSeconds(waitTime);
Time.timescale = 1;
StartCoroutine(CooldownTimeSlow());
}
IEnumerator CooldownTimeSlow()
{
yield return new WaitForSeconds(60.0f);
CanUse = true;
}
That would then give you code that checks if CanUse is true. If it is, then it waits for a keypress on the E key. When pressed, it sets the timescale to 0.35, sets CanUse to false so the player can't press the key again, and waits for 7 seconds before setting it back to 1. It then runs 'CooldownTimeSlow()' waits 60 seconds, before setting CanUse back to true, allowing the use of the ability again.