i click a button, my player performs a ground pound, if in contact with an enemy, time slows down for 3 seconds and the player chooses a direction, then time reverts to normal and the player goes FLYYING in the direction they chose until they hit a wall.
In the code below → the coroutine is called and all debug logs player however… when ground pounding an enemy, time does slow down but — my player doesnt move at all when choosing the direction and my players gravity doesnt revert after touching the ground
just wondering if there are any issues with my code - all values are set properly in inspector:
Sounds like there is… in fact, it sounds like you wrote a bug… and that means… time to start debugging!
By debugging you can find out exactly what your program is doing so you can fix it.
Use the above techniques to get the information you need in order to reason about what the problem is.
You can also use Debug.Log(...); statements to find out if any of your code is even running. Don’t assume it is.
Once you understand what the problem is, you may begin to reason about a solution to the problem.
NOTE: while you CAN do this with coroutines, it’s probably not the best approach. Another approach is to set some boolean flags to change how your code works during this effect, along with a simple float timer; that counts down during the effect. This gives you a far simpler piece of code to debug, since only one thing would ever happen at a time, whereas coroutines give the illusion of multiple things going at once. With coroutines, what you’re doing outside and inside the coroutine must be reasoned about to think how they might interact against each other.
I have a few suggestions, but I think you’ll need to add some more information in your Debug.Log statements to see what is happening.
I don’t think “yield return endShineSpark == true” does what you think it does. This is essentially the same as saying “yield return false”. This is not going to dynamically change when endShineSpark changes. This is probably why you don’t see the gravity return to normal. This is where Kurt’s suggestion of tracking the shine spark state in the main loop may be easier. If the player is currently in the shinespark state and they hit the ground, then you could call a new method to reset the state as expected.
If you have any other movement code which is modifying the RigidBody2D’s velocity every frame, then it will override any velocity change you tried to apply with the rb.AddForce. You may need to inhibit player input while the object is traveling under the shinespark effect.
It may be a good idea to test in an isolated environment whether the amount of force you are applying results in the desired final velocity.
Your coroutine only samples the player input once at the time that it is called. You need to be pressing the desired direction as you hit the target object, you can’t press the direction during the slowed time. If you print out inputDir you can see if the direction is being captured correctly.
So i took your advice and many parts worked but some didn’t. Now my character will pause all movement, slow time/gravity and a force will act upon him until he touches the ground. However he will only travel directly to the right… my character won’t move if i input anything else, so it only reponds if i choose directly right and then my character will launch to the right? ive attempted fiddling with the rb.addforce function by flipping inputdirx and inputdiry but it just causes the inputs to be switched and my character will then only go flying upwards?? Just can’t seem to find the bug with my directional input code??
Aside from that everything else works - my gravity and timescale do return when grounded
private void OnTriggerEnter2D(Collider2D _other) //for up and down cast spell
{
if (_other.GetComponent<Enemy>() != null && pState.casting)
{
_other.GetComponent<Enemy>().EnemyHit(spellDamage, (_other.transform.position - transform.position).normalized, -recoilYSpeed);
}
if (_other.tag == "Shinespark" && canShineSpark)
{
goShineSpark = true;
}
if (_other.tag == "Shinespark" && canShineSpark)
{
goShineSpark = true;
if (Input.GetKey(KeyCode.UpArrow)) inputDir.y += 1;
if (Input.GetKey(KeyCode.DownArrow)) inputDir.y -= 1;
if (Input.GetKey(KeyCode.LeftArrow)) inputDir.x -= 1;
if (Input.GetKey(KeyCode.RightArrow)) inputDir.x += 1;
StartCoroutine(ShineSpark());
Debug.Log("can shinespark");
}
}
IEnumerator ShineSpark()
{
if (goShineSpark)
{
rb.velocity = Vector2.zero;
rb.gravityScale = 0;
Time.timeScale = 0.1f;
Debug.Log("chhose shinsepak dir");
yield return new WaitForSeconds(0.2f);
Time.timeScale = 1;
rb.AddForce(new Vector2(inputDir.x, inputDir.y) * shineSparkSpeed, ForceMode2D.Impulse);
Debug.Log("shinespark fly");
if (Grounded())
{
canShineSpark = false;
rb.velocity = Vector2.zero;
rb.gravityScale = gravity;
goShineSpark = false;
Debug.Log("shinespark wns");
}
}
}
Do you ever reset the value of inputDir? From the code you have shared, you only add or subtract values each time a shinespark event occurs.
I think it would be very helpful for you to print out the value of inputDir just before AddForce to see if it has the value you expect.
Debug.Log("inputDir = " + inputDir);
I’m not sure what the Grounded() code in your coroutine is intended to do. This is only going to be checked one time immediately after AddForce happens (and before the player has even been moved by that force at all). Do you have this some code somewhere else that is used to restore gravity?
OK so ive made alot of progress. This is what happens now:
I ground pound, hit an enemy, time slows and allows me to choose aa direction, i will now fly in that choseen direction. There’s only 1 main issue → im not sure my gravity ever goes to 0 despite me putting it EVERYWHERE. Since when i try to shinespark to the right or left, my character won’t fly straight, they will fly in a falling curve (due to effects of gravity).
It may help to add unique Debug.Log statements at every place where gravity is changed. That may help you see when the gravity is changing to 0 and when it is changing back to normal. You could even include Time.time (or Time.unscaledTime) in the print to better understand the timeline of events after the fact. For example:
Debug.Log("ShineSpark() setting gravity to 0 at time " + Time.time);
When is ChooseDir() called? Is it during Update()?