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; }
/// <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; } }