holopy3/Assets/Plugins/RootMotion/FinalIK/_DEMOS/FBBIK/Scripts/PickUp2Handed.cs

127 lines
4 KiB
C#
Raw Normal View History

2020-12-10 14:25:12 +00:00
using UnityEngine;
using System.Collections;
using RootMotion;
using RootMotion.FinalIK;
namespace RootMotion.Demos {
/// <summary>
/// Picking up an arbitrary object with both hands.
/// </summary>
public abstract class PickUp2Handed : MonoBehaviour {
// GUI for testing
public int GUIspace;
void OnGUI() {
GUILayout.BeginHorizontal();
GUILayout.Space(GUIspace);
if (!holding) {
if (GUILayout.Button("Pick Up " + obj.name)) {
interactionSystem.StartInteraction(FullBodyBipedEffector.LeftHand, obj, false);
interactionSystem.StartInteraction(FullBodyBipedEffector.RightHand, obj, false);
}
} else {
if (GUILayout.Button("Drop " + obj.name)) {
interactionSystem.ResumeAll();
}
}
GUILayout.EndHorizontal();
}
protected abstract void RotatePivot();
public InteractionSystem interactionSystem; // The InteractionSystem of the character
public InteractionObject obj; // The object to pick up
public Transform pivot; // The pivot point of the hand targets
public Transform holdPoint; // The point where the object will lerp to when picked up
public float pickUpTime = 0.3f; // Maximum lerp speed of the object. Decrease this value to give the object more weight
private float holdWeight, holdWeightVel;
private Vector3 pickUpPosition;
private Quaternion pickUpRotation;
void Start() {
// Listen to interaction events
interactionSystem.OnInteractionStart += OnStart;
interactionSystem.OnInteractionPause += OnPause;
interactionSystem.OnInteractionResume += OnDrop;
}
// Called by the InteractionSystem when an interaction is paused (on trigger)
private void OnPause(FullBodyBipedEffector effectorType, InteractionObject interactionObject) {
if (effectorType != FullBodyBipedEffector.LeftHand) return;
if (interactionObject != obj) return;
// Make the object inherit the character's movement
obj.transform.parent = interactionSystem.transform;
// Make the object kinematic
var r = obj.GetComponent<Rigidbody>();
if (r != null) r.isKinematic = true;
// Set object pick up position and rotation to current
pickUpPosition = obj.transform.position;
pickUpRotation = obj.transform.rotation;
holdWeight = 0f;
holdWeightVel = 0f;
}
// Called by the InteractionSystem when an interaction starts
private void OnStart(FullBodyBipedEffector effectorType, InteractionObject interactionObject) {
if (effectorType != FullBodyBipedEffector.LeftHand) return;
if (interactionObject != obj) return;
// Rotate the pivot of the hand targets
RotatePivot();
// Rotate the hold point so it matches the current rotation of the object
holdPoint.rotation = obj.transform.rotation;
}
// Called by the InteractionSystem when an interaction is resumed from being paused
private void OnDrop(FullBodyBipedEffector effectorType, InteractionObject interactionObject) {
if (effectorType != FullBodyBipedEffector.LeftHand) return;
if (interactionObject != obj) return;
// Make the object independent of the character
obj.transform.parent = null;
// Turn on physics for the object
if (obj.GetComponent<Rigidbody>() != null) obj.GetComponent<Rigidbody>().isKinematic = false;
}
void LateUpdate() {
if (holding) {
// Smoothing in the hold weight
holdWeight = Mathf.SmoothDamp(holdWeight, 1f, ref holdWeightVel, pickUpTime);
// Interpolation
obj.transform.position = Vector3.Lerp(pickUpPosition, holdPoint.position, holdWeight);
obj.transform.rotation = Quaternion.Lerp(pickUpRotation, holdPoint.rotation, holdWeight);
}
}
// Are we currently holding the object?
private bool holding {
get {
return interactionSystem.IsPaused(FullBodyBipedEffector.LeftHand);
}
}
// Clean up delegates
void OnDestroy() {
if (interactionSystem == null) return;
interactionSystem.OnInteractionStart -= OnStart;
interactionSystem.OnInteractionPause -= OnPause;
interactionSystem.OnInteractionResume -= OnDrop;
}
}
}