mirror of
https://github.com/nothke/quality-control.git
synced 2025-08-11 08:03:44 +00:00
Added interaction, hand, rigidbody dragging, picking up hammer
This commit is contained in:
233
Assets/Plugins/Interaction/Runtime/Rigidbody/DragRigidbody.cs
Normal file
233
Assets/Plugins/Interaction/Runtime/Rigidbody/DragRigidbody.cs
Normal file
@@ -0,0 +1,233 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Nothke.Interaction.Items
|
||||
{
|
||||
/// <summary>
|
||||
/// Use this if mass of rigidbody changes while the rigidbody is being held
|
||||
/// </summary>
|
||||
public interface IDragRigidbodyReleaseMassSettable
|
||||
{
|
||||
float ReleaseMass { get; }
|
||||
}
|
||||
|
||||
public class DragRigidbody : MonoBehaviour
|
||||
{
|
||||
public static DragRigidbody e;
|
||||
private void Awake() { e = this; }
|
||||
|
||||
public float k_Spring = 50.0f;
|
||||
public float k_Damper = 5.0f;
|
||||
public float k_Drag = 0f;
|
||||
public float k_AngularDrag = 0.0f;
|
||||
public float k_Distance = 0.0001f;
|
||||
public bool k_AttachToCenterOfMass = false;
|
||||
|
||||
public float distanceLimit = 2;
|
||||
public float clampVelocity = 2;
|
||||
public float clampExitVelocity = 2;
|
||||
|
||||
public float fakeMass = 0;
|
||||
float originalMass;
|
||||
|
||||
Rigidbody body;
|
||||
private ConfigurableJoint joint;
|
||||
RigidbodyInterpolation originalInterpolation;
|
||||
|
||||
public bool Holding => joint && joint.connectedBody;
|
||||
|
||||
public event Action OnSlipped;
|
||||
|
||||
public bool Hitting { private set; get; }
|
||||
|
||||
float hitDistance;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
CreateJoint();
|
||||
}
|
||||
|
||||
void CreateJoint()
|
||||
{
|
||||
var go = new GameObject("Rigidbody dragger");
|
||||
body = go.AddComponent<Rigidbody>();
|
||||
//body.rotation = Quaternion.LookRotation(transform.forward, transform.up);
|
||||
joint = go.AddComponent<ConfigurableJoint>();
|
||||
body.isKinematic = true;
|
||||
}
|
||||
|
||||
public float GetJointDistance()
|
||||
{
|
||||
if (joint && joint.connectedBody)
|
||||
return Vector3.Distance(
|
||||
body.position,
|
||||
joint.connectedBody.transform.TransformPoint(joint.connectedAnchor));
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
Quaternion addedRotation = Quaternion.identity;
|
||||
[NonSerialized] public bool rotate;
|
||||
[NonSerialized] public float rotateXInput;
|
||||
[NonSerialized] public float rotateYInput;
|
||||
|
||||
bool overrideTarget = false;
|
||||
Vector3 overrideTargetPoint;
|
||||
|
||||
public void OverrideTarget(Vector3 target)
|
||||
{
|
||||
overrideTarget = true;
|
||||
overrideTargetPoint = target;
|
||||
}
|
||||
|
||||
public void EndOverridingTarget()
|
||||
{
|
||||
overrideTarget = false;
|
||||
}
|
||||
|
||||
public Vector3 GetFrontTargetPoint()
|
||||
{
|
||||
return new Ray(transform.position, transform.forward).GetPoint(hitDistance);
|
||||
}
|
||||
|
||||
void FixedUpdate()
|
||||
{
|
||||
if (joint && joint.connectedBody)
|
||||
{
|
||||
//var ray = new Ray(transform.position, transform.forward);
|
||||
|
||||
Vector3 targetPoint = overrideTarget ? overrideTargetPoint :
|
||||
GetFrontTargetPoint();
|
||||
//ray.GetPoint(hitDistance);
|
||||
|
||||
joint.transform.position = targetPoint;
|
||||
|
||||
//joint.connectedBody.velocity = Vector3.ClampMagnitude(joint.connectedBody.velocity, clampVelocity);
|
||||
//joint.targetRotation = transform.rotation;
|
||||
//joint.targetRotation = UnityEngine.Random.rotation;
|
||||
|
||||
var bodyRot = body.rotation;
|
||||
if (rotate)
|
||||
{
|
||||
float mx = rotateXInput * 10;
|
||||
float my = rotateYInput * 10;
|
||||
|
||||
addedRotation =
|
||||
Quaternion.AngleAxis(mx, Vector3.up) *
|
||||
Quaternion.AngleAxis(my, Vector3.right) * addedRotation;
|
||||
|
||||
|
||||
//addedRotation *= Quaternion.Euler(mx * 10, 0, my * 10);
|
||||
|
||||
//body.rotation = rot * addedRotation;
|
||||
//body.MoveRotation(rot * Quaternion.Euler(4, 0, 0));
|
||||
//joint.targetRotation = rot * Quaternion.Euler(4, 0, 0);
|
||||
}
|
||||
|
||||
//Quaternion faceTo = Quaternion.Inverse(transform.rotation) * Quaternion.Euler(0, 90, 0);
|
||||
//addedRotation = Quaternion.Slerp(addedRotation, faceTo, Time.deltaTime * 10);
|
||||
|
||||
body.rotation = transform.rotation * addedRotation;
|
||||
|
||||
if (GetJointDistance() > distanceLimit)
|
||||
{
|
||||
Slip();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void Slip()
|
||||
{
|
||||
End();
|
||||
|
||||
if (OnSlipped != null)
|
||||
OnSlipped();
|
||||
}
|
||||
|
||||
/*
|
||||
private void Update()
|
||||
{
|
||||
if (Input.GetMouseButtonUp(0) && joint && joint.connectedBody)
|
||||
End();
|
||||
}*/
|
||||
|
||||
public void Attach(RaycastHit hit, bool fixedRotation = true)
|
||||
{
|
||||
Attach(hit.rigidbody, hit.point, hit.distance, fixedRotation);
|
||||
}
|
||||
|
||||
public void Attach(Rigidbody rigidbody, Vector3 point, float distance, bool fixedRotation)
|
||||
{
|
||||
if (!joint) CreateJoint();
|
||||
|
||||
if (fakeMass > 0)
|
||||
{
|
||||
originalMass = rigidbody.mass;
|
||||
rigidbody.mass = fakeMass;
|
||||
}
|
||||
|
||||
originalInterpolation = rigidbody.interpolation;
|
||||
rigidbody.interpolation = RigidbodyInterpolation.Interpolate;
|
||||
|
||||
joint.transform.position = point;
|
||||
joint.anchor = Vector3.zero;
|
||||
joint.transform.rotation = transform.rotation;
|
||||
//joint.targetRotation = Quaternion.identity;
|
||||
//joint.targetRotation = Quaternion.Inverse(transform.rotation);// Quaternion.LookRotation(transform.forward, transform.up);
|
||||
|
||||
joint.angularXMotion = joint.angularYMotion = joint.angularZMotion
|
||||
= fixedRotation ? ConfigurableJointMotion.Locked : ConfigurableJointMotion.Free;
|
||||
|
||||
JointDrive drive = new JointDrive();
|
||||
drive.positionSpring = k_Spring;
|
||||
drive.positionDamper = k_Damper;
|
||||
drive.maximumForce = Mathf.Infinity;
|
||||
|
||||
joint.xDrive = drive;
|
||||
joint.yDrive = drive;
|
||||
joint.zDrive = drive;
|
||||
|
||||
//joint.spring = k_Spring;
|
||||
//joint.damper = k_Damper;
|
||||
//joint.maxDistance = k_Distance;
|
||||
joint.connectedBody = rigidbody;
|
||||
|
||||
hitDistance = distance;
|
||||
}
|
||||
|
||||
public void End()
|
||||
{
|
||||
if (!joint.connectedBody)
|
||||
return;
|
||||
|
||||
if (fakeMass > 0)
|
||||
{
|
||||
var massSettable = joint.connectedBody.GetComponent<IDragRigidbodyReleaseMassSettable>();
|
||||
|
||||
if (massSettable != null)
|
||||
{
|
||||
joint.connectedBody.mass = massSettable.ReleaseMass;
|
||||
}
|
||||
else
|
||||
{
|
||||
joint.connectedBody.mass = originalMass;
|
||||
}
|
||||
}
|
||||
|
||||
joint.connectedBody.interpolation = originalInterpolation;
|
||||
|
||||
if (clampExitVelocity > 0)
|
||||
joint.connectedBody.velocity =
|
||||
Vector3.ClampMagnitude(joint.connectedBody.velocity, clampExitVelocity);
|
||||
|
||||
addedRotation = Quaternion.identity;
|
||||
|
||||
joint.connectedBody = null;
|
||||
|
||||
overrideTarget = false;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e26630301387ce5469cfa0fb478b201b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,63 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Nothke.Interaction.Items
|
||||
{
|
||||
public class RigidbodyInteractable : Interactable
|
||||
{
|
||||
public Rigidbody rb;
|
||||
public bool rotateAroundPoint;
|
||||
|
||||
[System.NonSerialized]
|
||||
public bool held;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (!rb)
|
||||
rb = GetComponent<Rigidbody>();
|
||||
}
|
||||
|
||||
public override void Use(InteractionController im)
|
||||
{
|
||||
base.Use(im);
|
||||
|
||||
DragRigidbody.e.Attach(im.hit, !rotateAroundPoint);
|
||||
DragRigidbody.e.OnSlipped += Unhold;
|
||||
}
|
||||
|
||||
public override void StartHold()
|
||||
{
|
||||
base.StartHold();
|
||||
manager.FreezeDetection();
|
||||
|
||||
held = true;
|
||||
|
||||
OnStartedHold();
|
||||
}
|
||||
|
||||
public override void EndHold()
|
||||
{
|
||||
base.EndHold();
|
||||
|
||||
if (!held)
|
||||
return;
|
||||
|
||||
DragRigidbody.e.End();
|
||||
|
||||
Unhold();
|
||||
}
|
||||
|
||||
void Unhold()
|
||||
{
|
||||
manager.UnfreezeDetection();
|
||||
manager.LockFreeLook(false);
|
||||
DragRigidbody.e.OnSlipped -= Unhold;
|
||||
held = false;
|
||||
OnEndedHold();
|
||||
}
|
||||
|
||||
protected virtual void OnStartedHold() { }
|
||||
protected virtual void OnEndedHold() { }
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cf9152fd8b7951445bef5e6f0778fd53
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user