在手之间移动物体

时间:2018-05-23 21:57:05

标签: c# unity3d virtual-reality htc-vive

基本上,我正试图在目前功能齐全的两只“手”之间移动一个物体。我可以在房间空间内旋转地拾取物体并操纵它们。

但是,我遇到的问题是在控制器之间传输对象 我可以将物体交给另一只手,但是如果我放开原始手上的触发器,物体就会变成非运动物并掉回地板。

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

public class HandGrab : MonoBehaviour
{
    // Variable for Controller button register
    public string buttonName;

    // Allows objects to be transferred between hands
    public HandGrab secondaryHandRef;

    // Determines the referenced object type
    public XRNode nodeType;

    // This affects the distance of object grab from controller
    public Vector3 objectGrabOffset;

    // Default grab distance relative to the controller, (Where the collider sphere is) This can be changed to affect the visuals and where the items get manipulated from
    public float grabDistance = 0.1f;

    // Force at which an object is thrown
    public float throwingMultiplier = 1.5f;

    // To determine if object has been grabbed or cant be grabbed
    public string grabName = "Grabbing";

    // Stores the values of the currently grabbed object
    public Transform CurrentGrabObject
    {
        get { return _currentlyHeldObject; }
        set { _currentlyHeldObject = value; }
    }

    // Does as it says and stores the last frame and is used to work out velocity calculations
    private Vector3 _lastFramePosition;

    // Determines the transform values for the currently selected objects
    private Transform _currentlyHeldObject;

    // bolean to determine if an object is currently being held
    private bool _isHeld;

    // *Hopefully gets the roation of the controllers and matches that to the roation of the item*
    // *private Transform _objectRotation;*

    // Use this for initialization
    void Start()
    {
        // Clearing all variables back to zero
        _currentlyHeldObject = null;
        _lastFramePosition = transform.position;
        _isHeld = false;

        // Determining the tracking space available
        XRDevice.SetTrackingSpaceType(TrackingSpaceType.RoomScale);
    }

    // Update is called once per frame

    void Update()
    {
        // rotation and position tracking. Updates every frame, should be 90fps

        transform.localPosition = InputTracking.GetLocalPosition(nodeType);
        transform.localRotation = InputTracking.GetLocalRotation(nodeType);

        // Check the object in hand variable. If hand is empty, check to see if we can pick anything up (Object highlight posibilites)

        if (_currentlyHeldObject == null)
        {
            // Check to see if there are any colliders in the proximity of hands

            Collider[] colliders = Physics.OverlapSphere(transform.position, grabDistance);
            if (colliders.Length > 0)
            {
                // If there is a collision, then pickup the object if we press the grab button and give it the tag "Grabbing"

                if (Input.GetAxis(buttonName) >= 0.5F && colliders[0].transform.CompareTag(grabName))
                {
                    // Now we set to grabbing to true

                    if (_isHeld)
                    {
                        return;
                    }
                    _isHeld = true;

                    // Sets the current object to the object we have just picked up and binds it as a child object (this should allow all rotation to mimic the hands)

                    colliders[0].transform.SetParent(transform);

                    // If there is no RigidBody attached to the current object, then assign it a RigidBody variable

                    if (colliders[0].GetComponent<Rigidbody>() == null)
                    {
                        colliders[0].gameObject.AddComponent<Rigidbody>();
                    }

                    // Disable all physics on the grabbed object until it is released (May need to change if we want to enable objects to be swung and hit other "live objects")

                    colliders[0].GetComponent<Rigidbody>().isKinematic = true;

                    // Save the current object for a reference later

                    _currentlyHeldObject = colliders[0].transform;

                    // If other hand grabs the object, then release the object to be able to be re-parented above

                    if (secondaryHandRef.CurrentGrabObject != null)
                    {
                        secondaryHandRef.CurrentGrabObject = null;
                    }
                }
            }
        }
        else
        // We must now have an object in our hand at this point. We now update its current position to the current hand poistion + the offset definded above

        {
            //If we release the grab button, we drop the object here
            if (Input.GetAxis(buttonName) < 0.1f)
            {

                // Return the value of the object back to Non-Kinematic and re-enable physics
                Rigidbody _objectRB = _currentlyHeldObject.GetComponent<Rigidbody>();
                _objectRB.isKinematic = false;
                _objectRB.collisionDetectionMode = CollisionDetectionMode.Continuous;

                // Fun stuff starts here, we now calculate the hands current velocity
                Vector3 velocity = (transform.position - _lastFramePosition) / Time.deltaTime;

                // We now set that object velocity to the current velocity of the hand (I may adjust this to improve physics simulation)
                _objectRB.velocity = velocity * throwingMultiplier;

                // Kill the reference and revert the hands back to being empty and remove its parent
                _currentlyHeldObject.SetParent(null);
                _currentlyHeldObject = null;
            }
        }

        //Release the grab function
        if (Input.GetAxis(buttonName) < 0.5f && _isHeld)
        {
            _isHeld = false;
        }

        // Store the current position of the hand for velocity calculation in the upcoming frame
        _lastFramePosition = transform.position;

        //Tying off all loose ends here
    }
}

1 个答案:

答案 0 :(得分:1)

在您的更新功能中:

function GetActiveRow() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var s = ss.getActiveSheet();
  var range = s.getActiveRange();
  var row = range.getRow(); 
  var values = s.getRange( row + ':' + row ).getValues();  
  s.getRange('A1').offset(0, 0, 1, values[0].length).setValues(values);
}