0

I have a trigger collider on my right Vive controller that detects when an "Enemy"-tagged gameobject is within grab range. To create a 'grab,' I add a FixedJoint component to the controller with the Enemy gameobject as the connectedBody. Upon release of the grip, I set connectedBody = null and Destroy(joint) (where joint is the FixedJoint). Whenever I release the selectedObj it falls to the ground with zero velocity. What gives?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Grab : MonoBehaviour {
    private GameObject selectedObj;
    private GameObject grabbableEnemy;
    public Transform gripTransform;
    private SteamVR_TrackedObject trackedObject;
    private SteamVR_Controller.Device _controllerDevice;
    private SteamVR_TrackedController _controller;

    private Vector3[] positions = new Vector3[2]; // positions[0] last frame, positions[1] this frame;
    private Vector3 releasedVelocity;

    void Awake()
    {
        trackedObject = GetComponent<SteamVR_TrackedObject>();
    }

    // Use this for initialization
    void Start () {
        _controllerDevice = SteamVR_Controller.Input((int)trackedObject.index);
        _controller = GetComponent<SteamVR_TrackedController>();
        positions[0] = Vector3.zero;
        positions[1] = Vector3.zero;
        releasedVelocity = new Vector3(-99,-99,-99);

        selectedObj = null;
        grabbableEnemy = null;
    }

    // Update is called once per frame
    void FixedUpdate () {
        if (selectedObj)
        {
            Debug.Log("Updating velocity");
            positions[0] = positions[1];
            positions[1] = selectedObj.transform.position;
            Debug.Log("Selected obj velocity: " + selectedObj.GetComponent<Rigidbody>().velocity);
        }
        if (_controllerDevice.GetPressDown(SteamVR_Controller.ButtonMask.Grip))
        {
            Debug.Log("Gripped");
            if (grabbableEnemy)
            {
                Debug.Log("Grab sequence begins");
                selectedObj = grabbableEnemy;
                Debug.Log(selectedObj.name);
                selectedObj.transform.position = gripTransform.position;
                var joint = gameObject.AddComponent<FixedJoint>();
                joint.connectedBody = selectedObj.GetComponent<Rigidbody>();
            }
        }
        if (_controllerDevice.GetPressUp(SteamVR_Controller.ButtonMask.Grip))
        {
            Debug.Log("Ungripped");
            if (gameObject.GetComponent<FixedJoint>() && selectedObj)
            {
                Debug.Log("Launch sequence begins");
                // currently unused velocity value
                releasedVelocity = (positions[1] - positions[0]) / Time.deltaTime;

                foreach (FixedJoint joint in gameObject.GetComponents<FixedJoint>()) {
                    joint.connectedBody = null;
                    Destroy(joint);
                }
                selectedObj.GetComponent<Rigidbody>().velocity = gameObject.GetComponent<Rigidbody>().velocity;
                selectedObj.GetComponent<Rigidbody>().angularVelocity = gameObject.GetComponent<Rigidbody>().angularVelocity;

                Debug.Log("Released @ release: " + selectedObj.GetComponent<Rigidbody>().velocity);

                // For garbage collection?
                selectedObj = null;      
            }
        }
    }

    private void OnTriggerStay(Collider other)
    {
        Debug.Log("Triggered");
        if (other.gameObject.tag == "Enemy")
        {
            grabbableEnemy = other.gameObject;
        }
    }

    private void OnTriggerExit(Collider other)
    {
        grabbableEnemy = null;
    }
}
derHugo
  • 83,094
  • 9
  • 75
  • 115
AlleyOOP
  • 1,536
  • 4
  • 20
  • 43
  • By the way, `selectedObj = null;` doesn't help with GC. The object still exists. But this is still fine as the script *should* "forget" about a thrown object. But memory is not impacted at all by the `=null`. However, if it was a local variable, it would be GC'd anyway. – Draco18s no longer trusts SE Jul 06 '17 at 19:39

1 Answers1

1

You're calculating releasedVelocity but never setting anything to use its value.

You have:

selectedObj.GetComponent<Rigidbody>().velocity = gameObject.GetComponent<Rigidbody>().velocity;

but this will only set the velocity to the velocity of the GameObject your script is attached to. I'm guessing you wanted to do:

selectedObj.GetComponent<Rigidbody>().velocity = releasedVelocity;
Foggzie
  • 9,691
  • 1
  • 31
  • 48