Hi all I encountered a strange behaviour that maybe someone can help me understand.
I have a player that I can move aruond (player has rigid body non kinematic) and I want to implement a simple trap that when the player hit bounces him back and damage him.
The problem is:
the first AddForce works only if I add another one after it
if I use only the second AddForce it works fine alone
if I use only the first AddForce it doesn’t work and the player stay still in position
if I use both of the AddForce the second one is not performed but the first one is performed
private void OnCollisionEnter(Collision collision)
{
GameObject other = collision.gameObject;
if(other.tag == "Player")
{
Vector3 playerPos = other.transform.position;
Vector3 trapPos = transform.position;
Vector3 pushForceDirection = playerPos - trapPos; // evaluate push dir
Rigidbody playerRB = other.GetComponent<Rigidbody>();
if (playerRB)
{
playerRB.AddForce(pushForceDirection * 100, ForceMode.Impulse); // this is what i want
playerRB.AddForce(Vector3.up * 100, ForceMode.Impulse); // this is for test
}
else
{
Debug.LogError("No rigidbody found on player");
}
}
}
I wouldn’t put AddForce() within OnCollisionEnter().
Instead, raise some flag and store the relevant data in class variables (i.e. resolveCollision = true, otherObject = collision.gameObject). Then check for that flag within FixedUpdate(). If the flag is true, then resolve the collision, apply AddForce(), and clear the flag (resolveCollision = false), everything within FixedUpdate().
I checked the values and the vector is always not zero
Isn’t this polling system more computationally expensive??
Why you wouldn’t put AddForce() whitin OnCollisionEnter()?? (this question may be very basic but I would learn if there is something that I don’t know)
No, it’s just checking for a bool. That doesn’t have any impact.
Because OnCollisionEnter() might be called several times per physics update depending of the situation. For example, if the object collides with two other objects simultaneously. With the approach I suggested you ensure that a collision raises exactly one AddForce() per physics update, regardless the number of colliders or any other possible corner cases.
@Edy Thanks for your replies and suggestions. I tried implementing what you suggested but I still have the same problem.
I’m going to leave here a copy of the project so if someone want is free to see the problem in action and maybe the solution is easier to solve like this. Also maybe I’m making a noob error that is in another part of the project.
[Project File]
[Instructions]
To replicate the problem just go on “RazorTrap” script and try comment the AddForce on the up vector
Whenever you multiply a direction by some scalar value you probably want to make sure it is normalized first. This bit of code: pushForceDirection * 100 will produce unpredictable results unless you normalize pushForceDirection. See Unity - Scripting API: Vector3.Normalize
I can imagine a situation where the impulse you assign as a result of this non-normalized calculation is small enough to the point where ground friction just absorbs all of it. That would explain why giving another impulse in the upward direction suddenly solves it - because then the character lifts off the ground and there is no more friction to eat horizontal movement.