- 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
+185 -83
View File
@@ -44,7 +44,7 @@ MonoBehaviour:
Data:
- Name:
Entry: 12
Data: 10
Data: 12
- Name:
Entry: 7
Data:
@@ -329,7 +329,7 @@ MonoBehaviour:
Data: 20|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 3
Data: 2
- Name:
Entry: 7
Data: 21|UnityEngine.SpaceAttribute, UnityEngine.CoreModule
@@ -341,7 +341,61 @@ MonoBehaviour:
Data:
- Name:
Entry: 7
Data: 22|UnityEngine.TooltipAttribute, UnityEngine.CoreModule
Data: 22|UnityEngine.SerializeField, UnityEngine.CoreModule
- Name:
Entry: 8
Data:
- Name:
Entry: 13
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 7
Data:
- Name: $k
Entry: 1
Data: CameraFOVScaler
- Name: $v
Entry: 7
Data: 23|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: CameraFOVScaler
- Name: <UserType>k__BackingField
Entry: 9
Data: 19
- Name: <SystemType>k__BackingField
Entry: 9
Data: 19
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
- Name:
Entry: 6
Data:
- Name:
Entry: 8
Data:
- Name: <IsSerialized>k__BackingField
Entry: 5
Data: true
- Name: _fieldAttributes
Entry: 7
Data: 24|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 2
- Name:
Entry: 7
Data: 25|UnityEngine.TooltipAttribute, UnityEngine.CoreModule
- Name: tooltip
Entry: 1
Data: Changing the Z scale of this object will change the FOV of the attached
@@ -351,7 +405,7 @@ MonoBehaviour:
Data:
- Name:
Entry: 7
Data: 23|UnityEngine.SerializeField, UnityEngine.CoreModule
Data: 26|UnityEngine.SerializeField, UnityEngine.CoreModule
- Name:
Entry: 8
Data:
@@ -375,13 +429,13 @@ MonoBehaviour:
Data: _AttachedCameraIndex
- Name: $v
Entry: 7
Data: 24|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
Data: 27|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: _AttachedCameraIndex
- Name: <UserType>k__BackingField
Entry: 7
Data: 25|System.RuntimeType, mscorlib
Data: 28|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: System.Int32, mscorlib
@@ -390,7 +444,7 @@ MonoBehaviour:
Data:
- Name: <SystemType>k__BackingField
Entry: 9
Data: 25
Data: 28
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
@@ -405,13 +459,13 @@ MonoBehaviour:
Data: false
- Name: _fieldAttributes
Entry: 7
Data: 26|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
Data: 29|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 1
- Name:
Entry: 7
Data: 27|UdonSharp.UdonSyncedAttribute, UdonSharp.Runtime
Data: 30|UdonSharp.UdonSyncedAttribute, UdonSharp.Runtime
- Name:
Entry: 8
Data:
@@ -433,72 +487,18 @@ MonoBehaviour:
- Name: $k
Entry: 1
Data: _AttachedCamera
- Name: $v
Entry: 7
Data: 28|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: _AttachedCamera
- Name: <UserType>k__BackingField
Entry: 7
Data: 29|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: UnityEngine.Camera, UnityEngine.CoreModule
- Name:
Entry: 8
Data:
- Name: <SystemType>k__BackingField
Entry: 9
Data: 29
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
- Name:
Entry: 6
Data:
- Name:
Entry: 8
Data:
- Name: <IsSerialized>k__BackingField
Entry: 5
Data: false
- Name: _fieldAttributes
Entry: 7
Data: 30|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 0
- Name:
Entry: 13
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 7
Data:
- Name: $k
Entry: 1
Data: _FollowedPlayerNames
- Name: $v
Entry: 7
Data: 31|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: _FollowedPlayerNames
Data: _AttachedCamera
- Name: <UserType>k__BackingField
Entry: 7
Data: 32|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: System.String[], mscorlib
Data: UnityEngine.Camera, UnityEngine.CoreModule
- Name:
Entry: 8
Data:
@@ -540,19 +540,25 @@ MonoBehaviour:
Data:
- Name: $k
Entry: 1
Data: _FollowedPlayerNames_Cache
Data: _FollowedPlayerNames
- Name: $v
Entry: 7
Data: 34|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: _FollowedPlayerNames_Cache
Data: _FollowedPlayerNames
- Name: <UserType>k__BackingField
Entry: 9
Data: 32
Entry: 7
Data: 35|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: System.String[], mscorlib
- Name:
Entry: 8
Data:
- Name: <SystemType>k__BackingField
Entry: 9
Data: 32
Data: 35
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
@@ -567,7 +573,7 @@ MonoBehaviour:
Data: false
- Name: _fieldAttributes
Entry: 7
Data: 35|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
Data: 36|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 0
@@ -588,25 +594,19 @@ MonoBehaviour:
Data:
- Name: $k
Entry: 1
Data: _FollowedPlayers
Data: _FollowedPlayerNames_Cache
- Name: $v
Entry: 7
Data: 36|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
Data: 37|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: _FollowedPlayers
Data: _FollowedPlayerNames_Cache
- Name: <UserType>k__BackingField
Entry: 7
Data: 37|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: VRC.SDKBase.VRCPlayerApi[], VRCSDKBase
- Name:
Entry: 8
Data:
Entry: 9
Data: 35
- Name: <SystemType>k__BackingField
Entry: 9
Data: 37
Data: 35
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
@@ -637,6 +637,108 @@ MonoBehaviour:
- Name:
Entry: 8
Data:
- Name:
Entry: 7
Data:
- Name: $k
Entry: 1
Data: _FollowedPlayers
- Name: $v
Entry: 7
Data: 39|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: _FollowedPlayers
- Name: <UserType>k__BackingField
Entry: 7
Data: 40|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: VRC.SDKBase.VRCPlayerApi[], VRCSDKBase
- Name:
Entry: 8
Data:
- Name: <SystemType>k__BackingField
Entry: 9
Data: 40
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
- Name:
Entry: 6
Data:
- Name:
Entry: 8
Data:
- Name: <IsSerialized>k__BackingField
Entry: 5
Data: false
- Name: _fieldAttributes
Entry: 7
Data: 41|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 0
- Name:
Entry: 13
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 7
Data:
- Name: $k
Entry: 1
Data: _CameraFollowSpeed
- Name: $v
Entry: 7
Data: 42|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: _CameraFollowSpeed
- Name: <UserType>k__BackingField
Entry: 9
Data: 8
- Name: <SystemType>k__BackingField
Entry: 9
Data: 8
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
- Name:
Entry: 6
Data:
- Name:
Entry: 8
Data:
- Name: <IsSerialized>k__BackingField
Entry: 5
Data: false
- Name: _fieldAttributes
Entry: 7
Data: 43|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 0
- Name:
Entry: 13
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 13
Data:
+45 -16
View File
@@ -2,7 +2,6 @@
using CameraSystem;
using MMMaellon.LightSync;
using UdonSharp;
using UnityEditor.Overlays;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon.Common;
@@ -17,8 +16,9 @@ public class CameraAnchor : UdonSharpBehaviour
[SerializeField] private float NearClippingPlane = 0.3f;
[SerializeField] private float FarClippingPlane = 1000.0f;
[Space]
[Tooltip("Changing the Z scale of this object will change the FOV of the attached camera.")]
[SerializeField] private Transform CameraRoot;
[Tooltip("Changing the Z scale of this object will change the FOV of the attached camera.")]
[SerializeField] private Transform CameraFOVScaler;
[UdonSynced] private int _AttachedCameraIndex = -1;
@@ -26,19 +26,23 @@ public class CameraAnchor : UdonSharpBehaviour
private string[] _FollowedPlayerNames = new string[0];
private string[] _FollowedPlayerNames_Cache = new string[0];
private VRCPlayerApi[] _FollowedPlayers = new VRCPlayerApi[0];
private float _CameraFollowSpeed = 1.0f;
void LateUpdate()
void Update()
{
if (_AttachedCamera)
{
if (CameraRoot.childCount <= 0)
if (_AttachedCamera.transform.parent != CameraRoot)
{
Debug.Log("[CameraAnchor] Camera has been detached from " + gameObject.name + ".");
_AttachedCamera = null;
_AttachedCameraIndex = -1;
RequestSerialization();
}
else
{
_AttachedCamera.fieldOfView = FOV * CameraRoot.transform.localScale.z;
_AttachedCamera.fieldOfView = FOV * CameraFOVScaler.transform.localScale.z;
}
}
@@ -57,8 +61,15 @@ public class CameraAnchor : UdonSharpBehaviour
(LeftEyePosition.y + RightEyePosition.y + LeftFootPosition.y + RightFootPosition.y) / 4.0f,
(LeftEyePosition.z + RightEyePosition.z + LeftFootPosition.z + RightFootPosition.z) / 4.0f);
}
Vector3 CentroidAverage = CentroidSum / _FollowedPlayers.Length;
CameraRoot.LookAt(CentroidSum / _FollowedPlayers.Length, Vector3.up);
Vector3 LookDirection = (CentroidAverage - transform.position).normalized;
CameraRoot.transform.rotation = Quaternion.LookRotation(
Vector3.Lerp(
CameraRoot.transform.forward,
Vector3.RotateTowards(CameraRoot.transform.forward, LookDirection, 10.0f, 0.0f),
_CameraFollowSpeed / 10.0f)
);
}
else
{
@@ -66,6 +77,7 @@ public class CameraAnchor : UdonSharpBehaviour
}
}
public override void OnDeserialization(DeserializationResult Result)
{
_AttachCamera_Synced();
@@ -74,6 +86,19 @@ public class CameraAnchor : UdonSharpBehaviour
base.OnDeserialization(Result);
}
public override void OnPlayerLeft(VRCPlayerApi LeavingPlayer)
{
//foreach (VRCPlayerApi FollowedPlayer in _FollowedPlayers)
//{
// if (FollowedPlayer.displayName == LeavingPlayer.displayName)
// {
// }
//}
base.OnPlayerLeft(LeavingPlayer);
}
public void AttachCamera(Camera CameraComponent)
{
@@ -96,9 +121,10 @@ public class CameraAnchor : UdonSharpBehaviour
}
}
public void FollowPlayers(string[] Players)
public void FollowPlayers(string[] Players, float FollowSpeed = 1.0f)
{
_FollowedPlayerNames = Players;
_CameraFollowSpeed = FollowSpeed;
_FollowPlayers_Synced();
RequestSerialization();
}
@@ -113,16 +139,19 @@ public class CameraAnchor : UdonSharpBehaviour
private void _AttachCamera_Synced()
{
Camera NewCamera = CameraSystemManager.camerasObjects[_AttachedCameraIndex];
if (NewCamera != _AttachedCamera)
if (_AttachedCameraIndex >= 0)
{
_AttachedCamera = NewCamera;
_AttachedCamera.gameObject.SetActive(true);
_AttachedCamera.transform.parent = CameraRoot;
_AttachedCamera.fieldOfView = FOV;
_AttachedCamera.nearClipPlane = NearClippingPlane;
_AttachedCamera.farClipPlane = FarClippingPlane;
_AttachedCamera.GetComponent<LightSync>().TeleportToLocalSpace(Vector3.zero, Quaternion.identity, true);
Camera NewCamera = CameraSystemManager.camerasObjects[_AttachedCameraIndex];
if (NewCamera != _AttachedCamera)
{
_AttachedCamera = NewCamera;
_AttachedCamera.gameObject.SetActive(true);
_AttachedCamera.transform.parent = CameraRoot;
_AttachedCamera.fieldOfView = FOV;
_AttachedCamera.nearClipPlane = NearClippingPlane;
_AttachedCamera.farClipPlane = FarClippingPlane;
_AttachedCamera.GetComponent<LightSync>().TeleportToLocalSpace(Vector3.zero, Quaternion.identity, true);
}
}
}
@@ -117,18 +117,18 @@ public class CameraControllerRound3 : CameraControllerBase
}
public void OverheadCamera_FollowPlayers(string[] Players)
public void OverheadCamera_FollowPlayers(string[] Players, float FollowSpeed = 1.0f)
{
OverheadCameraAnchor.FollowPlayers(Players);
OverheadCameraAnchor.FollowPlayers(Players, FollowSpeed);
}
public void OverheadCamera_StopFollowingPlayers()
{
OverheadCameraAnchor.StopFollowingPlayers();
}
public void FrontCamera_FollowPlayers(string[] Players)
public void FrontCamera_FollowPlayers(string[] Players, float FollowSpeed = 1.0f)
{
FrontCameraAnchor.FollowPlayers(Players);
FrontCameraAnchor.FollowPlayers(Players, FollowSpeed);
}
public void FrontCamera_StopFollowingPlayers()
{