예제 #1
0
        public virtual void Place(Grabbable placeObj)
        {
            originParent = placeObj.transform.parent;
            placeObj.transform.parent        = transform;
            placeObj.transform.localPosition = offset;
            placeObj.transform.localRotation = Quaternion.identity;
            placeObj.body.isKinematic        = makeKinematic;

            if (jointLink != null && joint == null)
            {
                joint = jointLink.gameObject.AddComponent <FixedJoint>();
                joint.connectedBody = placeObj.body;
                joint.breakForce    = jointBreakForce;
                joint.breakTorque   = jointBreakTorque;

                joint.connectedMassScale  = 1;
                joint.massScale           = 1;
                joint.enableCollision     = false;
                joint.enablePreprocessing = false;
            }

            occupied     = true;
            placedObject = placeObj;
            OnPlace?.Invoke();
        }
예제 #2
0
        void Update()
        {
            if (EditorApplication.isPlaying)
            {
                return;
            }

            if (editorGrabbable != null)
            {
                if (lastEditorGrabbable != editorGrabbable)
                {
                    if (lastEditorGrabbable != null)
                    {
                        Remove(lastEditorGrabbable);
                        lastEditorGrabbable.transform.position = preEditorPos;
                    }

                    preEditorPos = editorGrabbable.transform.position;
                }
                else
                {
                    originParent = editorGrabbable.transform.parent;
                    editorGrabbable.transform.parent        = transform;
                    editorGrabbable.transform.localPosition = offset;
                    editorGrabbable.transform.localRotation = Quaternion.identity;
                    editorGrabbable.transform.parent        = originParent;
                }
            }
            lastEditorGrabbable = editorGrabbable;
        }
예제 #3
0
 private void OnEnable()
 {
     headerStyle = new GUIStyle()
     {
         fontStyle = FontStyle.Bold, alignment = TextAnchor.MiddleLeft
     };
     grabbable = target as Grabbable;
 }
예제 #4
0
 public PoseData(Hand hand, Grabbable grabbable)
 {
     posePositions  = new Vector3[0];
     poseRotations  = new Quaternion[0];
     handOffset     = new Vector3();
     rotationOffset = new Vector3();
     SavePose(hand, grabbable.transform);
 }
예제 #5
0
 internal virtual void StopHighlight(Grabbable from)
 {
     if (placedObject == null)
     {
         OnStopHighlightEvent?.Invoke(this, from);
         OnStopHighlight?.Invoke();
     }
 }
예제 #6
0
 /// <summary>Creates a new pose using the current hand relative to a given grabbable</summary>
 public HandPoseData(Hand hand, Grabbable grabbable)
 {
     posePositions         = new Vector3[0];
     poseRotations         = new Quaternion[0];
     handOffset            = new Vector3();
     rotationOffset        = Vector3.zero;
     localQuaternionOffset = Quaternion.identity;
     SavePose(hand, grabbable.transform);
 }
예제 #7
0
 public virtual void Remove(Grabbable placeObj)
 {
     if (makeKinematic)
     {
         placeObj.body.isKinematic = false;
     }
     placeObj.transform.parent = originParent;
     OnRemove?.Invoke();
     occupied     = false;
     placedObject = null;
 }
예제 #8
0
        protected void Start()
        {
#if UNITY_EDITOR
            lastEditorGrabbable = null;
            if (!EditorApplication.isPlaying)
            {
                return;
            }
#endif

            col           = gameObject.GetComponent <SphereCollider>();
            col.radius    = placeRadius;
            col.isTrigger = true;
            SetStartPlaced();
        }
예제 #9
0
        public void SetHeldPose(PoseData pose, Grabbable grabbable)
        {
            holdingObj = grabbable;
            OnBeforeGrabbed?.Invoke(this, holdingObj);

            holdingObj.transform.position = transform.position;

            //Set Pose
            pose.SetPose(this, grabbable.transform);
            SetLayerRecursive(transform, LayerMask.NameToLayer("HandHolding"));

            //Connect Joints
            joint1 = gameObject.AddComponent <FixedJoint>();
            joint1.connectedBody = holdingObj.body;
            joint1.breakForce    = holdingObj.jointBreakForce;
            joint1.breakTorque   = holdingObj.jointBreakForce;

            joint1.connectedMassScale  = 1;
            joint1.massScale           = 1;
            joint1.enableCollision     = false;
            joint1.enablePreprocessing = false;

            joint2 = holdingObj.body.gameObject.AddComponent <FixedJoint>();
            joint2.connectedBody = body;
            joint2.breakForce    = holdingObj.jointBreakForce;
            joint2.breakTorque   = holdingObj.jointBreakForce;

            joint2.connectedMassScale  = 1;
            joint2.massScale           = 1;
            joint2.enableCollision     = false;
            joint2.enablePreprocessing = false;

            grabPoint                    = new GameObject().transform;
            grabPoint.parent             = holdingObj.transform;
            grabPoint.transform.position = transform.position;
            grabPoint.transform.rotation = transform.rotation;

            OnGrabbed?.Invoke(this, holdingObj);
            holdingObj.OnGrab(this);

            SetTransformToFollow();

            grabLocked = true;

            //Reset Values
            grabbing = false;
        }
예제 #10
0
 protected void Start()
 {
     grabbable = GetComponent <Grabbable>();
     if (!leftPoseSet && !rightPoseSet)
     {
         Debug.LogError("Grabbable Pose has not been set for either hand", this);
         grabbable.enabled = false;
     }
     else if (!leftPoseSet && rightPoseSet && !(grabbable.handType == HandType.right))
     {
         Debug.Log("Setting Grabbable to right hand only because left handed pose not set", this);
         grabbable.handType = HandType.right;
     }
     else if (leftPoseSet && !rightPoseSet && !(grabbable.handType == HandType.left))
     {
         Debug.Log("Setting Grabbable to left hand only because right handed pose not set", this);
         grabbable.handType = HandType.left;
     }
 }
예제 #11
0
        void Start()
        {
#if UNITY_EDITOR
            lastEditorGrabbable = null;
            if (!EditorApplication.isPlaying)
            {
                return;
            }
#endif

            col                  = gameObject.GetComponent <SphereCollider>();
            col.radius           = placeRadius;
            col.isTrigger        = true;
            col.gameObject.layer = LayerMask.NameToLayer("PlacePoint");
            if (startPlaced != null)
            {
                startPlaced.SetPlacePoint(this);
                Place(startPlaced);
            }
        }
예제 #12
0
 public virtual void Remove(Grabbable placeObj)
 {
     if (makePlacedKinematic)
     {
         placeObj.body.isKinematic = false;
     }
     if (!parentOnPlace)
     {
         placeObj.transform.parent = originParent;
     }
     OnRemoveEvent?.Invoke(this, placeObj);
     OnRemove?.Invoke();
     occupied     = false;
     placedObject = null;
     if (joint != null)
     {
         Destroy(joint);
         joint = null;
     }
 }
예제 #13
0
        /// <summary>Returns true if there is a grabbable or link, out null if there is none</summary>
        bool GetGrabbable(GameObject obj, out Grabbable grabbable)
        {
            if (obj == null)
            {
                grabbable = null;
                return(false);
            }

            if (obj.GetComponent <Grabbable>())
            {
                grabbable = obj.GetComponent <Grabbable>();
                return(true);
            }

            if (obj.GetComponent <GrabbableChild>())
            {
                grabbable = obj.GetComponent <GrabbableChild>().grabParent;
                return(true);
            }

            grabbable = null;
            return(false);
        }
예제 #14
0
        public void BreakGrabConnection()
        {
            holdingObj = null;
            grabLocked = false;
            grabPose   = null;

            //This helps prevent clipping when releasing items by letting items drop through on release
            StartCoroutine(TimedResetLayer(ignoreReleaseTime, "HandReleasing", "Hand"));

            //Destroy Junk
            if (grabPoint != null)
            {
                Destroy(grabPoint.gameObject);
            }
            if (joint1 != null)
            {
                Destroy(joint1);
            }
            if (joint2 != null)
            {
                Destroy(joint2);
            }
        }
예제 #15
0
        public virtual void Place(Grabbable placeObj)
        {
            placingFrame = true;
            originParent = placeObj.transform.parent;
            placeObj.transform.parent        = transform;
            placeObj.transform.localPosition = placedOffset;
            placeObj.transform.localRotation = Quaternion.identity;
            placeObj.body.position           = placeObj.transform.position;
            placeObj.body.isKinematic        = makePlacedKinematic;
            placeObj.body.velocity           = Vector3.zero;
            placeObj.body.angularVelocity    = Vector3.zero;

            if (placedJointLink != null)
            {
                joint = placedJointLink.gameObject.AddComponent <FixedJoint>();
                joint.connectedBody = placeObj.body;
                joint.breakForce    = placedJointBreakForce;
                joint.breakTorque   = placedJointBreakForce;

                joint.connectedMassScale  = 1;
                joint.massScale           = 1;
                joint.enableCollision     = false;
                joint.enablePreprocessing = false;
            }

            if (!parentOnPlace)
            {
                placeObj.transform.parent = originParent;
            }

            occupied      = true;
            placedObject  = placeObj;
            placePosition = placedObject.transform.position;
            OnPlaceEvent?.Invoke(this, placeObj);
            OnPlace?.Invoke();
        }
예제 #16
0
        protected void Update()
        {
            if (joint != null && placedObject != null)
            {
                placedObject.transform.position = placePosition;
            }
#if UNITY_EDITOR
            if (EditorApplication.isPlaying)
            {
                return;
            }

            if (editorGrabbable != null)
            {
                if (lastEditorGrabbable != editorGrabbable)
                {
                    if (lastEditorGrabbable != null)
                    {
                        Remove(lastEditorGrabbable);
                        lastEditorGrabbable.transform.position = preEditorPos;
                    }

                    preEditorPos = editorGrabbable.transform.position;
                }
                else
                {
                    originParent = editorGrabbable.transform.parent;
                    editorGrabbable.transform.parent        = transform;
                    editorGrabbable.transform.localPosition = placedOffset;
                    editorGrabbable.transform.localRotation = Quaternion.identity;
                    editorGrabbable.transform.parent        = originParent;
                }
            }
            lastEditorGrabbable = editorGrabbable;
#endif
        }
예제 #17
0
 public PoseData GetHeldPose(out Grabbable held)
 {
     held = holdingObj;
     return(new PoseData(this));
 }
 void Start()
 {
     rb   = GetComponent <Rigidbody>();
     grab = GetComponent <Grabbable>();
 }
예제 #19
0
        /// <summary>Takes a hit from a grabbable object and moves the hand towards that point, then calculates ideal hand shape</summary>
        IEnumerator GrabObject(RaycastHit hit)
        {
            Grabbable lookingAtGrab;

            if (GetGrabbable(lookingAtObj, out lookingAtGrab))
            {
                lookingAtGrab.Unhighlight();
            }

            lookingAtObj = null;

            Grabbable tempHoldingObj;

            if (!GetGrabbable(hit.collider.gameObject, out tempHoldingObj))
            {
                yield break;
            }

            //Checks if the grabbable script is enabled
            if (!tempHoldingObj.enabled)
            {
                yield break;
            }

            //If the hand doesn't match the settings
            if ((tempHoldingObj.handType == HandType.left && !left) || (tempHoldingObj.handType == HandType.right && left))
            {
                yield break;
            }

            //Hand Swap - One Handed Items
            if (tempHoldingObj.singleHandOnly && tempHoldingObj.HeldCount() > 0)
            {
                tempHoldingObj.ForceHandsRelease();
                yield return(new WaitForFixedUpdate());

                yield return(new WaitForEndOfFrame());
            }


            holdingObj   = tempHoldingObj;
            startGrabPos = transform.position;
            startGrabRot = transform.rotation;

            OnBeforeGrabbed?.Invoke(this, holdingObj);

            //GrabbableBase check - cancels grab if failed
            var grabBase = holdingObj.GetComponent <GrabbablePointBase>();

            if (grabBase != null && !grabBase.Align(this))
            {
                yield break;
            }


            //Set layers for grabbing
            var originalLayer = LayerMask.LayerToName(holdingObj.gameObject.layer);

            holdingObj.SetLayerRecursive(holdingObj.transform, LayerMask.NameToLayer("Grabbable"), LayerMask.NameToLayer("Grabbing"));
            holdingObj.SetLayerRecursive(holdingObj.transform, LayerMask.NameToLayer("Holding"), LayerMask.NameToLayer("Grabbing"));
            holdingObj.SetLayerRecursive(holdingObj.transform, LayerMask.NameToLayer("Releasing"), LayerMask.NameToLayer("Grabbing"));
            SetLayerRecursive(transform, LayerMask.NameToLayer("HandHolding"));

            //SETS GRAB POINT
            grabPoint          = new GameObject().transform;
            grabPoint.position = hit.point;
            grabPoint.parent   = hit.transform;

            grabbing        = true;
            palmOffset      = transform.position - palmTransform.position;
            moveTo.position = grabPoint.transform.position + palmOffset;
            moveTo.rotation = grabPoint.transform.rotation;
            freezeRot       = true;

            //Aligns the hand using the closest hit point
            IEnumerator AutoAllign()
            {
                foreach (var finger in fingers)
                {
                    finger.ResetBend();
                }

                var mass = body.mass;
                var dir  = HandClosestHit(out _, reachDistance, LayerMask.GetMask("Grabbing"));

                var palmOriginParent = palmTransform.parent;

                palmTransform.parent = null;
                var originParent = transform.parent;

                transform.parent = palmTransform;

                palmTransform.LookAt(grabPoint.position, transform.forward);

                transform.parent     = originParent;
                palmTransform.parent = palmOriginParent;
                body.mass            = 0;


                transform.position = grabPoint.position + palmOffset;

                grabbingFrame = true;
                body.WakeUp();
                holdingObj.body.WakeUp();
                Physics.SyncTransforms();

                yield return(new WaitForFixedUpdate());

                body.WakeUp();
                grabbingFrame = false;
                if (holdingObj != null)
                {
                    holdingObj.body.WakeUp();
                }
                body.mass = mass;
            }

            //Predetermined Pose
            if (holdingObj.GetComponent <GrabbablePose>())
            {
                grabPose = holdingObj.GetComponent <GrabbablePose>();
                grabPose.SetGrabPose(this);
            }

            //Allign Position
            else if (grabBase == null)
            {
                yield return(StartCoroutine(AutoAllign()));
            }

            if (holdingObj != null)
            {
                //Finger Bend
                if (grabPose == null)
                {
                    foreach (var finger in fingers)
                    {
                        finger.BendFingerUntilHit(fingerBendSteps, LayerMask.GetMask("Grabbing"));
                    }
                }


                //Connect Joints
                joint1 = gameObject.AddComponent <FixedJoint>();
                joint1.connectedBody = holdingObj.body;
                joint1.breakForce    = 10000000;
                joint1.breakTorque   = 10000000;

                joint1.connectedMassScale  = 1;
                joint1.massScale           = 1;
                joint1.enableCollision     = false;
                joint1.enablePreprocessing = false;

                joint2 = holdingObj.body.gameObject.AddComponent <FixedJoint>();
                joint2.connectedBody = body;
                joint2.breakForce    = 10000000;
                joint2.breakTorque   = 10000000;

                joint2.connectedMassScale  = 1;
                joint2.massScale           = 1;
                joint2.enableCollision     = false;
                joint2.enablePreprocessing = false;

                grabPoint.transform.position = transform.position;
                grabPoint.transform.rotation = transform.rotation;
                OnGrabbed?.Invoke(this, holdingObj);
                holdingObj.OnGrab(this);

                yield return(new WaitForFixedUpdate());

                if (holdingObj != null)
                {
                    joint1.breakForce  = holdingObj.jointBreakForce;
                    joint1.breakTorque = holdingObj.jointBreakForce;

                    joint2.breakForce  = holdingObj.jointBreakForce;
                    joint2.breakTorque = holdingObj.jointBreakForce;

                    grabLocked = true;
                }

                if (grabPose != null || grabBase != null)
                {
                    transform.rotation = moveTo.rotation;
                }
            }

            //Reset Values
            freezePos = false;
            freezeRot = false;
            grabbing  = false;

            yield return(new WaitForEndOfFrame());

            if (grabPose != null || grabBase != null)
            {
                transform.rotation = follow.rotation;
            }
        }