summaryrefslogtreecommitdiff
path: root/Holding.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Holding.cs')
-rw-r--r--Holding.cs288
1 files changed, 288 insertions, 0 deletions
diff --git a/Holding.cs b/Holding.cs
new file mode 100644
index 0000000..dafc08b
--- /dev/null
+++ b/Holding.cs
@@ -0,0 +1,288 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class Holding : MonoBehaviour
+{
+ [HideInInspector]
+ public HoldableObject heldObject;
+
+ [HideInInspector]
+ public HoldableObject heldObjectOffHand;
+
+ [HideInInspector]
+ public Transform baseTransform;
+
+ private Rigidbody rightHand;
+
+ private Rigidbody leftHand;
+
+ [HideInInspector]
+ public ConfigurableJoint leftHandJoint;
+
+ [HideInInspector]
+ public ConfigurableJoint rightHandJoint;
+
+ public float grabForce;
+
+ [HideInInspector]
+ public bool isGrabbing;
+
+ private Transform rotaionTarget;
+
+ private bool hasMainHandWeapon;
+
+ private PlayerDeath death;
+
+ public LayerMask mask = default(LayerMask);
+
+ private Strength str;
+
+ private float strength = 1f;
+
+ private PID leftHandPID;
+
+ private PID rightHandPID;
+
+ private StandingDataHandler standingData;
+
+ private void Awake()
+ {
+ death = GetComponent<PlayerDeath>();
+ standingData = GetComponent<StandingDataHandler>();
+ str = GetComponent<Strength>();
+ if (!baseTransform)
+ {
+ baseTransform = GetComponentInChildren<HoldingBaseTransform>().transform;
+ }
+ rightHand = GetComponentInChildren<HandRight>().GetComponent<Rigidbody>();
+ leftHand = GetComponentInChildren<HandLeft>().GetComponent<Rigidbody>();
+ rotaionTarget = base.transform.GetComponentInChildren<RotationTarget>().transform;
+ mask = LayerMask.GetMask("Map");
+ leftHandPID = leftHand.GetComponent<PID>();
+ rightHandPID = rightHand.GetComponent<PID>();
+ }
+
+ private void Update()
+ {
+ if (!death.dead && (bool)heldObject)
+ {
+ strength = str.strength;
+ if (((bool)rightHandJoint || !heldObject.rightHandPos) && ((bool)leftHandJoint || !heldObject.leftHandPos) && (!heldObjectOffHand || (((bool)rightHandJoint || !heldObjectOffHand.rightHandPos) && ((bool)leftHandJoint || !heldObjectOffHand.leftHandPos))))
+ {
+ isGrabbing = false;
+ }
+ }
+ }
+
+ private void FixedUpdate()
+ {
+ if (death.dead || isGrabbing)
+ {
+ return;
+ }
+ if ((bool)heldObject)
+ {
+ HoldObjectInPlace(heldObject.rig, heldObject, offHand: false, rightHand);
+ if (!heldObjectOffHand && (bool)leftHandJoint)
+ {
+ HoldObjectInPlace(heldObject.rig, heldObject, offHand: false, leftHand, justHand: true);
+ }
+ }
+ if ((bool)heldObjectOffHand)
+ {
+ HoldObjectInPlace(heldObjectOffHand.rig, heldObjectOffHand, offHand: true, leftHand);
+ }
+ }
+
+ private void HoldObjectInPlace(Rigidbody rigi, HoldableObject held, bool offHand, Rigidbody hand, bool justHand = false)
+ {
+ Vector3 holdingPosition = held.holdingPosition;
+ if (offHand)
+ {
+ holdingPosition.x *= -1f;
+ }
+ holdingPosition = baseTransform.TransformPoint(holdingPosition);
+ Vector3 holdingRotation = held.holdingRotation;
+ Vector3 targetRotation = baseTransform.TransformDirection(holdingRotation);
+ Vector3 targetRotationUp = baseTransform.TransformDirection(held.holdingUpRotation);
+ if (!justHand)
+ {
+ held.pid.DoPID(holdingPosition, targetRotation, targetRotationUp, strength);
+ }
+ PID pID = rightHandPID;
+ Vector3 localPosition = held.rightHandPos.localPosition;
+ if (hand == leftHand)
+ {
+ localPosition = held.leftHandPos.localPosition;
+ pID = leftHandPID;
+ }
+ Vector3 position = held.holdingPosition + localPosition;
+ if (offHand)
+ {
+ position.x *= -1f;
+ }
+ position = baseTransform.TransformPoint(position);
+ Debug.DrawLine(position, position + Vector3.up);
+ Debug.DrawLine(holdingPosition, holdingPosition + Vector3.up);
+ pID.DoPID(position, Vector3.zero, Vector3.zero, strength);
+ }
+
+ public void StartHolding(HoldableObject holdableObject, bool hasOffHand)
+ {
+ holdableObject.isHeld = true;
+ isGrabbing = true;
+ bool offHand = false;
+ if (!hasMainHandWeapon)
+ {
+ hasMainHandWeapon = true;
+ heldObject = holdableObject;
+ if ((bool)heldObject.rightHandPos)
+ {
+ StartCoroutine(Grab(mainHand: true, rightHand, heldObject, offHand: false));
+ }
+ if ((bool)heldObject.leftHandPos && !hasOffHand)
+ {
+ StartCoroutine(Grab(mainHand: false, leftHand, heldObject, offHand: false));
+ }
+ }
+ else
+ {
+ offHand = true;
+ heldObjectOffHand = holdableObject;
+ heldObjectOffHand.leftHandPos = heldObjectOffHand.rightHandPos;
+ if ((bool)heldObjectOffHand.rightHandPos)
+ {
+ StartCoroutine(Grab(mainHand: false, leftHand, heldObjectOffHand, offHand: true));
+ }
+ }
+ StartCoroutine(HoldweaponStill(holdableObject.rig, offHand, holdableObject));
+ }
+
+ private IEnumerator Grab(bool mainHand, Rigidbody hand, HoldableObject held, bool offHand)
+ {
+ while (isGrabbing)
+ {
+ if (mainHand)
+ {
+ if (!rightHandJoint)
+ {
+ ReachForPoint(rightHand, rightHand.transform.GetChild(0).position, held.rightHandPos, isLeft: false, held.rig, held, offHand);
+ rightHand.GetComponentInChildren<Collider>().enabled = false;
+ }
+ }
+ else if (!leftHandJoint)
+ {
+ ReachForPoint(leftHand, leftHand.transform.GetChild(0).position, held.leftHandPos, isLeft: true, held.rig, held, offHand);
+ leftHand.GetComponentInChildren<Collider>().enabled = false;
+ }
+ yield return null;
+ }
+ leftHand.GetComponentInChildren<Collider>().enabled = true;
+ rightHand.GetComponentInChildren<Collider>().enabled = true;
+ }
+
+ private IEnumerator HoldweaponStill(Rigidbody rigToGrab, bool offHand, HoldableObject held)
+ {
+ while (isGrabbing)
+ {
+ Vector3 pos = held.holdingPosition;
+ if (offHand)
+ {
+ pos.x *= -1f;
+ }
+ rigToGrab.transform.position = baseTransform.TransformPoint(pos);
+ rigToGrab.transform.rotation = Quaternion.LookRotation(baseTransform.TransformDirection(heldObject.holdingRotation));
+ yield return null;
+ }
+ }
+
+ public void Drop()
+ {
+ List<HoldableObject> list = new List<HoldableObject>();
+ if ((bool)heldObject)
+ {
+ list.Add(heldObject);
+ }
+ if ((bool)heldObjectOffHand)
+ {
+ list.Add(heldObjectOffHand);
+ }
+ for (int i = 0; i < list.Count; i++)
+ {
+ list[i].holder = null;
+ list[i].isHeld = false;
+ list[i].rig.useGravity = true;
+ list[i].rig.drag = 0f;
+ list[i].rig.angularDrag = 0f;
+ Collider[] componentsInChildren = list[i].GetComponentsInChildren<Collider>();
+ foreach (Collider collider in componentsInChildren)
+ {
+ collider.material = null;
+ }
+ }
+ heldObject = null;
+ heldObjectOffHand = null;
+ if ((bool)rightHandJoint)
+ {
+ Object.Destroy(rightHandJoint);
+ }
+ if ((bool)leftHandJoint)
+ {
+ Object.Destroy(leftHandJoint);
+ }
+ hasMainHandWeapon = false;
+ }
+
+ private void ReachForPoint(Rigidbody rigToReach, Vector3 forcePosition, Transform targetPositionTransform, bool isLeft, Rigidbody rigToGrab, HoldableObject held, bool offHand)
+ {
+ Vector3 normalized = (targetPositionTransform.position - forcePosition).normalized;
+ rigToReach.AddForceAtPosition(normalized * grabForce * Mathf.Clamp(Time.deltaTime, 0f, 0.1f), forcePosition, ForceMode.Acceleration);
+ if (Vector3.Distance(targetPositionTransform.position, forcePosition) < 0.5f)
+ {
+ ConnectRig(rigToReach, rigToGrab, targetPositionTransform, isLeft, held, offHand);
+ }
+ }
+
+ private void ConnectRig(Rigidbody startRig, Rigidbody targetRig, Transform targetPositionTransform, bool isLeft, HoldableObject held, bool offHand)
+ {
+ ConfigurableJoint configurableJoint = startRig.gameObject.AddComponent<ConfigurableJoint>();
+ if (offHand)
+ {
+ targetPositionTransform.localRotation = Quaternion.Euler(targetPositionTransform.localEulerAngles.x, 0f - targetPositionTransform.localEulerAngles.y, targetPositionTransform.localEulerAngles.z);
+ }
+ startRig.transform.rotation = targetPositionTransform.rotation;
+ startRig.transform.position += targetPositionTransform.position - startRig.transform.GetChild(0).position;
+ configurableJoint.connectedBody = targetRig;
+ configurableJoint.projectionMode = JointProjectionMode.PositionAndRotation;
+ configurableJoint.xMotion = ConfigurableJointMotion.Locked;
+ configurableJoint.yMotion = ConfigurableJointMotion.Locked;
+ configurableJoint.zMotion = ConfigurableJointMotion.Locked;
+ configurableJoint.angularXMotion = ConfigurableJointMotion.Limited;
+ configurableJoint.angularYMotion = ConfigurableJointMotion.Limited;
+ configurableJoint.angularZMotion = ConfigurableJointMotion.Limited;
+ SoftJointLimit highAngularXLimit = configurableJoint.highAngularXLimit;
+ highAngularXLimit.limit = held.swingAngles.y;
+ configurableJoint.highAngularXLimit = highAngularXLimit;
+ highAngularXLimit.limit = held.swingAngles.x;
+ configurableJoint.lowAngularXLimit = highAngularXLimit;
+ highAngularXLimit.limit = held.twistAngles.x;
+ configurableJoint.angularYLimit = highAngularXLimit;
+ highAngularXLimit.limit = held.twistAngles.y;
+ configurableJoint.angularZLimit = highAngularXLimit;
+ SoftJointLimitSpring angularXLimitSpring = configurableJoint.angularXLimitSpring;
+ angularXLimitSpring.spring = held.swingSpring;
+ configurableJoint.angularXLimitSpring = angularXLimitSpring;
+ angularXLimitSpring.spring = held.twistSpring;
+ configurableJoint.angularYZLimitSpring = angularXLimitSpring;
+ configurableJoint.anchor = startRig.transform.InverseTransformPoint(startRig.transform.GetChild(0).position);
+ if (isLeft)
+ {
+ leftHandJoint = configurableJoint;
+ }
+ else
+ {
+ rightHandJoint = configurableJoint;
+ }
+ }
+}