After many rewrites and much debugging, video syncing finally works properly.

This commit is contained in:
2025-12-09 20:41:10 -05:00
parent 0b3fc5c08b
commit 1aebaeef76
5 changed files with 717 additions and 819 deletions
File diff suppressed because it is too large Load Diff
@@ -1,5 +1,4 @@
using Newtonsoft.Json.Linq;
using UdonSharp;
using UnityEngine;
using VRC.SDK3.Components.Video;
@@ -22,10 +21,7 @@ public enum ClueScreenType
[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]
public class CaseVideoSyncPlayer : UdonSharpBehaviour
{
[SerializeField] private GameManagerRound1 _GameManager;
[SerializeField] private BaseVRCVideoPlayer _VideoPlayer;
//[SerializeField] private float _SyncFrequency = 5.0f;
[Header("Meshes")]
[SerializeField] private MeshRenderer _BlankScreenMesh;
@@ -43,8 +39,8 @@ public class CaseVideoSyncPlayer : UdonSharpBehaviour
[UdonSynced, FieldChangeCallback(nameof(ShowScreen))] private ClueScreenType _ShowScreen = ClueScreenType.Blank;
[UdonSynced, FieldChangeCallback(nameof(FlashCorrectAnswer))] private bool _FlashCorrectAnswer = false;
[UdonSynced, FieldChangeCallback(nameof(VideoIndex))] private int _VideoIndex = -1;
[UdonSynced, FieldChangeCallback(nameof(TimeAndOffset))] private Vector2 _TimeAndOffset;
[UdonSynced] private int _VideoIndex = -1;
private int _OldVideoIndex = -1;
[UdonSynced, FieldChangeCallback(nameof(PlayVideo))] private bool _VideoIsPlaying;
@@ -66,6 +62,8 @@ public class CaseVideoSyncPlayer : UdonSharpBehaviour
private int _VideoLoadAttemptCounter = 0;
private bool _UseFallback = false;
private bool _FirstDeserialisationComplete = false;
private const int IMAGES_PER_MAP_ATLAS = 6;
private const int MAX_VIDEO_LOAD_ATTEMPTS = 5;
@@ -77,7 +75,7 @@ public class CaseVideoSyncPlayer : UdonSharpBehaviour
_MapScreenMesh.sharedMaterial = _MapScreenMaterial;
UpdateMap(false);
_UpdateMap();
}
void OnDestroy()
@@ -87,45 +85,43 @@ public class CaseVideoSyncPlayer : UdonSharpBehaviour
public override void OnDeserialization(DeserializationResult Result)
{
{ // Map syncing and redownloading
{ // Map syncing and redownloading
_ReloadMapList();
if (_MapDownloadsInProgress)
if (!_MapDownloadsInProgress)
{
return;
}
bool MapsNeedLoading = false;
if (_LoadedMaps.Length == _CachedMapIndices.Length)
{
for (int i = 0; i < _CachedMapIndices.Length; i++)
bool MapsNeedLoading = false;
if (_LoadedMaps.Length == _CachedMapIndices.Length)
{
if (_CachedMapIndices[i] != _LoadedMaps[i])
for (int i = 0; i < _CachedMapIndices.Length; i++)
{
MapsNeedLoading = true;
break;
if (_CachedMapIndices[i] != _LoadedMaps[i])
{
MapsNeedLoading = true;
break;
}
}
}
}
else
{
MapsNeedLoading = true;
}
else
{
MapsNeedLoading = true;
}
if (MapsNeedLoading)
{
QueueMapDownloads(_CachedMapIndices);
if (MapsNeedLoading)
{
QueueMapDownloads(_CachedMapIndices);
}
}
}
{ // Video syncing and redownloading
{ // Video list syncing
_ReloadVideoList();
}
base.OnDeserialization(Result);
}
public void SetNewLists(VRCUrl[] Maps, VRCUrl[] Videos)
public void InitialiseLists(VRCUrl[] Maps, VRCUrl[] Videos)
{
_CaseMapsList = Maps;
_ReloadMapList();
@@ -148,8 +144,13 @@ public class CaseVideoSyncPlayer : UdonSharpBehaviour
{
if (_IsUrlListDifferent(_CaseVideoList, _CaseVideoListCache))
{
_OldVideoIndex = -1;
_CaseVideoListCache = (VRCUrl[])_CaseVideoList.Clone();
_GameManager.TryIntroVideoLoad();
}
if (_VideoIndex != _OldVideoIndex)
{
_LoadNewVideoIndex();
}
}
@@ -208,7 +209,7 @@ public class CaseVideoSyncPlayer : UdonSharpBehaviour
int MapPage = SubMapIndex / IMAGES_PER_MAP_ATLAS;
if (MapPage == _MapDownloadIndex)
{
_MapScreenMaterial.SetTexture("_EmissionMap", _MapImages[MapPage]);
_UpdateSubMap(MapPage);
}
_MapDownloadIndex++;
@@ -235,7 +236,10 @@ public class CaseVideoSyncPlayer : UdonSharpBehaviour
{
if (FlashCorrectAnswer)
{
Debug.Log("[CaseVideoSyncPlayer] Flashing correct answer.");
SubMapIndex = (SubMapIndex == 4) ? 3 : 4;
Debug.Log("[CaseVideoSyncPlayer] New submap is " + SubMapIndex);
_UpdateMap(false);
SendCustomEventDelayedSeconds(nameof(NextCorrectAnswerFrame), 0.2f);
}
else
@@ -248,44 +252,62 @@ public class CaseVideoSyncPlayer : UdonSharpBehaviour
}
}
private void UpdateMap(bool SyncResult = true)
private void _UpdateMap(bool Sync = true)
{
Debug.Log("[CaseVideoSyncPlayer] Now inside _UpdateMap()");
int MapPage = SubMapIndex / IMAGES_PER_MAP_ATLAS;
int SubmapIndexWrapped = SubMapIndex % IMAGES_PER_MAP_ATLAS;
Debug.Log("[CaseVideoSyncPlayer] Map page: " + MapPage);
if (MapPage < _MapImages.Length)
{
switch (SubmapIndexWrapped)
{
case 0: _MapScreenMaterial.SetVector("_MainTex_ST", new Vector4(0.5f, 0.33333333f, 0.0f, 0.66666666f)); break;
case 1: _MapScreenMaterial.SetVector("_MainTex_ST", new Vector4(0.5f, 0.33333333f, 0.5f, 0.66666666f)); break;
case 2: _MapScreenMaterial.SetVector("_MainTex_ST", new Vector4(0.5f, 0.33333333f, 0.0f, 0.33333333f)); break;
case 3: _MapScreenMaterial.SetVector("_MainTex_ST", new Vector4(0.5f, 0.33333333f, 0.5f, 0.33333333f)); break;
case 4: _MapScreenMaterial.SetVector("_MainTex_ST", new Vector4(0.5f, 0.33333333f, 0.0f, 0.0f)); break;
case 5: _MapScreenMaterial.SetVector("_MainTex_ST", new Vector4(0.5f, 0.33333333f, 0.5f, 0.0f)); break;
}
_MapScreenMaterial.SetTexture("_EmissionMap", _MapImages[MapPage]);
Debug.Log("[CaseVideoSyncPlayer] Updating submap.");
_UpdateSubMap(MapPage);
ShowScreen = ClueScreenType.Map;
}
if (SyncResult)
{
RequestSerialization();
}
if (Sync)
{
RequestSerialization();
}
}
private void _UpdateSubMap(int MapPage = -1)
{
Debug.Log("[CaseVideoSyncPlayer] Now inside _UpdateSubMap()");
int SubmapIndexWrapped = SubMapIndex % IMAGES_PER_MAP_ATLAS;
Debug.Log("[CaseVideoSyncPlayer] Wrapped submap index: " + SubmapIndexWrapped);
switch (SubmapIndexWrapped)
{
case 0: _MapScreenMaterial.SetVector("_MainTex_ST", new Vector4(0.5f, 0.33333333f, 0.0f, 0.66666666f)); break;
case 1: _MapScreenMaterial.SetVector("_MainTex_ST", new Vector4(0.5f, 0.33333333f, 0.5f, 0.66666666f)); break;
case 2: _MapScreenMaterial.SetVector("_MainTex_ST", new Vector4(0.5f, 0.33333333f, 0.0f, 0.33333333f)); break;
case 3: _MapScreenMaterial.SetVector("_MainTex_ST", new Vector4(0.5f, 0.33333333f, 0.5f, 0.33333333f)); break;
case 4: _MapScreenMaterial.SetVector("_MainTex_ST", new Vector4(0.5f, 0.33333333f, 0.0f, 0.0f)); break;
case 5: _MapScreenMaterial.SetVector("_MainTex_ST", new Vector4(0.5f, 0.33333333f, 0.5f, 0.0f)); break;
}
if (MapPage >= 0)
{
_MapScreenMaterial.SetTexture("_EmissionMap", _MapImages[MapPage]);
}
}
public void SetVideoIndexLocal(int Index)
public void SetVideoIndex(int Index)
{
_VideoIndex = Index;
_VideoLoadAttemptCounter = 0;
if (_VideoIndex >= 0)
if (Index != _OldVideoIndex)
{
_UseFallback = false;
_LoadVideo_Private();
_VideoIndex = Index;
_LoadNewVideoIndex();
RequestSerialization();
}
}
private void _LoadNewVideoIndex()
{
_OldVideoIndex = _VideoIndex;
_VideoLoadAttemptCounter = 0;
_UseFallback = false;
_LoadVideo_Private();
}
private void _LoadVideo_Private()
{
@@ -293,27 +315,11 @@ public class CaseVideoSyncPlayer : UdonSharpBehaviour
}
public void TryLoadURL()
{
if (VideoIndex >= 0 && VideoIndex < _CaseVideoList.Length)
if (_VideoIndex >= 0 && _VideoIndex < _CaseVideoList.Length)
{
_VideoPlayer.LoadURL(_CaseVideoList[VideoIndex]);
_VideoPlayer.LoadURL(_CaseVideoList[_VideoIndex]);
SetVideoLoadStatus(IndicationStatus.Loading);
}
else
{
if (_VideoLoadAttemptCounter >= MAX_VIDEO_LOAD_ATTEMPTS)
{
Debug.LogError("[CaseVideoSyncPlayer] Index " + VideoIndex + " is out of range. Out of retry attempts. Something is wrong.");
SetVideoLoadStatus(IndicationStatus.LoadFailure);
_VideoLoadAttemptCounter = 0;
}
else
{
Debug.LogWarning("[CaseVideoSyncPlayer] Index " + VideoIndex + " is out of range. Checking range again in 1 second...");
SetVideoLoadStatus(IndicationStatus.Loading);
_VideoLoadAttemptCounter++;
SendCustomEventDelayedSeconds(nameof(TryLoadURL), 1.1f);
}
}
}
private void _PlayVideo_Private()
@@ -325,7 +331,7 @@ public class CaseVideoSyncPlayer : UdonSharpBehaviour
{
_VideoPlayer.Stop();
_UseFallback = false;
VideoIndex = -1;
_VideoIndex = -1;
SetVideoLoadStatus(IndicationStatus.Idle);
}
@@ -374,7 +380,7 @@ public class CaseVideoSyncPlayer : UdonSharpBehaviour
// SendCustomEventDelayedSeconds(nameof(TryLoadFallbackURL), 5.5f);
//}
//SetVideoLoadStatus(IndicationStatus.LoadFailure);
SetVideoLoadStatus(IndicationStatus.LoadFailure);
base.OnVideoError(VideoError);
}
@@ -400,7 +406,6 @@ public class CaseVideoSyncPlayer : UdonSharpBehaviour
if (_VideoIsPlaying)
{
ShowScreen = ClueScreenType.Video;
//UpdateTimeAndOffset();
}
else
{
@@ -415,8 +420,6 @@ public class CaseVideoSyncPlayer : UdonSharpBehaviour
PlayVideo = false;
ShowScreen = ClueScreenType.Blank;
RequestSerialization();
base.OnVideoEnd();
}
@@ -431,30 +434,6 @@ public class CaseVideoSyncPlayer : UdonSharpBehaviour
}
}
//private void UpdateTimeAndOffset()
//{
// if (Networking.IsOwner(gameObject))
// {
// TimeAndOffset = new Vector2(_VideoPlayer.GetTime(), (float)Networking.GetServerTimeInSeconds());
// if (_SyncFrequency > 0.0f)
// {
// SendCustomEventDelayedSeconds(nameof(UpdateTimeAndOffset), _SyncFrequency);
// }
// }
// else
// {
// Resync();
// }
// RequestSerialization();
//}
public void Resync()
{
_VideoPlayer.SetTime(TimeAndOffset.x + ((float)Networking.GetServerTimeInSeconds() - TimeAndOffset.y));
}
[NetworkCallable]
public void ClearScreen()
@@ -496,8 +475,6 @@ public class CaseVideoSyncPlayer : UdonSharpBehaviour
break;
}
}
RequestSerialization();
}
private bool _IsUrlListDifferent(VRCUrl[] New, VRCUrl[] Cached)
@@ -526,9 +503,9 @@ public class CaseVideoSyncPlayer : UdonSharpBehaviour
set
{
_SubMapIndex = value;
if (_SubMapIndex >= 0)
if (_SubMapIndex >= 0 && !FlashCorrectAnswer)
{
UpdateMap(!FlashCorrectAnswer);
_UpdateMap();
}
}
get => _SubMapIndex;
@@ -555,19 +532,6 @@ public class CaseVideoSyncPlayer : UdonSharpBehaviour
get => _FlashCorrectAnswer;
}
public int VideoIndex
{
set
{
if (_VideoIndex != value)
{
SetVideoIndexLocal(value);
RequestSerialization();
}
}
get => _VideoIndex;
}
public bool PlayVideo
{
set
@@ -576,17 +540,4 @@ public class CaseVideoSyncPlayer : UdonSharpBehaviour
}
get => _VideoIsPlaying;
}
public Vector2 TimeAndOffset
{
set
{
_TimeAndOffset = value;
if (!Networking.IsOwner(gameObject))
{
Resync();
}
}
get => _TimeAndOffset;
}
}