I'm trying to throw objects the same direction the camera is pointing to (forward), but it is behaving really weird. Objects don't always get thrown forward, sometimes it gets thrown up or towards the player itself (backward). And I don't know why:
Here is a snippet of PickingUp
class:
public float throwForce = 1000f;
...
private void PickUpObject(GameObject pickUpObj)
{
if (pickUpObj.GetComponent<Rigidbody>())
{
heldObj = pickUpObj;
heldObjRb = pickUpObj.GetComponent<Rigidbody>();
heldObjRb.isKinematic = true;
heldObjRb.transform.parent = holdPos.transform;
heldObj.layer = LayerNumber;
Physics.IgnoreCollision(heldObj.GetComponent<Collider>(), player.GetComponent<Collider>(), true);
reticle.color = new Color(1, 1, 1, 0.75f);
reticle.enabled = false;
}
}
void DropObject()
{
//re-enable collision with player
Physics.IgnoreCollision(heldObj.GetComponent<Collider>(), player.GetComponent<Collider>(), false);
heldObj.layer = 0; //object assigned back to default layer
heldObjRb.isKinematic = false;
heldObj.transform.parent = null; //unparent object
heldObj = null; //undefine game object
reticle.color = new Color(1, 1, 1, 0.75f);
reticle.enabled = true;
}
void ThrowObject()
{
//same as drop function, but add force to object before undefining it
Physics.IgnoreCollision(heldObj.GetComponent<Collider>(), player.GetComponent<Collider>(), false);
heldObj.layer = 0;
heldObjRb.isKinematic = false;
heldObj.transform.parent = null;
Vector3 camerDirection = camera.transform.forward;
heldObjRb.AddForce(camerDirection * throwForce);
// heldObjRb.constraints = RigidbodyConstraints.None;
heldObj = null;
reticle.color = new Color(1, 1, 1, 0.75f);
reticle.enabled = true;
}
All objects have Rigidbody and colliders attached to them. I get the same issue when dropping the objects too.
CodePudding user response:
Try specifying the force mode as impulse on the AddForce method. The default is acceleration which can often require unreasonable large numbers to get the desired effect.
heldObjRb.AddForce(camerDirection * throwForce, ForceMode.Impulse);
A lot of people pointed out that your issue might be collision between the pickupobject and the players collider. You're using a method that tells the physics engine to ignore the collisions that I'm not familiar with, but should be fine to use for your purpose. I would suggest enabling the collision after a short time delay, so the object has enough time to escape the players collider. You can do so with an invoke.
void ThrowObject()
{
//same as drop function, but add force to object before undefining it
heldObj.layer = 0;
heldObjRb.isKinematic = false;
heldObj.transform.parent = null;
Vector3 camerDirection = camera.transform.forward;
heldObjRb.AddForce(camerDirection * throwForce, ForceMode.Impulse);
// heldObjRb.constraints = RigidbodyConstraints.None;
reticle.color = new Color(1, 1, 1, 0.75f);
reticle.enabled = true;
Invoke("ResetCollision", 0.5f);//can be adjusted
}
public void ResetCollision(){
Physics.IgnoreCollision(heldObj.GetComponent<Collider>(), player.GetComponent<Collider>(), false);
heldObj = null;
}