mirror of
https://github.com/hanetzer/sdraw_mods_cvr.git
synced 2025-09-03 18:39:23 +00:00
246 lines
9.5 KiB
C#
246 lines
9.5 KiB
C#
using ABI.CCK.Components;
|
|
using ABI_RC.Core.InteractionSystem;
|
|
using ABI_RC.Core.Player;
|
|
using ABI_RC.Systems.IK;
|
|
using ABI_RC.Systems.Movement;
|
|
using UnityEngine;
|
|
|
|
namespace ml_ppu
|
|
{
|
|
class PickUpManager : MonoBehaviour
|
|
{
|
|
public static PickUpManager Instance { get; private set; } = null;
|
|
|
|
Collider m_holderPointA = null;
|
|
CVRPointer m_holderPointerA = null;
|
|
Collider m_holderPointB = null;
|
|
CVRPointer m_holderPointerB = null;
|
|
|
|
CapsuleCollider m_collider = null;
|
|
Matrix4x4 m_colliderOffSet;
|
|
Matrix4x4 m_avatarOffSet;
|
|
|
|
Transform m_hips = null;
|
|
Transform m_armLeft = null;
|
|
Transform m_armRight = null;
|
|
bool m_ready = false;
|
|
bool m_held = false;
|
|
|
|
Vector3 m_lastPosition;
|
|
Vector3 m_velocity;
|
|
|
|
void Awake()
|
|
{
|
|
if(Instance != null)
|
|
{
|
|
DestroyImmediate(this);
|
|
return;
|
|
}
|
|
|
|
Instance = this;
|
|
DontDestroyOnLoad(this);
|
|
}
|
|
|
|
void Start()
|
|
{
|
|
GameEvents.OnAvatarSetup.AddListener(this.OnAvatarSetup);
|
|
GameEvents.OnAvatarClear.AddListener(this.OnAvatarClear);
|
|
GameEvents.OnIKScaling.AddListener(this.OnIKScaling);
|
|
GameEvents.OnWorldPreSpawn.AddListener(this.OnWorldPreSpawn);
|
|
GameEvents.OnSeatPreSit.AddListener(this.OnSeatPreSit);
|
|
|
|
Settings.OnEnabledChanged.AddListener(this.OnEnabledChanged);
|
|
}
|
|
|
|
void OnDestroy()
|
|
{
|
|
if(Instance == this)
|
|
Instance = null;
|
|
|
|
GameEvents.OnAvatarSetup.RemoveListener(this.OnAvatarSetup);
|
|
GameEvents.OnAvatarClear.RemoveListener(this.OnAvatarClear);
|
|
GameEvents.OnIKScaling.RemoveListener(this.OnIKScaling);
|
|
GameEvents.OnWorldPreSpawn.RemoveListener(this.OnWorldPreSpawn);
|
|
GameEvents.OnSeatPreSit.RemoveListener(this.OnSeatPreSit);
|
|
|
|
Settings.OnEnabledChanged.RemoveListener(this.OnEnabledChanged);
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if(m_ready)
|
|
{
|
|
if(!m_held)
|
|
{
|
|
if((m_holderPointA != null) && !m_collider.bounds.Intersects(m_holderPointA.bounds))
|
|
{
|
|
m_holderPointA = null;
|
|
m_holderPointerA = null;
|
|
}
|
|
|
|
Vector3 l_armsMidPoint = (m_armLeft.position + m_armRight.position) * 0.5f;
|
|
Quaternion l_avatarRot = PlayerSetup.Instance._avatar.transform.rotation;
|
|
|
|
m_collider.transform.position = Vector3.zero;
|
|
m_collider.transform.rotation = Quaternion.identity;
|
|
m_collider.transform.up = Quaternion.Inverse(l_avatarRot) * (l_armsMidPoint - m_hips.position).normalized;
|
|
|
|
m_collider.transform.position = m_hips.position;
|
|
m_collider.transform.rotation = l_avatarRot * m_collider.transform.rotation;
|
|
}
|
|
else
|
|
{
|
|
// Check if our points are still valid
|
|
if((m_holderPointA != null) && m_holderPointerA.isActiveAndEnabled && (m_holderPointB != null) && m_holderPointerB.isActiveAndEnabled && !ModSupport.IsRagdolled())
|
|
{
|
|
Matrix4x4 l_midPoint = Matrix4x4.TRS(
|
|
Vector3.Lerp(m_holderPointA.transform.position, m_holderPointB.transform.position, 0.5f),
|
|
Quaternion.Slerp(m_holderPointA.transform.rotation, m_holderPointB.transform.rotation, 0.5f),
|
|
Vector3.one
|
|
);
|
|
Matrix4x4 l_colliderMat = l_midPoint * m_colliderOffSet;
|
|
m_collider.transform.position = l_colliderMat.GetPosition();
|
|
m_collider.transform.rotation = l_colliderMat.rotation;
|
|
|
|
Matrix4x4 l_avatarMat = l_colliderMat * m_avatarOffSet;
|
|
BetterBetterCharacterController.Instance.TeleportPlayerTo(l_avatarMat.GetPosition(), l_avatarMat.rotation.eulerAngles, true, false);
|
|
|
|
Vector3 l_position = l_avatarMat.GetPosition();
|
|
m_velocity = (l_position - m_lastPosition) / Time.deltaTime;
|
|
m_lastPosition = l_position;
|
|
}
|
|
else
|
|
{
|
|
m_holderPointA = null;
|
|
m_holderPointerA = null;
|
|
m_holderPointB = null;
|
|
m_holderPointerB = null;
|
|
m_held = false;
|
|
|
|
BetterBetterCharacterController.Instance.SetVelocity(m_velocity * Settings.VelocityMultiplier);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void OnAvatarSetup()
|
|
{
|
|
Animator l_animator = PlayerSetup.Instance._animator;
|
|
if((l_animator != null) && l_animator.isHuman)
|
|
{
|
|
IKSystem.Instance.SetAvatarPose(IKSystem.AvatarPose.TPose);
|
|
PlayerSetup.Instance._avatar.transform.localPosition = Vector3.zero;
|
|
PlayerSetup.Instance._avatar.transform.localRotation = Quaternion.identity;
|
|
|
|
m_hips = l_animator.GetBoneTransform(HumanBodyBones.Hips);
|
|
m_armLeft = l_animator.GetBoneTransform(HumanBodyBones.LeftUpperArm);
|
|
m_armRight = l_animator.GetBoneTransform(HumanBodyBones.RightUpperArm);
|
|
|
|
if((m_hips != null) && (m_armLeft != null) && (m_armRight != null))
|
|
{
|
|
Vector3 l_hipsPos = (PlayerSetup.Instance.transform.GetMatrix().inverse * m_hips.GetMatrix()).GetPosition();
|
|
Vector3 l_armPos = (PlayerSetup.Instance.transform.GetMatrix().inverse * m_armLeft.GetMatrix()).GetPosition();
|
|
|
|
m_collider = new GameObject("[Collider]").AddComponent<CapsuleCollider>();
|
|
m_collider.transform.parent = this.transform;
|
|
m_collider.isTrigger = true;
|
|
m_collider.height = Vector3.Distance(l_hipsPos, new Vector3(0f, l_armPos.y, l_armPos.z));
|
|
m_collider.radius = new Vector2(l_armPos.x, l_armPos.z).magnitude;
|
|
m_collider.center = new Vector3(0f, m_collider.height * 0.5f, 0f);
|
|
m_collider.gameObject.AddComponent<GrabDetector>();
|
|
|
|
m_ready = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
void OnAvatarClear()
|
|
{
|
|
m_ready = false;
|
|
m_held = false;
|
|
|
|
if(m_collider != null)
|
|
{
|
|
UnityEngine.Object.Destroy(m_collider.gameObject);
|
|
m_collider = null;
|
|
}
|
|
m_holderPointA = null;
|
|
m_holderPointerA = null;
|
|
m_holderPointB = null;
|
|
m_holderPointerB = null;
|
|
}
|
|
|
|
void OnIKScaling(float p_scale)
|
|
{
|
|
if(m_ready)
|
|
m_collider.transform.localScale = Vector3.one * p_scale;
|
|
}
|
|
|
|
void OnWorldPreSpawn()
|
|
{
|
|
if(m_ready && m_held)
|
|
{
|
|
m_held = false;
|
|
m_holderPointA = null;
|
|
m_holderPointerA = null;
|
|
m_holderPointB = null;
|
|
m_holderPointerB = null;
|
|
}
|
|
}
|
|
|
|
void OnSeatPreSit(CVRSeat p_seat)
|
|
{
|
|
if(!p_seat.occupied && m_ready && m_held)
|
|
{
|
|
m_held = false;
|
|
m_holderPointA = null;
|
|
m_holderPointerA = null;
|
|
m_holderPointB = null;
|
|
m_holderPointerB = null;
|
|
}
|
|
}
|
|
|
|
void OnEnabledChanged(bool p_state)
|
|
{
|
|
if(!p_state && m_ready && m_held)
|
|
{
|
|
m_held = false;
|
|
m_holderPointA = null;
|
|
m_holderPointerA = null;
|
|
m_holderPointB = null;
|
|
m_holderPointerB = null;
|
|
}
|
|
}
|
|
|
|
internal void OnGrabDetected(Collider p_collider, CVRPointer p_pointer)
|
|
{
|
|
if(m_ready && !m_held && CVRWorld.Instance.allowFlying && !ModSupport.IsRagdolled())
|
|
{
|
|
if(m_holderPointA == null)
|
|
{
|
|
m_holderPointA = p_collider;
|
|
m_holderPointerA = p_pointer;
|
|
}
|
|
else
|
|
{
|
|
if((m_holderPointB == null) && (m_holderPointA != p_collider) && (m_holderPointA.transform.root == p_collider.transform.root))
|
|
{
|
|
m_holderPointB = p_collider;
|
|
m_holderPointerB = p_pointer;
|
|
|
|
// Remember offsets
|
|
Matrix4x4 l_midPoint = Matrix4x4.TRS(
|
|
Vector3.Lerp(m_holderPointA.transform.position, m_holderPointB.transform.position, 0.5f),
|
|
Quaternion.Slerp(m_holderPointA.transform.rotation, m_holderPointB.transform.rotation, 0.5f),
|
|
Vector3.one
|
|
);
|
|
m_colliderOffSet = l_midPoint.inverse * m_collider.transform.GetMatrix();
|
|
m_avatarOffSet = m_collider.transform.GetMatrix().inverse * PlayerSetup.Instance._avatar.transform.GetMatrix();
|
|
m_lastPosition = PlayerSetup.Instance._avatar.transform.position;
|
|
m_held = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|