Jamie Greunbaum 2bf76f34cd Oh, boy, there's a lot here.
- Added a functioning Modem.
- Added a destination sign at the Modem's destination location.
- Intro video transcripts are now optional in case files.
- Added a proper endgame handler for round 1.
- Fixed a lot of formatting for text between rounds.
- Fixed a bug that showed the wrong text if all round 3 markers are exhausted.
- Shortened time to detect improperly placed markers by just a bit.
2025-08-18 04:19:21 -04:00

114 lines
2.7 KiB
C#

using UdonSharp;
using UnityEngine;
using VRC.SDK3.UdonNetworkCalling;
using VRC.SDKBase;
using VRC.Udon;
using VRC.Udon.Common.Interfaces;
[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]
public class Modem : UdonSharpBehaviour
{
[SerializeField] private Modem _ModemDestination;
[Space]
[SerializeField] private AudioManager _AudioManager;
[SerializeField] private Animator _ModemAnimator;
[SerializeField] private Animator _ModemDestinationAnimator;
[UdonSynced] private string[] _EnteredPlayers = new string[MAX_PLAYERS_IN_MODEM];
private const int MAX_PLAYERS_IN_MODEM = 10;
public void ResetModem()
{
_ModemAnimator.SetBool("Teleport", false);
_ModemDestinationAnimator.SetBool("Teleport", false);
}
public override void OnPlayerTriggerEnter(VRCPlayerApi Player)
{
for (int i = 0; i < MAX_PLAYERS_IN_MODEM; i++)
{
if (_EnteredPlayers[i] == null)
{
_EnteredPlayers[i] = Player.displayName;
break;
}
}
RequestSerialization();
base.OnPlayerTriggerEnter(Player);
}
public override void OnPlayerTriggerExit(VRCPlayerApi Player)
{
for (int i = 0; i < MAX_PLAYERS_IN_MODEM; i++)
{
if (_EnteredPlayers[i] == Player.displayName)
{
_EnteredPlayers[i] = null;
break;
}
}
RequestSerialization();
base.OnPlayerTriggerExit(Player);
}
public void BeginTeleportProcess()
{
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All,
"PlaySFX", SFXEventType.ModemOperation);
_ModemAnimator.SetBool("Teleport", true);
_ModemDestinationAnimator.SetBool("Teleport", true);
SendCustomEventDelayedSeconds(nameof(TeleportAllPlayers), 4.0f);
SendCustomEventDelayedSeconds(nameof(ResetAnimations), 6.0f);
}
public void TeleportAllPlayers()
{
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(TeleportLocalPlayerIfInModem));
}
public void ResetAnimations()
{
_ModemAnimator.SetBool("Teleport", false);
_ModemDestinationAnimator.SetBool("Teleport", false);
}
[NetworkCallable]
public void TeleportLocalPlayerIfInModem()
{
for (int j = 0; j < _EnteredPlayers.Length; j++)
{
if (_EnteredPlayers[j] == Networking.LocalPlayer.displayName)
{
TeleportToModemDestination();
break;
}
}
}
private void TeleportToModemDestination()
{
Vector3 DeltaVector = Networking.LocalPlayer.GetPosition() - transform.position;
Quaternion DeltaRotation = _ModemDestination.transform.rotation * Quaternion.Inverse(transform.rotation);
Vector3 DestinationVectorRotated = DeltaRotation * DeltaVector.normalized;
Vector3 DestinationPositionDelta = DestinationVectorRotated * DeltaVector.magnitude;
Networking.LocalPlayer.TeleportTo(
_ModemDestination.transform.position + DestinationPositionDelta,
DeltaRotation * Networking.LocalPlayer.GetRotation());
}
}