Search code examples
c#unity-game-enginegame-physicsvirtual-reality

Adding "force field" to object in Unity to avoid collider clipping?


I'm making a bow and arrow game in Unity and C# with virtual reality. I want the arrow to rest on the bow's handle before you shoot. Right now I have a box collider on the handle and another collider on the arrow. It works OK, until you push the arrow through the handle. It glitches out for a sec then it just passes through (like a no clip).

In my VR class we learned that you can add a normal force or a "push back force" to an object to keep other objects from passing through it. I don't want this to literally push back the arrow though (that would remove the realism). Is there a way to add a force field to an object? Where other objects are repelled very lightly at all times instead of a one-shot burst of force?

Here's code I've already tried that helps a little but not much. This is a script attached to the bow:

private void OnCollisionEnter(Collision collision) {

    if (collision.gameObject.tag == "Arrow") {
        Rigidbody arrowBody = collision.gameObject.GetComponent<Rigidbody>();
        arrowBody.AddForce(this.transform.TransformDirection(Vector3.left) * 100f);
    }

}

I should probably add that the arrow is held in a "hand" using a fixed joint, so adding a second fixed joint to the bow handle is not an option (the hand's joint ends up failing and the arrow falls to the ground without being held by either joint).


Solution

  • I ended up changing the parent transform of the arrow to the bow upon collision, then letting it go from the controller's fixed joint that was holding it. It binds perfectly now.

    Not much code to provide:

    private void OnCollisionEnter(Collision col)
    {
        if (col.gameObject.tag == "Bow")
        {
                this.transform.parent = col.gameObject.transform;
                GameObject.Find("Controller").GetComponent<FixedJoint>().connectedBody = null;      
        }
    }