Files
2026-06-07 16:58:24 +01:00

163 lines
4.4 KiB
C#

using System.Reflection;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;
namespace VRC.SDK3.ClientSim
{
[AddComponentMenu("")]
public class ClientSimUdonHelper :
ClientSimPositionSyncedHelperBase,
IClientSimInteractable,
IClientSimPickupHandler,
IClientSimStationHandler,
IClientSimSyncableHandler
{
private IClientSimUdonManager _udonManager;
private UdonBehaviour _udonBehaviour;
private static readonly FieldInfo _isReady =
typeof(UdonBehaviour).GetField("_isReady", (BindingFlags.Instance | BindingFlags.NonPublic));
public void Initialize(
UdonBehaviour udonBehaviour,
IClientSimUdonManager udonManager,
IClientSimSyncedObjectManager syncedObjectManager,
bool isReady)
{
_udonBehaviour = udonBehaviour;
#pragma warning disable 618
SyncPosition = _udonBehaviour.SynchronizePosition;
#pragma warning restore 618
SetIsReady(isReady);
_udonManager = udonManager;
_udonManager.AddUdonBehaviour(_udonBehaviour);
// Ensure that SyncPosition is set before calling this.
base.Initialize(syncedObjectManager);
}
private void Start()
{
// Catch Helper not initialized.
if (_udonBehaviour == null)
{
this.LogWarning($"Destroying uninitialized Helper. Object: {Tools.GetGameObjectPath(gameObject)}");
DestroyImmediate(this);
}
}
protected override void OnDestroy()
{
base.OnDestroy();
// Nullable needed for uninitialized case.
_udonManager?.RemoveUdonBehaviour(_udonBehaviour);
}
private void SetIsReady(bool isReady)
{
_isReady.SetValue(_udonBehaviour, isReady);
}
public void OnReady()
{
SetIsReady(true);
}
public UdonBehaviour GetUdonBehaviour()
{
return _udonBehaviour;
}
#region IClientSimSyncableHandler
public void OnOwnershipTransferred(int ownerID)
{
_udonBehaviour.RunEvent("_onOwnershipTransferred", ("Player", VRCPlayerApi.GetPlayerById(ownerID)));
}
#endregion
#region IClientSimInteractable
public float GetProximity()
{
return _udonBehaviour.proximity;
}
public bool CanInteract()
{
return _udonBehaviour.IsInteractive;
}
public string GetInteractText()
{
return _udonBehaviour.interactText;
}
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.
//check if this object has already been destroyed, we can't just do a null check because that still throws a destroyed object error in unity
if (!Utilities.IsValid(this))
{
return Vector3.zero;
}
return ClientSimTooltip.GetToolTipPosition(gameObject);
}
public void Interact()
{
_udonBehaviour.Interact();
}
#endregion
#region IClientSimPickupable
public void OnPickup()
{
_udonBehaviour.OnPickup();
}
public void OnDrop()
{
_udonBehaviour.OnDrop();
}
public void OnPickupUseDown()
{
_udonBehaviour.OnPickupUseDown();
}
public void OnPickupUseUp()
{
_udonBehaviour.OnPickupUseUp();
}
#endregion
#region IClientSimStationHandler
public void OnStationEnter(VRCStation station)
{
VRC.SDK3.Components.VRCStation sdk3Station = station as VRC.SDK3.Components.VRCStation;
_udonBehaviour.RunEvent(sdk3Station.OnLocalPlayerEnterStation, ("Player", Networking.LocalPlayer));
}
public void OnStationExit(VRCStation station)
{
VRC.SDK3.Components.VRCStation sdk3Station = station as VRC.SDK3.Components.VRCStation;
_udonBehaviour.RunEvent(sdk3Station.OnLocalPlayerExitStation, ("Player", Networking.LocalPlayer));
}
#endregion
}
}