- Home /
New question on similar topic
Addforce lasting 1 frame
Edit: (My rigid body settings are as follows - mass = 1 drag = 0 angular drag = 0.05 gravity = yes is kinematic = no interpolate = none collision detection = discrete only constraints on all rotations)
Hello,
I am trying to make a directional air dodge mechanic (like in smash bros) but the force I am adding is only lasting for one frame. This is only happening with my left and right (A and D) inputs. Here is the specific part of the script.
else if (anim.GetBool("IsAirborn") == true && Input.GetKeyDown(KeyCode.I) && NotShielding == true && Input.GetKey(KeyCode.D) && airdodgeamount < 1 && djumping == false)
{
NotShielding = false;
gravity = 0;
anim.SetInteger("AnimParameter", 9);
speed = 30f;
calculatedforce = speed * (50 * mainrb.mass);
mainrb.AddForce(new Vector3(calculatedforce, 0, 0));
coroutine = WaitForAirdodge(0.167f);
StartCoroutine(coroutine);
gravity = 8;
airdodgeamount++;
}
else if (anim.GetBool("IsAirborn") == true && Input.GetKeyDown(KeyCode.I) && NotShielding == true && Input.GetKey(KeyCode.A) && airdodgeamount < 1 && djumping == false)
{
NotShielding = false;
gravity = 0;
anim.SetInteger("AnimParameter", 9);
speed = -30f;
calculatedforce = speed * (50 * mainrb.mass);
mainrb.AddForce(new Vector3(calculatedforce, 0, 0));
coroutine = WaitForAirdodge(0.167f);
StartCoroutine(coroutine);
gravity = 8;
airdodgeamount++;
}
else if (anim.GetBool("IsAirborn") == true && Input.GetKeyDown(KeyCode.I) && NotShielding == true && Input.GetKey(KeyCode.W) && airdodgeamount < 1 && djumping == false)
{
NotShielding = false;
gravity = 0;
anim.SetInteger("AnimParameter", 9);
speed = 0.1f;
calculatedforce = speed * (50 * mainrb.mass) - mainrb.velocity.y;
mainrb.AddForce(new Vector3(0, calculatedforce, 0), ForceMode.Impulse);
coroutine = WaitForAirdodge(0.167f);
StartCoroutine(coroutine);
gravity = 8;
airdodgeamount++;
}
else if (anim.GetBool("IsAirborn") == true && Input.GetKeyDown(KeyCode.I) && NotShielding == true && Input.GetKey(KeyCode.S) && airdodgeamount < 1 && djumping == false)
{
NotShielding = false;
gravity = 0;
anim.SetInteger("AnimParameter", 9);
speed = -0.05f;
calculatedforce = speed * (50 * mainrb.mass) - mainrb.velocity.y;
mainrb.AddForce(new Vector3(0, calculatedforce, 0), ForceMode.Impulse);
coroutine = WaitForAirdodge(0.167f);
StartCoroutine(coroutine);
gravity = 8;
airdodgeamount++;
}
else if (anim.GetBool("IsAirborn") == true && Input.GetKeyDown(KeyCode.I) && NotShielding == true && airdodgeamount < 1 && djumping == false)
{
gravity = 0;
NotShielding = false;
anim.SetInteger("AnimParameter", 9);
calculatedforce = 0 - mainrb.velocity.y;
mainrb.AddForce(new Vector3(0, calculatedforce, 0), ForceMode.Impulse);
coroutine = WaitForAirdodge(0.167f);
StartCoroutine(coroutine);
}
Here is my entire script fixed update script as i have no idea where the problem could be.
void FixedUpdate()
{
Physics.gravity = new Vector3(0, -gravity, 0);
if (touching == true && jumping == false)
{
anim.SetBool("IsAirborn", false);
}
else if (touching == false)
{
anim.SetBool("IsAirborn", true);
}
if (anim.GetBool("IsAirborn") == false && Input.GetKeyDown(KeyCode.I) && NotShielding == true)
{
NotShielding = false;
anim.SetInteger("AnimParameter", 6);
shield.SetActive(true);
coroutine = WaitForShield(0.167f);
StartCoroutine(coroutine);
}
else if (anim.GetBool("IsAirborn") == true && Input.GetKeyDown(KeyCode.I) && NotShielding == true && Input.GetKey(KeyCode.D) && airdodgeamount < 1 && djumping == false)
{
NotShielding = false;
gravity = 0;
anim.SetInteger("AnimParameter", 9);
speed = 30f;
calculatedforce = speed * (50 * mainrb.mass);
mainrb.AddForce(new Vector3(calculatedforce, 0, 0));
coroutine = WaitForAirdodge(0.167f);
StartCoroutine(coroutine);
gravity = 8;
airdodgeamount++;
}
else if (anim.GetBool("IsAirborn") == true && Input.GetKeyDown(KeyCode.I) && NotShielding == true && Input.GetKey(KeyCode.A) && airdodgeamount < 1 && djumping == false)
{
NotShielding = false;
gravity = 0;
anim.SetInteger("AnimParameter", 9);
speed = -30f;
calculatedforce = speed * (50 * mainrb.mass);
mainrb.AddForce(new Vector3(calculatedforce, 0, 0));
coroutine = WaitForAirdodge(0.167f);
StartCoroutine(coroutine);
gravity = 8;
airdodgeamount++;
}
else if (anim.GetBool("IsAirborn") == true && Input.GetKeyDown(KeyCode.I) && NotShielding == true && Input.GetKey(KeyCode.W) && airdodgeamount < 1 && djumping == false)
{
NotShielding = false;
gravity = 0;
anim.SetInteger("AnimParameter", 9);
speed = 0.1f;
calculatedforce = speed * (50 * mainrb.mass) - mainrb.velocity.y;
mainrb.AddForce(new Vector3(0, calculatedforce, 0), ForceMode.Impulse);
coroutine = WaitForAirdodge(0.167f);
StartCoroutine(coroutine);
gravity = 8;
airdodgeamount++;
}
else if (anim.GetBool("IsAirborn") == true && Input.GetKeyDown(KeyCode.I) && NotShielding == true && Input.GetKey(KeyCode.S) && airdodgeamount < 1 && djumping == false)
{
NotShielding = false;
gravity = 0;
anim.SetInteger("AnimParameter", 9);
speed = -0.05f;
calculatedforce = speed * (50 * mainrb.mass) - mainrb.velocity.y;
mainrb.AddForce(new Vector3(0, calculatedforce, 0), ForceMode.Impulse);
coroutine = WaitForAirdodge(0.167f);
StartCoroutine(coroutine);
gravity = 8;
airdodgeamount++;
}
else if (anim.GetBool("IsAirborn") == true && Input.GetKeyDown(KeyCode.I) && NotShielding == true && airdodgeamount < 1 && djumping == false)
{
gravity = 0;
NotShielding = false;
anim.SetInteger("AnimParameter", 9);
calculatedforce = 0 - mainrb.velocity.y;
mainrb.AddForce(new Vector3(0, calculatedforce, 0), ForceMode.Impulse);
coroutine = WaitForAirdodge(0.167f);
StartCoroutine(coroutine);
}
else if (anim.GetBool("IsAirborn") == false && Input.GetKeyDown(KeyCode.W) && NotShielding == true)
{
jumping = true;
anim.SetBool("IsAirborn", true);
anim.SetInteger("AnimParameter", 3);
coroutine = WaitForJump(0.3f);
StartCoroutine(coroutine);
}
else if (anim.GetBool("IsAirborn") == true && Input.GetKeyDown(KeyCode.W) && doublejumpamount < 1f && NotShielding == true)
{
djumping = true;
anim.SetInteger("AnimParameter", 5);
anim.SetBool("IsAirborn", true);
coroutine = WaitForDJump(0.2f);
StartCoroutine(coroutine);
doublejumpamount++;
}
else if (anim.GetBool("IsAirborn") == true && Input.GetKey(KeyCode.S) && NotShielding == true)
{
gravity = 15;
}
else if (Input.GetKey(KeyCode.A) && Input.GetKey(KeyCode.LeftShift) && anim.GetBool("IsAirborn") == false && NotShielding == true)
{
anim.SetInteger("AnimParameter", 2);
transform.eulerAngles = new Vector3(0, 270, 0);
speed = -1;
calculatedforce = speed * (50 * mainrb.mass);
mainrb.AddForce(new Vector3(calculatedforce, 0, 0));
}
else if (Input.GetKey(KeyCode.D) && Input.GetKey(KeyCode.LeftShift) && anim.GetBool("IsAirborn") == false && NotShielding == true)
{
anim.SetInteger("AnimParameter", 2);
transform.eulerAngles = new Vector3(0, 90, 0);
speed = 1;
calculatedforce = speed * (50 * mainrb.mass);
mainrb.AddForce(new Vector3(calculatedforce, 0, 0));
}
else if (Input.GetKeyDown(KeyCode.A) && anim.GetBool("IsAirborn") == false && NotShielding == true)
{
anim.SetInteger("AnimParameter", 1);
transform.eulerAngles = new Vector3(0, 270, 0);
speed = -10;
calculatedforce = speed * (50 * mainrb.mass);
mainrb.AddForce(new Vector3(calculatedforce, 0, 0));
}
else if (Input.GetKeyDown(KeyCode.D) && anim.GetBool("IsAirborn") == false && NotShielding == true)
{
anim.SetInteger("AnimParameter", 1);
transform.eulerAngles = new Vector3(0, 90, 0);
speed = 10;
calculatedforce = speed * (50 * mainrb.mass);
mainrb.AddForce(new Vector3(calculatedforce, 0, 0));
}
else if (Input.GetKey(KeyCode.A) && anim.GetBool("IsAirborn") == false && NotShielding == true)
{
anim.SetInteger("AnimParameter", 1);
transform.eulerAngles = new Vector3(0, 270, 0);
speed = -2;
calculatedforce = speed * (50 * mainrb.mass);
mainrb.AddForce(new Vector3(calculatedforce, 0, 0));
}
else if (Input.GetKey(KeyCode.D) && anim.GetBool("IsAirborn") == false && NotShielding == true)
{
anim.SetInteger("AnimParameter", 1);
transform.eulerAngles = new Vector3(0, 90, 0);
speed = 2;
calculatedforce = speed * (50 * mainrb.mass);
mainrb.AddForce(new Vector3(calculatedforce, 0, 0));
}
else if (Input.GetKey(KeyCode.A) && anim.GetBool("IsAirborn") == true && NotShielding == true)
{
speed = -2;
calculatedforce = speed * (50 * mainrb.mass);
mainrb.AddForce(new Vector3(calculatedforce, 0, 0));
}
else if (Input.GetKey(KeyCode.D) && anim.GetBool("IsAirborn") == true && NotShielding == true)
{
speed = 2;
calculatedforce = speed * (50 * mainrb.mass);
mainrb.AddForce(new Vector3(calculatedforce, 0, 0));
}
else if (Input.GetKey(KeyCode.S) && NotShielding == false)
{
anim.SetInteger("AnimParameter", 8);
shield.SetActive(false);
coroutine = WaitForSpotdodge(0.2f);
StartCoroutine(coroutine);
}
else if (NotShielding == true)
{
anim.SetInteger("AnimParameter", 0);
gravity = 8;
}
else
{
}
if (wanttojump == true)
{
if (Input.GetKey(KeyCode.W))
{
jumping = false;
jumpspeed = 1f;
calculatedforce = jumpspeed * (5 * mainrb.mass) - (mainrb.velocity.y * 1);
mainrb.AddForce(new Vector3(0, calculatedforce, 0), ForceMode.Impulse);
}
else if (!Input.GetKey(KeyCode.W))
{
jumping = false;
jumpspeed = 0.7f;
calculatedforce = jumpspeed * (5 * mainrb.mass) - (mainrb.velocity.y * 1);
mainrb.AddForce(new Vector3(0, calculatedforce, 0), ForceMode.Impulse);
}
anim.SetInteger("AnimParameter", 4);
anim.SetBool("IsAirborn", true);
wanttojump = false;
}
if (resetgravity == true)
{
gravity = 8;
resetgravity = false;
}
if (wanttodjump == true)
{
gravity = 0;
jumpspeed = 1;
calculatedforce = jumpspeed * (5 * mainrb.mass) - (mainrb.velocity.y * 1);
mainrb.AddForce(new Vector3(0, calculatedforce, 0), ForceMode.Impulse);
anim.SetInteger("AnimParameter", 4);
wanttodjump = false;
coroutine = GravityDelay(0.1f);
StartCoroutine(coroutine);
djumping = false;
}
touching = false;
}
Thank you in advance.
Not sure if this is the only issue, but you are setting the force just once after you set NotShielding to false. Not sure what else is happening in the coroutine because I don't see it here, but I imagine that it is just waiting for the given amount of time and then perhaps setting the notShielding to true again. I would suggest adding the force in the coroutine if you want to do it every fixed update (WaitForFixedUpdate());
Cheers
Hey there,
please rework that code.... This might also make you discover that bug...
For example:
When you have a if ... elseif... elseif and in EVERY statement you check for example for NotShielding == true
this is horrible. For once it's difficult to understand, but also performance suffers from this. Divide those statements. Have rather some deeper if/else trees than one if/elseif that is soo long. This will also make it possible that you can delete half of that code. Whenever you have an if/elseif statement where for 2 or more conditions the exact same code is executed this can be done better!
calculatedforce = speed * (50 * mainrb.mass);
mainrb.AddForce(new Vector3(calculatedforce, 0, 0));
Those 2 lines alone are in 10 of those statements. Rework it and people will be more likely to debug this.
Answer by Meishin · May 25, 2019 at 01:56 PM
Hello @DoctorChar,
I'm sorry i'm not going to spot your specific issue but if an action only last 1 step it's usually because you overwrite it the next step (or within the same step).
That being said, in my humble opinion, you need to clean your code first cause it is hardly readable, for examples: - Segment your code more : handle NotShielding == false specific treatment appart from the rest so you don't write it 15 times in the if statements - Factorise your code and give meaning to your code:
for example lines 105 to 164 could be rewrote like below and read must clearer:
else if (NotShielding == true &&
(Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.A) ||
Input.GetKeyDown(KeyCode.D) ||Input.GetKeyDown(KeyCode.A)))
{
handleADMovement();
}
void handleADMovement()
{
float initialSpeedBoost = 5f;
// Handle specific Airborn movement
if (anim.GetBool("IsAirborn"))
{
// Invert Speed depending on A/D key
speed = 2 * (Input.GetKey(KeyCode.A) || Input.GetKeyDown(KeyCode.A)? -1:1);
}
else
{
// Now everything under is not Airborn related
// D Control - to be described
if (Input.GetKey(KeyCode.D) || Input.GetKeyDown(KeyCode.D))
{
transform.eulerAngles = new Vector3(0, 90, 0);
// Add an initial speed boost in case key just pressed
speed = 2 * (Input.GetKeyDown(KeyCode.D) ? initialSpeedBoost : 1f);
}
// A Control - to be described
// Takes precedence over D Key (cf else if statements)
// So if A & D key are pressed simultaneously, only A key will be taken into account
if (Input.GetKey(KeyCode.A) || Input.GetKeyDown(KeyCode.A))
{
transform.eulerAngles = new Vector3(0, 270, 0);
speed = -2 * (Input.GetKeyDown(KeyCode.A) ? initialSpeedBoost : 1f);
}
// Handle Grounded animation and Shift control
// Shift Key control - Set anim 2 and reduce speed to 1/-1
if (Input.GetKey(KeyCode.LeftShift))
{
anim.SetInteger("AnimParameter", 2);
speed = speed / speed;
}
// Set anim 1 - Prob Grounded animation
else
{
anim.SetInteger("AnimParameter", 1);
}
}
// Apply force to rigidbody
calculatedforce = speed * (50 * mainrb.mass);
mainrb.AddForce(new Vector3(calculatedforce, 0, 0));
}
That is some effort man, big respect here! Though i think people should do that on their own to actually have a learning experience from this.
haha yeah i agree tho he/she still has plenty of opportunities to learn ^^
Thank you so much, I often struggle with formatting so I will reorganise my code and then try and find the problem again. This looks like it would have taken a lot of effort, so that was really kind of you to do!
Follow this Question
Related Questions
Why can't i addforce to a rigidbody? 2 Answers
How to move Character with AddForce 1 Answer
AddForce/ForceMode.Impulse 1 Answer
Slowly move a GameObject on 1 axis, then destroy it. 1 Answer
In air movement troubles. 1 Answer