1
votes

I'm having trouble with applying relative-force to a pooled object.

I have an object-pool that has all my bullets ready for re-use. The bullets are disabled while not in use.

when a player shoots his weapon, a bullet is pulled from the objectpool and the following is done on the bullet, in this order:

  • SetActive(true)
  • transform.position = bulletSpawnPosition
  • transform.rotation = rotation of the gun/barrel
  • RigidBody.AddRelativeForce(Vector3.forward * speed, ForceMode.Impulse)

This works correct for just one player. When I have another player who also pulls bullets from the objectpool, the bullet seems to keep the rotation of the previous player, so the force is added in the wrong direction.

One thing that I can/could do, is wait for the next frame, between setting the rotation and applying the relative-force, but that feels wrong. Am i missing something? The code below is slightly modified, but narrows down to what's happening.

function Shoot() {
    GameObject poolObject = GetObjectFromPool();
    poolObject.SetActive(true);
    poolObject.transform.position = transform.position;
    poolObject .transform.rotation = transform.rotation;

    if (poolObject != null)
    {
        //add force
        Rigidbody rBody = poolObject.GetComponent<Rigidbody>();
        rBody.AddRelativeForce(Vector3.forward * ProjectileSpeed.Value, ForceMode.Impulse);
    }
}
2
see the answer below, i did that, and had nothing to do with this problem. I reset the velocity and angularVelocity when the bullet is disabled and marked for re-use. The code shows the use of the bullet, not the resetting. setting a new position and rotation is not something i want to do on resetMarijn

2 Answers

2
votes

Always reset items from a pool before using them again. Have a function for each type of Object in a pool that you can easily call to reset them. Since the bullet has a Rigidbody attached to it and is still moving when you take it from the pool, simply reset the velocity and the angularVelocity too just in-case it is still rotating. You do that by setting them to Vector3(0, 0, 0);. The Vector3.zero property is a shortcut for new Vector3(0, 0, 0); and should be used here.

This should do it:

public void resetPool(Rigidbody rg)
{
    rg.velocity = Vector3.zero;
    rg.angularVelocity = Vector3.zero;
}
1
votes

I found the problem, it has to do with calling SetActive before setting the position and rotation:

this causes issues:

 poolObject.SetActive(true);
 poolObject.transform.position = transform.position;
 poolObject .transform.rotation = transform.rotation;

while this works:

  poolObject.transform.position = transform.position;
  poolObject .transform.rotation = transform.rotation;
  poolObject.SetActive(true);