173 lines
5.1 KiB
C#
173 lines
5.1 KiB
C#
using System;
|
|
using UnityEngine;
|
|
using VRC.SDKBase;
|
|
|
|
namespace VRC.SDK3.ClientSim
|
|
{
|
|
[AddComponentMenu("")]
|
|
public class ClientSimPickupHelper : ClientSimBehaviour, IClientSimPickupable
|
|
{
|
|
private Rigidbody _rigidbody;
|
|
private VRC_Pickup _pickup;
|
|
|
|
private VRCPlayerApi _heldPlayer;
|
|
private VRC_Pickup.PickupHand _heldHand;
|
|
private Action<IClientSimPickupable> _forceDropHandler;
|
|
|
|
public static void InitializePickup(VRC_Pickup pickup)
|
|
{
|
|
ClientSimPickupHelper previousHelper = pickup.gameObject.GetComponent<ClientSimPickupHelper>();
|
|
if (previousHelper != null)
|
|
{
|
|
DestroyImmediate(previousHelper);
|
|
pickup.LogWarning($"Destroying old pickup helper on object: {Tools.GetGameObjectPath(pickup.gameObject)}");
|
|
}
|
|
|
|
ClientSimPickupHelper helper = pickup.gameObject.AddComponent<ClientSimPickupHelper>();
|
|
helper.SetPickup(pickup);
|
|
}
|
|
|
|
public static void ForceDrop(VRC_Pickup pickup)
|
|
{
|
|
ClientSimPickupHelper helper = pickup.GetComponent<ClientSimPickupHelper>();
|
|
if (helper)
|
|
{
|
|
helper._forceDropHandler?.Invoke(helper);
|
|
}
|
|
}
|
|
|
|
public static VRCPlayerApi GetCurrentPlayer(VRC_Pickup pickup)
|
|
{
|
|
ClientSimPickupHelper helper = pickup.GetComponent<ClientSimPickupHelper>();
|
|
|
|
if (!helper)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return helper.GetHoldingPlayer();
|
|
}
|
|
|
|
public static VRC_Pickup.PickupHand GetPickupHand(VRC_Pickup pickup)
|
|
{
|
|
ClientSimPickupHelper helper = pickup.GetComponent<ClientSimPickupHelper>();
|
|
if (helper)
|
|
{
|
|
return helper._heldHand;
|
|
}
|
|
return VRC_Pickup.PickupHand.None;
|
|
}
|
|
|
|
public static void PickupDestroy(VRC_Pickup pickup)
|
|
{
|
|
ForceDrop(pickup);
|
|
}
|
|
|
|
public static void PlayHapticForPickup(VRC_Pickup obj, float duration, float amplitude, float frequency)
|
|
{
|
|
VRCPlayerApi player = obj.currentPlayer;
|
|
VRC_Pickup.PickupHand hand = obj.currentHand;
|
|
if (Utilities.IsValid(player) && hand != VRC_Pickup.PickupHand.None)
|
|
{
|
|
player.PlayHapticEventInHand(obj.currentHand, duration, amplitude, frequency);
|
|
}
|
|
}
|
|
|
|
private void SetPickup(VRC_Pickup pickup)
|
|
{
|
|
_pickup = pickup;
|
|
_rigidbody = GetComponent<Rigidbody>();
|
|
}
|
|
|
|
|
|
#region IClientSimInteractible
|
|
|
|
public float GetProximity()
|
|
{
|
|
return _pickup.proximity;
|
|
}
|
|
|
|
public bool CanInteract()
|
|
{
|
|
return _pickup.pickupable;
|
|
}
|
|
|
|
public string GetInteractText()
|
|
{
|
|
if (!string.IsNullOrEmpty(_pickup.InteractionText))
|
|
{
|
|
return _pickup.InteractionText;
|
|
}
|
|
|
|
return AutoHold() ? "Equip" : "Hold to Grab";
|
|
}
|
|
|
|
public Vector3 GetInteractTextPlacement()
|
|
{
|
|
// VRChatBug: Tooltips always ignore the tooltipPlacement transform and instead place the tooltip at the top
|
|
// of the first collider on the object.
|
|
return ClientSimTooltip.GetToolTipPosition(gameObject);
|
|
}
|
|
|
|
public void Interact() { }
|
|
|
|
#endregion
|
|
|
|
#region IClientSimPickupable
|
|
|
|
public void Pickup(VRCPlayerApi player, VRC_Pickup.PickupHand heldHand, Action<IClientSimPickupable> forceDropHandler)
|
|
{
|
|
if (IsHeld())
|
|
{
|
|
return;
|
|
}
|
|
_heldPlayer = player;
|
|
_heldHand = heldHand;
|
|
_forceDropHandler = forceDropHandler;
|
|
}
|
|
|
|
public void Drop(VRCPlayerApi player)
|
|
{
|
|
if (GetHoldingPlayer() != player)
|
|
{
|
|
return;
|
|
}
|
|
_heldPlayer = null;
|
|
_heldHand = VRC_Pickup.PickupHand.None;
|
|
_forceDropHandler = null;
|
|
}
|
|
|
|
public bool IsHeld() => Utilities.IsValid(_heldPlayer);
|
|
|
|
public VRCPlayerApi GetHoldingPlayer() => IsHeld() ? _heldPlayer : null;
|
|
|
|
public bool AutoHold() => _pickup.AutoHold is VRC_Pickup.AutoHoldMode.Yes or VRC_Pickup.AutoHoldMode.Sometimes;
|
|
|
|
public GameObject GetGameObject() => gameObject;
|
|
|
|
public Transform GetTransform() => transform;
|
|
|
|
public Rigidbody GetRigidbody() => _rigidbody;
|
|
|
|
public VRC_Pickup GetPickup() => _pickup;
|
|
|
|
public VRC_Pickup.PickupOrientation GetOrientation() => _pickup.orientation;
|
|
|
|
public Transform GetGunLocation() => _pickup.ExactGun;
|
|
|
|
public Transform GetGripLocation() => _pickup.ExactGrip;
|
|
|
|
public float GetThrowVelocityBoostScale() => _pickup.ThrowVelocityBoostScale;
|
|
|
|
public bool AllowManipulation() => _pickup.allowManipulationWhenEquipped;
|
|
|
|
#endregion
|
|
|
|
// TODO display use text after picking up a pickup.
|
|
public string PickupText()
|
|
{
|
|
return _pickup.UseText;
|
|
}
|
|
}
|
|
}
|