Correct/incorrect events are now guaranteed to fire only from the marker owner.

This commit is contained in:
2025-07-20 20:45:15 -04:00
parent 999a0342d5
commit 83e08ed403
10 changed files with 3237 additions and 776 deletions
@@ -44,7 +44,7 @@ MonoBehaviour:
Data:
- Name:
Entry: 12
Data: 12
Data: 15
- Name:
Entry: 7
Data:
@@ -488,13 +488,13 @@ MonoBehaviour:
Data:
- Name: $k
Entry: 1
Data: _StageIndex
Data: _ActiveMarker
- Name: $v
Entry: 7
Data: 33|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: _StageIndex
Data: _ActiveMarker
- Name: <UserType>k__BackingField
Entry: 9
Data: 29
@@ -518,13 +518,73 @@ MonoBehaviour:
Data: 34|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 1
Data: 2
- Name:
Entry: 7
Data: 35|UdonSharp.UdonSyncedAttribute, UdonSharp.Runtime
- Name:
Entry: 8
Data:
- Name:
Entry: 7
Data: 36|UdonSharp.FieldChangeCallbackAttribute, UdonSharp.Runtime
- 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: _StageIndex
- Name: $v
Entry: 7
Data: 37|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: _StageIndex
- Name: <UserType>k__BackingField
Entry: 9
Data: 29
- 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: 3
Data: 1
- Name:
Entry: 8
Data:
- Name: <IsSerialized>k__BackingField
Entry: 5
Data: false
- Name: _fieldAttributes
Entry: 7
Data: 38|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 1
- Name:
Entry: 7
Data: 39|UdonSharp.UdonSyncedAttribute, UdonSharp.Runtime
- Name:
Entry: 8
Data:
- Name:
Entry: 13
Data:
@@ -545,13 +605,13 @@ MonoBehaviour:
Data: _ContinentData
- Name: $v
Entry: 7
Data: 36|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
Data: 40|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: _ContinentData
- Name: <UserType>k__BackingField
Entry: 7
Data: 37|System.RuntimeType, mscorlib
Data: 41|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: VRC.SDK3.Data.DataDictionary, VRCSDK3
@@ -560,7 +620,7 @@ MonoBehaviour:
Data:
- Name: <SystemType>k__BackingField
Entry: 9
Data: 37
Data: 41
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
@@ -575,7 +635,7 @@ MonoBehaviour:
Data: false
- Name: _fieldAttributes
Entry: 7
Data: 38|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
Data: 42|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 0
@@ -599,13 +659,13 @@ MonoBehaviour:
Data: _GameStatus
- Name: $v
Entry: 7
Data: 39|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
Data: 43|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: _GameStatus
- Name: <UserType>k__BackingField
Entry: 7
Data: 40|System.RuntimeType, mscorlib
Data: 44|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: GameStatus, Assembly-CSharp
@@ -629,13 +689,67 @@ MonoBehaviour:
Data: false
- Name: _fieldAttributes
Entry: 7
Data: 41|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
Data: 45|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 1
- Name:
Entry: 7
Data: 42|UdonSharp.UdonSyncedAttribute, UdonSharp.Runtime
Data: 46|UdonSharp.UdonSyncedAttribute, UdonSharp.Runtime
- 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: _RunTimer
- Name: $v
Entry: 7
Data: 47|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: _RunTimer
- 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: 3
Data: 1
- Name:
Entry: 8
Data:
- Name: <IsSerialized>k__BackingField
Entry: 5
Data: false
- Name: _fieldAttributes
Entry: 7
Data: 48|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 1
- Name:
Entry: 7
Data: 49|UdonSharp.UdonSyncedAttribute, UdonSharp.Runtime
- Name:
Entry: 8
Data:
@@ -659,7 +773,7 @@ MonoBehaviour:
Data: _Timer
- Name: $v
Entry: 7
Data: 43|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
Data: 50|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: _Timer
@@ -683,13 +797,13 @@ MonoBehaviour:
Data: false
- Name: _fieldAttributes
Entry: 7
Data: 44|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
Data: 51|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 1
- Name:
Entry: 7
Data: 45|UdonSharp.UdonSyncedAttribute, UdonSharp.Runtime
Data: 52|UdonSharp.UdonSyncedAttribute, UdonSharp.Runtime
- Name:
Entry: 8
Data:
@@ -713,7 +827,7 @@ MonoBehaviour:
Data: _SuccessCounter
- Name: $v
Entry: 7
Data: 46|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
Data: 53|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: _SuccessCounter
@@ -737,13 +851,79 @@ MonoBehaviour:
Data: false
- Name: _fieldAttributes
Entry: 7
Data: 47|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
Data: 54|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 1
Data: 2
- Name:
Entry: 7
Data: 48|UdonSharp.UdonSyncedAttribute, UdonSharp.Runtime
Data: 55|UdonSharp.UdonSyncedAttribute, UdonSharp.Runtime
- Name:
Entry: 8
Data:
- Name:
Entry: 7
Data: 56|UdonSharp.FieldChangeCallbackAttribute, UdonSharp.Runtime
- 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: _FailureCounter
- Name: $v
Entry: 7
Data: 57|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: _FailureCounter
- Name: <UserType>k__BackingField
Entry: 9
Data: 29
- 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: 3
Data: 1
- Name:
Entry: 8
Data:
- Name: <IsSerialized>k__BackingField
Entry: 5
Data: false
- Name: _fieldAttributes
Entry: 7
Data: 58|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 2
- Name:
Entry: 7
Data: 59|UdonSharp.UdonSyncedAttribute, UdonSharp.Runtime
- Name:
Entry: 8
Data:
- Name:
Entry: 7
Data: 60|UdonSharp.FieldChangeCallbackAttribute, UdonSharp.Runtime
- Name:
Entry: 8
Data:
@@ -3,6 +3,7 @@ using UdonSharp;
using UnityEngine;
using VRC.SDK3.Data;
using VRC.SDK3.UdonNetworkCalling;
using VRC.SDKBase;
using VRC.Udon.Common.Interfaces;
@@ -39,34 +40,50 @@ public class GameManagerRound3 : GameManagerBase
[SerializeField] private AudioManager _AudioManager;
[UdonSynced, FieldChangeCallback(nameof(CurrentlyActiveMap))] private ContinentMap _CurrentlyActiveMap = ContinentMap.INDEX_MAX;
[UdonSynced, FieldChangeCallback(nameof(ActiveMarker))] private int _ActiveMarker = 0;
[UdonSynced] private int _StageIndex = 0;
private DataDictionary _ContinentData;
[UdonSynced] private GameStatus _GameStatus = GameStatus.Pregame;
[UdonSynced] private bool _RunTimer = false;
[UdonSynced] private int _Timer = TIMER_LENGTH;
private const float LENGTH_OF_ONE_SECOND = 1.022222222222222222222f;
private const int TIMER_LENGTH = 45;
[UdonSynced] private int _SuccessCounter = 0;
[UdonSynced, FieldChangeCallback(nameof(SuccessCounter))] private int _SuccessCounter = 0;
[UdonSynced, FieldChangeCallback(nameof(FailureCounter))] private int _FailureCounter = 0;
private const int MAX_SUCCESS_COUNT = 8;
private const int MAX_FAILURE_COUNT = 2;
public override void InitialiseGameMode()
{
_StageIndex = 0;
_SuccessCounter = 0;
_Timer = TIMER_LENGTH;
SuccessCounter = 0;
FailureCounter = 0;
_Timer = TIMER_LENGTH;
_RunTimer = false;
InitialiseMarkers();
GetCurrentMap().RandomiseCountries();
RequestSerialization();
base.InitialiseGameMode();
}
private void InitialiseMarkers()
{
for (int i = 0; i < _Markers.Length; i++)
{
_Markers[i].Initialise();
Networking.SetOwner(Networking.GetOwner(gameObject), _Markers[i].gameObject);
_Markers[i].SendCustomNetworkEvent(NetworkEventTarget.All, "Initialise");
}
_Markers[0].SetPickupable(true);
GetCurrentMap().RandomiseCountries();
RequestSerialization();
base.InitialiseGameMode();
_ActiveMarker = 0;
GetCurrentMarker().SendCustomNetworkEvent(NetworkEventTarget.All, "SetPickupable", true);
}
@@ -118,7 +135,7 @@ public class GameManagerRound3 : GameManagerBase
public void BeginRound()
{
GetCurrentMarker().SendCustomNetworkEvent(NetworkEventTarget.Owner, "Activated", true);
GetCurrentMarker().SendCustomNetworkEvent(NetworkEventTarget.All, "Activated", true);
UpdateInterface();
@@ -132,13 +149,21 @@ public class GameManagerRound3 : GameManagerBase
_GameStatus = GameStatus.Begin;
_Timer = TIMER_LENGTH;
SendCustomEventDelayedSeconds(nameof(TickTimer), LENGTH_OF_ONE_SECOND);
SendCustomNetworkEvent(NetworkEventTarget.Owner, nameof(BeginTimerTick));
RequestSerialization();
}
[NetworkCallable]
public void BeginTimerTick()
{
_RunTimer = true;
SendCustomEventDelayedSeconds(nameof(TickTimer), LENGTH_OF_ONE_SECOND);
}
public void TickTimer()
{
if (!_RunTimer) return;
_Timer--;
if (_Timer < 0)
{
@@ -146,17 +171,21 @@ public class GameManagerRound3 : GameManagerBase
return;
}
SendCustomEventDelayedSeconds(nameof(TickTimer), LENGTH_OF_ONE_SECOND);
BeginTimerTick();
RequestSerialization();
}
[NetworkCallable]
public void CorrectResponse()
{
_SuccessCounter++;
if (_SuccessCounter >= MAX_SUCCESS_COUNT)
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All,
"PlaySFX", SFXEventType.MapCorrect);
SuccessCounter++;
if (SuccessCounter >= MAX_SUCCESS_COUNT)
{
SendCustomNetworkEvent(NetworkEventTarget.Owner, nameof(GameHasBeenWon));
GameHasBeenWon();
}
else
{
@@ -166,9 +195,19 @@ public class GameManagerRound3 : GameManagerBase
RequestSerialization();
}
[NetworkCallable]
public void IncorrectResponse()
{
SetUpNextCountry();
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All,
"PlaySFX", SFXEventType.MapIncorrect);
FailureCounter++;
if (FailureCounter >= MAX_FAILURE_COUNT)
{
SetUpNextCountry();
}
RequestSerialization();
}
@@ -179,35 +218,46 @@ public class GameManagerRound3 : GameManagerBase
public FloorMapMarker GetCurrentMarker()
{
return _Markers[GetCurrentMap().GetCurrentCountryIndex()];
return _Markers[ActiveMarker];
}
public string GetCurrentCountry()
{
return GetCurrentMap().GetCurrentCountry();
return GetCurrentMap().GetCountry(ActiveMarker);
}
public string GetCurrentCity()
{
return GetCurrentMap().GetCurrentCity();
return GetCurrentMap().GetCity(ActiveMarker);
}
public void SetUpNextCountry()
{
int NextCountry = GetCurrentMap().NextCountry();
if (NextCountry < 0)
GetCurrentMarker().SendCustomNetworkEvent(NetworkEventTarget.All, "Activated", false);
FailureCounter = 0;
ActiveMarker++;
UpdateInterface();
RequestSerialization();
}
private void ActivateMarker()
{
if (ActiveMarker >= FloorMap.MAX_SELECTED_COUNTRIES)
{
// If we ran out of countries, lose the game here.
SendCustomNetworkEvent(NetworkEventTarget.Owner, nameof(GameHasBeenLost), true);
return;
}
GetCurrentMarker().SendCustomNetworkEvent(NetworkEventTarget.Owner, "Activated", true);
UpdateInterface();
GetCurrentMarker().SendCustomNetworkEvent(NetworkEventTarget.All, "Activated", true);
}
[NetworkCallable]
public void GameHasBeenWon()
{
_RunTimer = false;
if ((int)_GameStatus <= (int)GameStatus.Begin)
{
GameStatusUpdate(GameStatus.Win);
@@ -244,18 +294,20 @@ public class GameManagerRound3 : GameManagerBase
[NetworkCallable]
public void GameHasBeenLost(bool RanOutOfMarkers)
{
if ((int)_GameStatus != (int)GameStatus.Win)
_RunTimer = false;
if (_GameStatus != GameStatus.Win)
{
for (int i = 0; i < _Markers.Length; i++)
{
_Markers[i].SendCustomNetworkEvent(NetworkEventTarget.Owner, "Activated", false);
_Markers[i].SendCustomNetworkEvent(NetworkEventTarget.All, "Activated", false);
}
GameStatusUpdate(RanOutOfMarkers ? GameStatus.RanOutOfMarkers : GameStatus.RanOutOfTime);
HostCardBetweenRoundsInterface GameLossInterface =
(HostCardBetweenRoundsInterface)GetHostCardInterface(RoundSegmentType.BetweenSegments);
GameLossInterface.HeaderUI.text = "The player has lost. " + _SuccessCounter + " countries in " + TIMER_LENGTH + " seconds.";
GameLossInterface.HeaderUI.text = "The player has run out of " + (RanOutOfMarkers ? "markers" : "time") + ". " + SuccessCounter + " countries in " + TIMER_LENGTH + " seconds.";
StopFinalRoundMusic();
SendCustomEventDelayedSeconds(nameof(PlayWindDownMusic), 2.5f);
@@ -299,18 +351,6 @@ public class GameManagerRound3 : GameManagerBase
}
public void PlayCorrectSound()
{
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All,
"PlaySFX", SFXEventType.MapCorrect);
}
public void PlayIncorrectSound()
{
_AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All,
"PlaySFX", SFXEventType.MapIncorrect);
}
private void UpdateInterface()
{
HostCardCaptureCarmenInterface CaptureCarmenInterface =
@@ -351,4 +391,32 @@ public class GameManagerRound3 : GameManagerBase
}
get => _CurrentlyActiveMap;
}
public int ActiveMarker
{
set
{
_ActiveMarker = value;
ActivateMarker();
}
get => _ActiveMarker;
}
private int SuccessCounter
{
set
{
_SuccessCounter = value;
}
get => _SuccessCounter;
}
private int FailureCounter
{
set
{
_FailureCounter = value;
}
get => _FailureCounter;
}
}