J'ai un collisionneur de déclencheur sur mon contrôleur droit de Vive qui détecte quand un gameobject "Enemy
" -tagged est dans la portée de saisie. Pour créer un "grab", j'ajoute un composant FixedJoint
au contrôleur avec l'objet game Enemy comme connectedBody
. Lors de la libération de la poignée, j'ai réglé connectedBody = null
et Destroy(joint)
(où joint est le FixedJoint). Chaque fois que je relâche le selectedObj
, il tombe au sol avec une vitesse nulle. Ce qui donne?SteamVR GameObject rigidbody libéré de grab avec la vitesse zéro
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;
}
}
Par ailleurs, 'selectedObj = null;' n'aide pas avec GC. L'objet existe toujours. Mais c'est toujours correct car le script * devrait * "oublier" un objet projeté. Mais la mémoire n'est pas affectée du tout par le '= null'. Cependant, s'il s'agissait d'une variable locale, ce serait GC'd de toute façon. – Draco18s