- Home /
Using bools in Update function to run code once not consistent
I am trying to run this code:
void CheckIfHit()
{
RaycastHit forwardHit;
float dist;
Vector3 dir;
dist = 2.0f;
dir = transform.forward;
Debug.DrawRay(transform.position, dir * dist, Color.green);
//if the ray forward hits something
if (Physics.Raycast(transform.position, dir * dist, out forwardHit, dist))
{
//if it hits the radiussphere
if (forwardHit.transform.CompareTag("RadiusSphere"))
{
//if not already avoiding radius loop
if (!avoidRadiusLoop)
{
avoidRadiusLoop = true;
//30% chance of avoidance
if (Random.value < 1.0f)
{
Debug.Log("avoiding");
animate.SetBool("Jump", true);
GetComponent<Rigidbody>().AddForce(transform.up * 15.0f, ForceMode.VelocityChange);
}
}
}
}
}
I want my enemy to jump over an object at a 30% (I have it at 100% now for testing) chance. This works mostly but every now and then, the Debug.Log("avoiding")
line will return twice, which makes my enemy jump twice as high in the air... am i missing something or is there a better way of doing this? Thanks
Answer by Eudaimonium · Aug 26, 2015 at 11:31 AM
Actually, disregard my previous answer if you're just looking to quickly fix up your code:
Simply add a 0.2 seconds (or so) of a cooldown after immediate jump.
So, if all the IFs have passed and actor jumps, use AddForce, and set a timer which disables the raycasting for checking isGrounded for some 0.2 seconds (don't forget to also manually set isGrounded = false immediately).
EDIT: Here's your code:
I'm assuming all of this is within the same script: http://pastebin.com/7ZE7GxiB
Thanks for the help, seems to work now anyway :) I'm also intrigued about your other method of checking if a player is grounded as I really wasn't sure the best way to make that check, perhaps i'll play around with it, thanks again :)
Thanks.
You can use the other method in conjunction to this one, simply as another layer of security.
Or not, if this now works as expected, leave it be :D Deal with bugs when they arise, and it's not a complex problem in itself anyway.
Answer by CHPedersen · Aug 26, 2015 at 10:41 AM
There is nothing in your code that reveals how it can run twice, but then again, we can't see the full scope of the variable avoidRadiusLoop. It appears to be a class field declared in the same script as this function? My guess is that it is being set to false unexpectedly elsewhere.
Hi @CHPedersen I have the following function which checks if I am grounded:
void CheckIfGrounded()
{
RaycastHit downwardHit;
float dist;
Vector3 dir;
dist = 0.2f;
dir = new Vector3(0, -1, 0);
//If ray hits something below
if (Physics.Raycast(transform.position + new Vector3(0, 0.1f, 0), dir * dist, out downwardHit, dist))
{
isGrounded = true;
}
else
{
isGrounded = false;
}
}
Then I perform a check in the Update function that says if I am grounded, set the avoidRadiusLoop back to false:
if (isGrounded)
{
avoidRadiusLoop = false;
}
Answer by Eudaimonium · Aug 26, 2015 at 11:14 AM
As per your comment to reply by CHPedersen,
Problem is that you're still to close too the ground in the frame immediately after the jump, so the raycast that determinates if you're grounded still hits.
This is the problem I had when coding my own 3D Physics in XNA framework, in C# from scratch.
Raycasting from actor's feet downward is a horrible way to check if a player is not jumping/flying, I have no idea why everybody uses that.
Best way to do that is to check the actor's vertical speed; in pseudo:
bool isJumping;
bool isFalling;
bool canJump;
if player's vertical speed is positive, player is jumping, and can NOT jump;
if player's vertical speed is negative, player is falling and NOT jumping and can NOT jump;
if player is falling and NOT jumping, AND it's vertical speed is now below some tiny threshold = now the player is NOT falling, is grounded, and CAN jump again.
What if, later, you've implemented a platform feature that allows the user to ride a lift up? Then his vertical speed is positive, but he is not jumping. ;)
I guess it would work if you define the speed as relative to the player's first parent, which is still zero if standing on a moving platform.
Well I guess you'd basically just need an additional check over everything - has the player jumped?
If it's vertical speed is non-zero but the player did NOT yet jump, you can still enable him to do, though I see no reason to jump when riding Z-moving elevators, XY-moving platforms would make more sense; but that would work with my original suggestion anyway.
Your answer
![](https://koobas.hobune.stream/wayback/20220612001502im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Making elevator stop at triggers 0 Answers
Only once in update 1 Answer
can't change bool in update function 1 Answer
activating multiple voids with the same name trough one line 1 Answer
Bool not being re-triggered in FixedUpdate or Update 1 Answer