Initial progress syncing + many existing bugs

This commit is contained in:
2026-01-15 23:00:15 +01:00
parent fb902aaddc
commit c41491e55e
11 changed files with 345 additions and 230 deletions

View File

@@ -69,7 +69,7 @@ namespace Marro.PacManUdon
networkManager.Initialize();
ghostManager.Initialize(maze.ghostTargets, pacMan, this);
pacMan.Initialize(playerInput, this);
pacMan.Initialize(playerInput, maze.pacManStart, this);
bonusFruit.Initialize();
pelletManager.Initialize();
statusDisplay.Initialize();
@@ -112,6 +112,10 @@ namespace Marro.PacManUdon
public void StartGameButtonPressed()
{
Debug.Log($"{gameObject} Start Game Button was pressed!");
if (networkManager.IsOwner)
{
networkManager.SendEvent(NetworkEventType.StartGameButtonPressed);
}
StartTimeSequence(PacManTimeSequence.StartNewGame);
}
@@ -197,6 +201,8 @@ namespace Marro.PacManUdon
public void GotPowerPellet()
{
Debug.Log($"{gameObject} GotPowerPellet");
if (gameState == PacManGameState.AttractMode)
{
TimeSequenceSkipToNextStep();
@@ -224,6 +230,8 @@ namespace Marro.PacManUdon
public void GhostCaught(int scoreBonus)
{
Debug.Log($"{gameObject} GhostCaught");
if (gameState == PacManGameState.AttractMode)
{
TimeSequenceSkipToNextStep();
@@ -237,7 +245,7 @@ namespace Marro.PacManUdon
public void PacManCaught()
{
StartTimeSequence(PacManTimeSequence.PacManCaught);
//StartTimeSequence(PacManTimeSequence.PacManCaught);
}
public void NoGhostsScared()
@@ -252,6 +260,8 @@ namespace Marro.PacManUdon
public void Intermission2PoleUpdate()
{
Debug.Log($"{gameObject} Intermission2PoleUpdate");
TimeSequenceSkipToNextStep();
}
@@ -400,21 +410,26 @@ namespace Marro.PacManUdon
public override void AppendSyncedData(byte[][] data, ref int offset, NetworkEventType eventType)
{
data[offset++] = new byte[] { NetworkManager.Int32ToByte((int)gameState) };
data[offset++] = BitConverter.GetBytes(currentlyInTimeSequence);
data[offset++] = new byte[] { NetworkManager.Int32ToByte((int)currentTimeSequence) };
data[offset++] = BitConverter.GetBytes(timeSequenceProgress);
//data[offset++] = new byte[] { NetworkManager.Int32ToByte((int)gameState) };
//data[offset++] = BitConverter.GetBytes(currentlyInTimeSequence);
//data[offset++] = new byte[] { NetworkManager.Int32ToByte((int)currentTimeSequence) };
//data[offset++] = BitConverter.GetBytes(timeSequenceSecondsPassed);
}
public override bool SetSyncedData(byte[] data, ref int offset, NetworkEventType eventType)
{
SetGameState((PacManGameState)data[offset++]);
if (eventType == NetworkEventType.StartGameButtonPressed)
{
StartGameButtonPressed();
}
var currentlyInTimeSequence = BitConverter.ToBoolean(data, offset++);
var currentTimeSequence = (PacManTimeSequence)data[offset++];
var timeSequenceProgress = BitConverter.ToSingle(data, offset);
offset += 4;
TimeSequenceSyncWithRemote(currentlyInTimeSequence, currentTimeSequence, timeSequenceProgress);
//SetGameState((PacManGameState)data[offset++]);
//var currentlyInTimeSequence = BitConverter.ToBoolean(data, offset++);
//var currentTimeSequence = (PacManTimeSequence)data[offset++];
//var timeSequenceSecondsPassed = BitConverter.ToSingle(data, offset);
//offset += 4;
//TimeSequenceSyncWithRemote(currentlyInTimeSequence, currentTimeSequence, timeSequenceSecondsPassed);
return true;
}

View File

@@ -55,17 +55,17 @@ namespace Marro.PacManUdon
private bool kinematic;
// This should be called once when the game is initialized
public void Initialize(GameObject[] ghostTargets, PacMan pacMan, GameManager gameController)
public void Initialize(Transform[] ghostTargets, PacMan pacMan, GameManager gameController)
{
this.gameController = gameController;
ghosts = transform.GetComponentsInChildren<Ghost>(true);
blinky = ghosts[0];
for (int ghostIndex = 0; ghostIndex < ghosts.Length; ghostIndex++)
{
Vector2 homePosition = ghostTargets[0].transform.localPosition;
Vector2 idlePosition1 = ghostTargets[1 + ghostIndex * 3].transform.localPosition;
Vector2 idlePosition2 = ghostTargets[2 + ghostIndex * 3].transform.localPosition;
Vector2 cornerPosition = ghostTargets[3 + ghostIndex * 3].transform.localPosition;
Vector2 homePosition = ghostTargets[0].localPosition;
Vector2 idlePosition1 = ghostTargets[1 + ghostIndex * 3].localPosition;
Vector2 idlePosition2 = ghostTargets[2 + ghostIndex * 3].localPosition;
Vector2 cornerPosition = ghostTargets[3 + ghostIndex * 3].localPosition;
ghosts[ghostIndex].Initialize(pacMan, blinky, homePosition, idlePosition1, idlePosition2, cornerPosition);
}

View File

@@ -34,6 +34,11 @@ namespace Marro.PacManUdon
public override void AppendSyncedData(byte[][] data, ref int offset, NetworkEventType eventType)
{
if (eventType != NetworkEventType.PacManTurn)
{
return;
}
var position = GetPosition();
data[offset++] = BitConverter.GetBytes(position.x);
data[offset++] = BitConverter.GetBytes(position.y);
@@ -45,9 +50,14 @@ namespace Marro.PacManUdon
public override bool SetSyncedData(byte[] data, ref int offset, NetworkEventType eventType)
{
SetPosition(new Vector2(BitConverter.ToSingle(data, offset), BitConverter.ToSingle(data, offset + 2)));
SetDirection(new Vector2(BitConverter.ToSingle(data, offset + 4), BitConverter.ToSingle(data, offset + 6)));
offset += 8;
if (eventType != NetworkEventType.PacManTurn)
{
return true;
}
SetPosition(new Vector2(BitConverter.ToSingle(data, offset), BitConverter.ToSingle(data, offset + 4)));
SetDirection(new Vector2(BitConverter.ToSingle(data, offset + 8), BitConverter.ToSingle(data, offset + 12)));
offset += 16;
return true;
}

View File

@@ -41,6 +41,12 @@ namespace Marro.PacManUdon
{
_lastUpdate = PoleStrechLevels.None;
SetStrechLevel(PoleStrechLevels.None);
SetActive(false); // Should only activate for intermission 2
}
public void SetActive(bool isActive)
{
gameObject.SetActive(isActive);
}
public override void SyncedUpdate()

View File

@@ -43,7 +43,7 @@ MonoBehaviour:
Data:
- Name:
Entry: 12
Data: 4
Data: 5
- Name:
Entry: 7
Data:
@@ -109,19 +109,19 @@ MonoBehaviour:
Data:
- Name: $k
Entry: 1
Data: ghostTargets
Data: pelletContainer
- Name: $v
Entry: 7
Data: 6|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: ghostTargets
Data: pelletContainer
- Name: <UserType>k__BackingField
Entry: 7
Data: 7|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: UnityEngine.GameObject[], UnityEngine.CoreModule
Data: UnityEngine.GameObject, UnityEngine.CoreModule
- Name:
Entry: 8
Data:
@@ -169,25 +169,19 @@ MonoBehaviour:
Data:
- Name: $k
Entry: 1
Data: pelletContainer
Data: mazeSprite
- Name: $v
Entry: 7
Data: 10|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: pelletContainer
Data: mazeSprite
- Name: <UserType>k__BackingField
Entry: 7
Data: 11|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: UnityEngine.GameObject, UnityEngine.CoreModule
- Name:
Entry: 8
Data:
Entry: 9
Data: 7
- Name: <SystemType>k__BackingField
Entry: 9
Data: 11
Data: 7
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
@@ -202,13 +196,13 @@ MonoBehaviour:
Data: true
- Name: _fieldAttributes
Entry: 7
Data: 12|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
Data: 11|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 1
- Name:
Entry: 7
Data: 13|UnityEngine.SerializeField, UnityEngine.CoreModule
Data: 12|UnityEngine.SerializeField, UnityEngine.CoreModule
- Name:
Entry: 8
Data:
@@ -229,19 +223,25 @@ MonoBehaviour:
Data:
- Name: $k
Entry: 1
Data: mazeSprite
Data: ghostTargets
- Name: $v
Entry: 7
Data: 14|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
Data: 13|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: mazeSprite
Data: ghostTargets
- Name: <UserType>k__BackingField
Entry: 9
Data: 11
Entry: 7
Data: 14|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: UnityEngine.Transform[], UnityEngine.CoreModule
- Name:
Entry: 8
Data:
- Name: <SystemType>k__BackingField
Entry: 9
Data: 11
Data: 14
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
@@ -278,6 +278,66 @@ MonoBehaviour:
- Name:
Entry: 8
Data:
- Name:
Entry: 7
Data:
- Name: $k
Entry: 1
Data: pacManStart
- Name: $v
Entry: 7
Data: 17|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: pacManStart
- Name: <UserType>k__BackingField
Entry: 7
Data: 18|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: UnityEngine.Transform, UnityEngine.CoreModule
- Name:
Entry: 8
Data:
- Name: <SystemType>k__BackingField
Entry: 9
Data: 18
- 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: 19|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 1
- Name:
Entry: 7
Data: 20|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: 13
Data:

View File

@@ -8,8 +8,9 @@
public class Maze : UdonSharpBehaviour
{
[SerializeField] public Vector2 mazeBoundaries;
[SerializeField] public GameObject[] ghostTargets;
[SerializeField] public GameObject pelletContainer;
[SerializeField] public GameObject mazeSprite;
[SerializeField] public Transform[] ghostTargets;
[SerializeField] public Transform pacManStart;
}
}

View File

@@ -14,6 +14,7 @@ namespace Marro.PacManUdon
FullSyncForced = 0,
FullSync = 1,
PacManTurn = 2,
StartGameButtonPressed = 3,
}
public class NetworkManager : UdonSharpBehaviour
@@ -217,7 +218,12 @@ namespace Marro.PacManUdon
syncedObjects = root.GetComponentsInChildren<SyncedObject>(includeInactive: true);
Debug.Log($"({nameof(PacManUdon)} {nameof(NetworkManager)}) 3 Found {syncedObjects.Length} {nameof(SyncedObject)} in children of {root.name}.");
foreach (var obj in syncedObjects)
{
obj.networkManager = this;
}
Debug.Log($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Found {syncedObjects.Length} {nameof(SyncedObject)} in children of {root.name}.");
SetOwner(Networking.IsOwner(gameObject));
@@ -239,6 +245,11 @@ namespace Marro.PacManUdon
public void FixedUpdate()
{
if (!Ready)
{
return;
}
// Fetch the current time
UpdateInternalTime();
@@ -268,14 +279,14 @@ namespace Marro.PacManUdon
IsEventUpdate = false;
ProgressSyncedTime(internalTime);
Debug.Log($"{nameof(PacManUdon)} {nameof(NetworkManager)} syncedObjects: {syncedObjects}");
Debug.Log($"{nameof(PacManUdon)} {nameof(NetworkManager)} Starting SyncedUpdate for {syncedObjects.Length} objects.");
for (int i = 0; i < syncedObjects.Length; i++)
{
var obj = syncedObjects[i];
Debug.Log($"{nameof(PacManUdon)} {nameof(NetworkManager)} SyncedUpdate for {obj.gameObject.name}");
obj.SyncedUpdate();
if (obj.gameObject.activeInHierarchy)
{
obj.SyncedUpdate();
}
}
}
@@ -367,7 +378,7 @@ namespace Marro.PacManUdon
QueueEventInBuffer(result);
Debug.Log($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Prepared event with {eventSize} bytes and timestamp {timestamp} for serialization, index is now {this.eventsQueueIndex}");
Debug.Log($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Prepared event of type {eventType} with {eventSize} bytes, timestamp {timestamp} and id {eventId} for serialization.");
RequestSerializationForEvents();
@@ -905,6 +916,11 @@ namespace Marro.PacManUdon
/// An animator which visualizes whether the current perspective is the owner.
/// </summary>
[SerializeField] private Animator DebugImageToIndicateOwner;
public void DoFullSync()
{
SendEvent(NetworkEventType.FullSync);
}
#endregion
}
}

View File

@@ -43,7 +43,7 @@ namespace Marro.PacManUdon
#endregion
public void Initialize(PlayerInput input, GameManager gameController)
public void Initialize(PlayerInput input, Transform startTransform, GameManager gameController)
{
this.gameController = gameController;
this.input = input;
@@ -51,14 +51,13 @@ namespace Marro.PacManUdon
renderer = GetComponent<Renderer>();
frozen = false;
hideUntilUnfrozen = false;
startPosition = transform.localPosition;
startRotation = transform.localRotation;
startScale = transform.localScale;
startPosition = startTransform.localPosition;
startRotation = startTransform.localRotation;
startScale = startTransform.localScale;
}
public void Reset()
{
// Debug.Log($"{gameObject} Reset!");
transform.SetLocalPositionAndRotation(startPosition, startRotation);
transform.localScale = startScale;
direction = Vector2.left;
@@ -69,6 +68,8 @@ namespace Marro.PacManUdon
SetDead(false);
animator.SetTrigger("Reset");
Debug.Log($"{gameObject} Reset! Position is now {GetPosition()}.");
}
public override void SyncedUpdate()
@@ -155,6 +156,7 @@ namespace Marro.PacManUdon
SetDirection(inputDirection + new Vector2(GridMoverTools.PositionToGrid(nextPosition).x - nextPosition.x, 0).normalized);
}
SetTargetDirection(inputDirection); // This is the direction most logic should assume pacman is moving, the actual direction may be different due to cornering
networkManager.SendEvent(NetworkEventType.PacManTurn);
}
return nextPosition;
@@ -338,5 +340,31 @@ namespace Marro.PacManUdon
gameController.GotFruit();
}
}
public override void AppendSyncedData(byte[][] data, ref int offset, NetworkEventType eventType)
{
if (eventType != NetworkEventType.PacManTurn || kinematic || frozen || !enabled)
{
return;
}
data[offset++] = BitConverter.GetBytes(targetDirection.x);
data[offset++] = BitConverter.GetBytes(targetDirection.y);
base.AppendSyncedData(data, ref offset, eventType);
}
public override bool SetSyncedData(byte[] data, ref int offset, NetworkEventType eventType)
{
if (eventType != NetworkEventType.PacManTurn || kinematic || frozen || !enabled)
{
return true;
}
SetTargetDirection(new Vector2(BitConverter.ToSingle(data, offset), BitConverter.ToSingle(data, offset + 4)));
offset += 8;
return base.SetSyncedData(data, ref offset, eventType);
}
}
}

View File

@@ -20,6 +20,7 @@ namespace Marro.PacManUdon
// Show pole
SetIntermissionScreenVisible(true);
intermission2Pole.Reset();
intermission2Pole.SetActive(true);
break;
case 2:
// Start music

View File

@@ -42,6 +42,7 @@ namespace Marro.PacManUdon
{
jumpingToTimeSequence = true;
TimeSequenceProgressToTime(100000f);
Debug.LogWarning($"{gameObject} TimeSequenceEndCurrent");
TryFinalizeTimeSequence();
jumpingToTimeSequence = false;
}
@@ -58,7 +59,7 @@ namespace Marro.PacManUdon
private void TimeSequenceSkipToNextStep()
{
// Debug.Log($"{gameObject} TimeSequenceSkipToNextStep");
Debug.Log($"{gameObject} TimeSequenceSkipToNextStep");
if (timeSequenceProgress < timeSequenceKeyframeTimes.Length)
{
TimeSequenceProgressToTime(timeSequenceKeyframeTimes[timeSequenceProgress]);
@@ -89,18 +90,19 @@ namespace Marro.PacManUdon
private void TimeSequencePrepareForFinish(PacManTimeSequence timeSequence)
{
if (networkManager.IsOwner)
{
TimeSequenceExecuteFinalize(timeSequence);
//if (networkManager.IsOwner)
//{
Debug.LogWarning($"{gameObject} TimeSequencePrepareForFinish");
TimeSequenceExecuteFinalize(timeSequence);
if (!jumpingToTimeSequence)
{
TimeSequenceExecuteFinished(timeSequence);
}
}
else
{
waitingForTimeSequenceFinalize = true;
}
//}
//else
//{
// waitingForTimeSequenceFinalize = true;
//}
}
private void TryFinalizeTimeSequence()
@@ -114,26 +116,26 @@ namespace Marro.PacManUdon
waitingForTimeSequenceFinalize = false;
}
private void TimeSequenceSyncWithRemote(bool currentlyInTimeSequence, PacManTimeSequence currentTimeSequence, float timeSequenceProgress)
{
// If the remote is in a time sequence but we're not, or we're in a different time sequence, jump to the remote's time sequence.
if (currentlyInTimeSequence && (!this.currentlyInTimeSequence || currentTimeSequence != this.currentTimeSequence))
{
StartTimeSequence(currentTimeSequence);
}
//private void TimeSequenceSyncWithRemote(bool currentlyInTimeSequence, PacManTimeSequence currentTimeSequence, float timeSequenceSecondsPassed)
//{
// // If the remote is in a time sequence but we're not, or we're in a different time sequence, jump to the remote's time sequence.
// if (currentlyInTimeSequence && (!this.currentlyInTimeSequence || currentTimeSequence != this.currentTimeSequence))
// {
// StartTimeSequence(currentTimeSequence);
// }
// If we're (now) in a time sequence, jump our progress to match the one on the remote
if (this.currentlyInTimeSequence)
{
TimeSequenceProgressToTime(timeSequenceProgress);
}
// // If we're (now) in a time sequence, jump our progress to match the one on the remote
// if (this.currentlyInTimeSequence)
// {
// TimeSequenceProgressToTime(timeSequenceSecondsPassed);
// }
// If the remote has finished it's time sequence and we have one waiting to be finalized, we can do so now
if (!currentlyInTimeSequence)
{
TryFinalizeTimeSequence();
}
}
// // If the remote has finished it's time sequence and we have one waiting to be finalized, we can do so now
// if (!currentlyInTimeSequence)
// {
// TryFinalizeTimeSequence();
// }
//}
#region Events
@@ -245,7 +247,7 @@ namespace Marro.PacManUdon
private void TimeSequenceExecuteStep(PacManTimeSequence timeSequence, int sequenceProgress)
{
// Debug.Log($"{gameObject} Triggered time sequence step for sequence {currentTimeSequence} with progress {sequenceProgress}");
Debug.Log($"{gameObject} Triggered time sequence step for sequence {currentTimeSequence} with progress {sequenceProgress}");
switch (timeSequence)
{
default:
@@ -299,7 +301,7 @@ namespace Marro.PacManUdon
private void TimeSequenceExecuteFinalize(PacManTimeSequence timeSequence)
{
// Debug.Log($"{gameObject} Triggered time sequence step for sequence {currentTimeSequence} with progress {sequenceProgress}");
Debug.Log($"{gameObject} Triggered time sequence finalize for sequence {currentTimeSequence}");
switch (timeSequence)
{
default:
@@ -343,7 +345,7 @@ namespace Marro.PacManUdon
private void TimeSequenceExecuteFinished(PacManTimeSequence timeSequence)
{
// Debug.Log($"{gameObject} Triggered time sequence step for sequence {currentTimeSequence} with progress {sequenceProgress}");
Debug.Log($"{gameObject} Triggered time sequence finished for sequence {currentTimeSequence}");
switch (timeSequence)
{
default:
@@ -447,16 +449,5 @@ namespace Marro.PacManUdon
}
#endregion
public int TimeSequenceProgress
{
get => timeSequenceProgress;
}
public float TimeSequenceSecondsPassed
{
get => timeSequenceSecondsPassed;
set => TimeSequenceProgressToTime(value);
}
}
}