- Camera follower will now track the upper-midsections of VRChat players.

- Camera tracking now has a follow speed setting.
- Camera anchor FOV scaler is now a separate object.
- Camera overlays now overlay properly once again.
- Implemented a much better check for whether a camera was detached.
- Improved code that detects when a game is over, and why it ended.
- Tweaked ending camera animation timing.
This commit is contained in:
2026-03-21 01:02:39 -04:00
parent 6b376463ba
commit 0b6a8440fc
8 changed files with 423 additions and 166 deletions
@@ -1,7 +1,6 @@
using UdonSharp;
using UnityEngine;
using UnityEngine.Video;
using VRC.SDK3.Data;
using VRC.SDK3.UdonNetworkCalling;
using VRC.SDKBase;
@@ -96,6 +95,8 @@ public class GameManagerRound3 : GameManagerBase
_CameraControllerRound3.InitialiseCameras();
_CameraControllerRound3.PlayIFeelGood(true);
DeinitialiseGameplayCameraFollowers();
DeinitialiseEndingCameraFollowers();
RequestSerialization();
}
@@ -200,6 +201,8 @@ public class GameManagerRound3 : GameManagerBase
_CameraControllerRound3.DisableAllSwitchers();
_CameraControllerRound3.HostPlayerTimerToggle.Activate = false;
_CameraControllerRound3.ActivatePlayfieldSwitchTriggerGroup = true;
InitialiseGameplayCameraFollowers();
GetCurrentMarker().SendCustomNetworkEvent(NetworkEventTarget.Owner, "Activated", true);
_EndingPlayer.LoadRandomVideo();
@@ -231,7 +234,7 @@ public class GameManagerRound3 : GameManagerBase
_Timer--;
if (_Timer < 0)
{
SendCustomNetworkEvent(NetworkEventTarget.Owner, nameof(GameHasBeenLost), false);
SendCustomNetworkEvent(NetworkEventTarget.Owner, nameof(GameIsOver), false, false);
return;
}
@@ -252,7 +255,7 @@ public class GameManagerRound3 : GameManagerBase
SuccessCounter++;
if (SuccessCounter >= MAX_SUCCESS_COUNT)
{
GameHasBeenWon();
GameIsOver(true, false);
}
else
{
@@ -323,7 +326,7 @@ public class GameManagerRound3 : GameManagerBase
if (ActiveMarker >= FloorMap.MAX_SELECTED_COUNTRIES)
{
// If we ran out of countries, lose the game here.
SendCustomNetworkEvent(NetworkEventTarget.Owner, nameof(GameHasBeenLost), true);
SendCustomNetworkEvent(NetworkEventTarget.Owner, nameof(GameIsOver), false, true);
return;
}
@@ -335,7 +338,21 @@ public class GameManagerRound3 : GameManagerBase
}
[NetworkCallable]
public void GameHasBeenWon()
public void GameIsOver(bool GameWon, bool HaveWeRunOutOfMarkers)
{
if (GameWon)
{
_GameHasBeenWon();
}
else
{
_GameHasBeenLost(HaveWeRunOutOfMarkers);
}
InitialiseEndingCameraFollowers();
}
private void _GameHasBeenWon()
{
_RunTimer = false;
@@ -380,18 +397,17 @@ public class GameManagerRound3 : GameManagerBase
_NewspaperPublicDisplay.Activate(true);
}
[NetworkCallable]
public void GameHasBeenLost(bool RanOutOfMarkers)
private void _GameHasBeenLost(bool HaveWeRunOutOfMarkers)
{
_RunTimer = false;
if (_GameStatus == GameStatus.Begin)
{
GameStatusUpdate(RanOutOfMarkers ? GameStatus.RanOutOfMarkers : GameStatus.RanOutOfTime);
GameStatusUpdate(HaveWeRunOutOfMarkers ? GameStatus.RanOutOfMarkers : GameStatus.RanOutOfTime);
HostCardBetweenRoundsInterface GameLossInterface =
(HostCardBetweenRoundsInterface)GetHostCardInterface(RoundSegmentType.BetweenSegments);
GameLossInterface.HeaderUI.text = "The player has run out of " + (RanOutOfMarkers ? "markers" : "time") + ".";
GameLossInterface.HeaderUI.text = "The player has run out of " + (HaveWeRunOutOfMarkers ? "markers" : "time") + ".";
GameLossInterface.CommentUI.text =
"- Found " + SuccessCounter + " countries in " + TIMER_LENGTH + " seconds.\n\n" +
"- There's one more thing I want you to do for us. You know what it is...";
@@ -477,7 +493,7 @@ public class GameManagerRound3 : GameManagerBase
_EndingPlayer.PlayVideo = false;
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All, "FadeOutMusic");
_CameraControllerRound3.SwitchToOverheadCamera();
_CameraControllerRound3.SwitchToFrontCamera();
_CameraControllerRound3.DeinitialiseCameras();
_CaseManager.EndGame();
@@ -546,6 +562,30 @@ public class GameManagerRound3 : GameManagerBase
return CurrentWinner[0];
}
private void InitialiseGameplayCameraFollowers()
{
_CameraControllerRound3.FrontCamera_FollowPlayers(new string[1] { GetRound3PlayerName() });
}
private void DeinitialiseGameplayCameraFollowers()
{
_CameraControllerRound3.FrontCamera_StopFollowingPlayers();
}
private void InitialiseEndingCameraFollowers()
{
string[] PlayerFollows = new string[2] {
_CaseManager.GetHostOwner().displayName,
GetRound3PlayerName()
};
_CameraControllerRound3.FrontCamera_FollowPlayers(PlayerFollows);
_CameraControllerRound3.OverheadCamera_FollowPlayers(PlayerFollows);
}
private void DeinitialiseEndingCameraFollowers()
{
_CameraControllerRound3.OverheadCamera_StopFollowingPlayers();
}
protected override HostCardInterfaceBase GetHostCardInterface(RoundSegmentType Question)
{