- Home /
Problem is not reproducible or outdated
Unity 2d Physics Collision Jumping / Glitching
I'm having trouble with a rotating canister object colliding with static box collider objects. Basically, I'm trying to replicate in 2D those explosive gas canisters from Half-Life 2 that push themselves around via escaping gas resulting in much hilarity and hi-jinx.
The canister is a 2d box collider with continuous collision detection enabled and a 2d rigid body and the background objects are static 2d box colliders. I'm using body.AddForceAtPosition(-gasEscapePosition * gasLeakForce, gasEscapePosition) to move the object around in FixedUpdate.
When the canister collides with any walls, its causing the object to jump for a frame and looks terrible. This has only been a problem since I started using AddForceAtPosition instead of AddForce.
Here is a gif of it jumping around: image link
Also, here is the movement code:
 using UnityEngine;
 
 public class CanisterHealth : Health
 {
     public override float maxHealth { get { return 30.0f; } set { } }
     public override float drain { get { return 0.0f; } }
 
     // Canister Variables
     public bool gasLeak = false;
     public float gasLeakForce;
     public float explosionDelay;
     public float timeToDie;
     public Vector2 gasEscapePosition;
     public float gasEscapeOffSet;
 
     // Vacuum variables
     public GameObject gasLeakParticles;
 
     /* Cached components */
     [HideInInspector] public Rigidbody2D body;
 
 
     public void Start()
     {
         // Cache component lookups
         body = GetComponent<Rigidbody2D>();
     }
 
     private void Update()
     {
         if (gasLeak && Time.time > timeToDie) Explode();
     }
 
     private void FixedUpdate()
     {
         if (gasLeak) GasLeak();
     }
 
     // Decrement the props's health by amount and set color
     public override void Damage(float amount, ContactPoint2D contactPoint)
     {
         // Flash body if damaged to give feedback
         if (health > 0)
         {
             if (!flashing) StartCoroutine(Flash());
             health -= amount;
         }
 
         // Flash body and reduce time to die if already leaking
         else if (gasLeak)
         {
             if (!flashing) StartCoroutine(Flash());
             timeToDie -= amount * 0.1f;
         }
 
         // Start gas leak
         else if (health <= 0 && !gasLeak && canDie)
         {
             Dying(contactPoint);
         }
     }
 
     public void Dying(ContactPoint2D contactPoint)
     {
         if (gasLeakParticles)
         {
             // Create gas escape position and direction
             gasEscapePosition = contactPoint.normal;
             float targetAngle = (Mathf.Atan2(gasEscapePosition.y, gasEscapePosition.x) * Mathf.Rad2Deg) + gasEscapeOffSet;
             Quaternion rotation = Quaternion.AngleAxis(targetAngle, Vector3.forward);
 
             // Create gas VFX and add as child of canister object so they remain attached
             GameObject vfx = Instantiate(gasLeakParticles, contactPoint.point, rotation) as GameObject;
             vfx.transform.parent = tr;
         }
 
         gasLeak = true;
         timeToDie = Time.time + explosionDelay;
     }
 
     private void Explode()
     {
         // Create delayed explosion and vacuum if an outside wall
         if (explosion != null) Instantiate(explosion, tr.position, Quaternion.identity);
 
         // Kill the poor object - :(
         Destroy(this.gameObject);
     }
 
     private void GasLeak()
     {
         // Add blow force from escape point
         body.AddForceAtPosition(-gasEscapePosition * gasLeakForce, gasEscapePosition);
     }
 }
 
Any ideas as to why?
Rigidbody2D.AddForceAtPosition uses world-space as the position. Your usage seems very odd in that you're using some world-space position * gasLeakForce as the force. Are you mixing-up world/local-spaces?
You can convert between global and local-spaces using Rigidbody2D.GetRelativePoint and Rigidbody2D.GetPoint.
Already solved this while I was waiting for it to be approved. It was a world and local space mix-up, yeah.
Thanks anyway $$anonymous$$elv.
 koobas.hobune.stream
koobas.hobune.stream 
                       
                
                       
			     
			 
                