You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
	
	
		
			193 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			C#
		
	
		
		
			
		
	
	
			193 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			C#
		
	
| 
								 
											1 year ago
										 
									 | 
							
								using System.Collections;
							 | 
						||
| 
								 | 
							
								using System.Collections.Generic;
							 | 
						||
| 
								 | 
							
								using UnityEngine;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace Autohand
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    [RequireComponent(typeof(Grabbable)), DefaultExecutionOrder(10)]
							 | 
						||
| 
								 | 
							
								    public class GrabbableHeldJoint : MonoBehaviour
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        [Tooltip("The grabbable that this grabbable is connected to")]
							 | 
						||
| 
								 | 
							
								        public Grabbable connectedGrabbable;
							 | 
						||
| 
								 | 
							
								        [Tooltip("Offsets the center of this joint")]
							 | 
						||
| 
								 | 
							
								        public Vector3 pivotOffset;
							 | 
						||
| 
								 | 
							
								        [Tooltip("This will multiply the hands strength while holding this grabbable to give it more or less positional priority while holding this joint as a second hand (good to reduce when you dont want this joint having movement priority while being held)")]
							 | 
						||
| 
								 | 
							
								        [Min(0.1f)]
							 | 
						||
| 
								 | 
							
								        public float heldMassScale = 1f;
							 | 
						||
| 
								 | 
							
								        [Space]
							 | 
						||
| 
								 | 
							
								        [Tooltip("The maximum distance this joint is allowed to move in the local positive x-axis")]
							 | 
						||
| 
								 | 
							
								        public float xMaxLimit = 0f;
							 | 
						||
| 
								 | 
							
								        [Tooltip("The maximum distance this joint is allowed to move in the local negative x-axis")]
							 | 
						||
| 
								 | 
							
								        public float xMinLimit = 0f;
							 | 
						||
| 
								 | 
							
								        [Tooltip("This will force the joint back into its center position based on the given spring strength while not being held along this axis")]
							 | 
						||
| 
								 | 
							
								        public float xSpring = 0f;
							 | 
						||
| 
								 | 
							
								        [Space]
							 | 
						||
| 
								 | 
							
								        [Tooltip("The maximum distance this joint is allowed to move in the local positive y-axis")]
							 | 
						||
| 
								 | 
							
								        public float yMaxLimit = 0f;
							 | 
						||
| 
								 | 
							
								        [Tooltip("The maximum distance this joint is allowed to move in the local negative y-axis")]
							 | 
						||
| 
								 | 
							
								        public float yMinLimit = 0f;
							 | 
						||
| 
								 | 
							
								        [Tooltip("This will force the joint back into its center position based on the given spring strength while not being held along this axis")]
							 | 
						||
| 
								 | 
							
								        public float ySpring = 0f;
							 | 
						||
| 
								 | 
							
								        [Space]
							 | 
						||
| 
								 | 
							
								        [Tooltip("The maximum distance this joint is allowed to move in the local positive z-axis")]
							 | 
						||
| 
								 | 
							
								        public float zMaxLimit = 0f;
							 | 
						||
| 
								 | 
							
								        [Tooltip("The maximum distance this joint is allowed to move in the local negative z-axis")]
							 | 
						||
| 
								 | 
							
								        public float zMinLimit = 0f;
							 | 
						||
| 
								 | 
							
								        [Tooltip("This will force the joint back into its center position based on the given spring strength while not being held along this axis")]
							 | 
						||
| 
								 | 
							
								        public float zSpring = 0f;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        [Space]
							 | 
						||
| 
								 | 
							
								        [Range(0, 1), Tooltip("The percentage from the min/max distance needed to trigger the event, good for creating a buffer for the event to trigger slightly before the max range to help prevent missed event")]
							 | 
						||
| 
								 | 
							
								        public float eventOffset = 0.05f;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public UnityHandGrabEvent OnMinDistanceEvent;
							 | 
						||
| 
								 | 
							
								        public UnityHandGrabEvent OnMaxDistanceEvent;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        bool triggeredMaxEvent;
							 | 
						||
| 
								 | 
							
								        bool triggeredMinEvent;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        Vector3 handLocalPosition;
							 | 
						||
| 
								 | 
							
								        Vector3 localPosition;
							 | 
						||
| 
								 | 
							
								        Vector3 localTargetPosition;
							 | 
						||
| 
								 | 
							
								        Vector3 localStartPosition;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        Grabbable grabbable;
							 | 
						||
| 
								 | 
							
								        Vector3 localOrigin;
							 | 
						||
| 
								 | 
							
								        Vector3 localStartOrigin;
							 | 
						||
| 
								 | 
							
								        Hand jointHand;
							 | 
						||
| 
								 | 
							
								        bool grabFrame;
							 | 
						||
| 
								 | 
							
								        bool started = false;
							 | 
						||
| 
								 | 
							
								        public void Start()
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if(started)
							 | 
						||
| 
								 | 
							
								                return;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            ResetOrigin();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if(grabbable == null) {
							 | 
						||
| 
								 | 
							
								                grabbable = GetComponent<Grabbable>();
							 | 
						||
| 
								 | 
							
								                grabbable.OnGrabEvent += OnGrabbed;
							 | 
						||
| 
								 | 
							
								                grabbable.OnReleaseEvent += OnReleased;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            grabbable.singleHandOnly = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if(xMinLimit == 0 && yMinLimit == 0 && zMinLimit == 0)
							 | 
						||
| 
								 | 
							
								                triggeredMinEvent = true;
							 | 
						||
| 
								 | 
							
								            started = true;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public void ResetOrigin()
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            localOrigin = connectedGrabbable.rootTransform.InverseTransformPoint(transform.position) + pivotOffset;
							 | 
						||
| 
								 | 
							
								            localStartOrigin = localOrigin;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        internal void OnGrabbed(Hand hand, Grabbable grab)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            jointHand = hand;
							 | 
						||
| 
								 | 
							
								            hand.body.mass *= heldMassScale;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            localOrigin = hand.heldJoint.connectedAnchor + pivotOffset;
							 | 
						||
| 
								 | 
							
								            localTargetPosition = new Vector3(
							 | 
						||
| 
								 | 
							
								                Mathf.Clamp(handLocalPosition.x, localOrigin.x + xMinLimit, localOrigin.x + xMaxLimit),
							 | 
						||
| 
								 | 
							
								                Mathf.Clamp(handLocalPosition.y, localOrigin.y + yMinLimit, localOrigin.y + yMaxLimit),
							 | 
						||
| 
								 | 
							
								                Mathf.Clamp(handLocalPosition.z, localOrigin.z + zMinLimit, localOrigin.z + zMaxLimit)
							 | 
						||
| 
								 | 
							
								            );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            localTargetPosition += pivotOffset;
							 | 
						||
| 
								 | 
							
								            grabFrame = true;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        void OnReleased(Hand hand, Grabbable grab)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            jointHand = null;
							 | 
						||
| 
								 | 
							
								            hand.body.mass /= heldMassScale;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            localOrigin = localStartOrigin;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        private void FixedUpdate()
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if(grabFrame) {
							 | 
						||
| 
								 | 
							
								                grabFrame = false;
							 | 
						||
| 
								 | 
							
								                return;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            UpdateJoint();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public void SetJointMax() {
							 | 
						||
| 
								 | 
							
								            transform.position = connectedGrabbable.rootTransform.TransformPoint(localOrigin + pivotOffset + new Vector3(xMaxLimit, yMaxLimit, zMaxLimit));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public void SetJointMin() {
							 | 
						||
| 
								 | 
							
								            transform.position = connectedGrabbable.rootTransform.TransformPoint(localOrigin + pivotOffset + new Vector3(xMinLimit, yMinLimit, zMinLimit));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public void UpdateJoint()
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if (connectedGrabbable.HeldCount() > 0 && grabbable.HeldCount(false, false, true) > 0 && jointHand != null)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                handLocalPosition = jointHand.heldJoint.connectedBody.transform.InverseTransformPoint(jointHand.moveTo.position) + pivotOffset;
							 | 
						||
| 
								 | 
							
								                localPosition = jointHand.heldJoint.connectedAnchor + pivotOffset;
							 | 
						||
| 
								 | 
							
								                localTargetPosition = new Vector3(
							 | 
						||
| 
								 | 
							
								                    Mathf.MoveTowards(localPosition.x, Mathf.Clamp(handLocalPosition.x, localOrigin.x + xMinLimit, localOrigin.x + xMaxLimit), 1f),
							 | 
						||
| 
								 | 
							
								                    Mathf.MoveTowards(localPosition.y, Mathf.Clamp(handLocalPosition.y, localOrigin.y + yMinLimit, localOrigin.y + yMaxLimit), 1f),
							 | 
						||
| 
								 | 
							
								                    Mathf.MoveTowards(localPosition.z, Mathf.Clamp(handLocalPosition.z, localOrigin.z + zMinLimit, localOrigin.z + zMaxLimit), 1f)
							 | 
						||
| 
								 | 
							
								                );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if(localPosition != localTargetPosition) {
							 | 
						||
| 
								 | 
							
								                    //Vector3 globalTargetPosition = connectedGrabbable.rootTransform.TransformPoint(localTargetPosition - jointHand.handGrabPoint.localPosition);
							 | 
						||
| 
								 | 
							
								                    transform.localPosition += (localTargetPosition - localPosition); // Adjusting position with pivot offset
							 | 
						||
| 
								 | 
							
								                    transform.localPosition = new Vector3(
							 | 
						||
| 
								 | 
							
								                        Mathf.Clamp(transform.localPosition.x, localStartOrigin.x + xMinLimit, localStartOrigin.x + xMaxLimit),
							 | 
						||
| 
								 | 
							
								                        Mathf.Clamp(transform.localPosition.y, localStartOrigin.y + yMinLimit, localStartOrigin.y + yMaxLimit),
							 | 
						||
| 
								 | 
							
								                        Mathf.Clamp(transform.localPosition.z, localStartOrigin.z + zMinLimit, localStartOrigin.z + zMaxLimit)
							 | 
						||
| 
								 | 
							
								                    );
							 | 
						||
| 
								 | 
							
								                    jointHand.heldJoint.connectedAnchor += (localTargetPosition - localPosition);
							 | 
						||
| 
								 | 
							
								                    jointHand.handGrabPoint.localPosition += (localTargetPosition - localPosition);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                Vector3 localPosition = connectedGrabbable.transform.InverseTransformPoint(transform.position) + pivotOffset;
							 | 
						||
| 
								 | 
							
								                Vector3 localTargetPosition = new Vector3(
							 | 
						||
| 
								 | 
							
								                    Mathf.MoveTowards(localPosition.x, localOrigin.x, Time.fixedDeltaTime * xSpring),
							 | 
						||
| 
								 | 
							
								                    Mathf.MoveTowards(localPosition.y, localOrigin.y, Time.fixedDeltaTime * ySpring),
							 | 
						||
| 
								 | 
							
								                    Mathf.MoveTowards(localPosition.z, localOrigin.z, Time.fixedDeltaTime * zSpring)
							 | 
						||
| 
								 | 
							
								                );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if(transform.localPosition != localOrigin)
							 | 
						||
| 
								 | 
							
								                    transform.position = connectedGrabbable.rootTransform.TransformPoint(localTargetPosition);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								                    
							 | 
						||
| 
								 | 
							
								            if(OnMaxDistanceEvent != null) {
							 | 
						||
| 
								 | 
							
								                var localPos = connectedGrabbable.rootTransform.InverseTransformPoint(transform.position);
							 | 
						||
| 
								 | 
							
								                bool greaterOrEqual =
							 | 
						||
| 
								 | 
							
								                    localPos.x >= localStartOrigin.x + xMaxLimit - xMaxLimit * eventOffset - 0.001f &&
							 | 
						||
| 
								 | 
							
								                    localPos.y >= localStartOrigin.y + yMaxLimit - yMaxLimit * eventOffset - 0.001f &&
							 | 
						||
| 
								 | 
							
								                    localPos.z >= localStartOrigin.z + zMaxLimit - zMaxLimit * eventOffset - 0.001f; 
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if(greaterOrEqual && !triggeredMaxEvent) {
							 | 
						||
| 
								 | 
							
								                    OnMaxDistanceEvent.Invoke(jointHand, connectedGrabbable);
							 | 
						||
| 
								 | 
							
								                    triggeredMaxEvent = true;
							 | 
						||
| 
								 | 
							
								                    triggeredMinEvent = false;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if(OnMinDistanceEvent != null) {
							 | 
						||
| 
								 | 
							
								                var localPos = connectedGrabbable.rootTransform.InverseTransformPoint(transform.position);
							 | 
						||
| 
								 | 
							
								                bool lessOrEqual =
							 | 
						||
| 
								 | 
							
								                    localPos.x <= localStartOrigin.x + xMinLimit - xMinLimit * eventOffset + 0.001f &&
							 | 
						||
| 
								 | 
							
								                    localPos.y <= localStartOrigin.y + yMinLimit - yMinLimit * eventOffset + 0.001f &&
							 | 
						||
| 
								 | 
							
								                    localPos.z <= localStartOrigin.z + zMinLimit - zMinLimit * eventOffset + 0.001f;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if(lessOrEqual && !triggeredMinEvent) {
							 | 
						||
| 
								 | 
							
								                    OnMinDistanceEvent.Invoke(jointHand, connectedGrabbable);
							 | 
						||
| 
								 | 
							
								                    triggeredMinEvent = true;
							 | 
						||
| 
								 | 
							
								                    triggeredMaxEvent = false;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |