Compare commits
13 Commits
43ee68dc44
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 26625f6b6f | |||
| 69a0a752be | |||
| 97fe8cd69f | |||
| 8d5362eff6 | |||
| e3f93c69c5 | |||
| 74223c8139 | |||
| 129ef16714 | |||
| a15f977107 | |||
| f53a41f70c | |||
| 16b0a348e4 | |||
| 8dec85e9f2 | |||
| a251763158 | |||
| 8e9936274f |
6
.vsconfig
Normal file
6
.vsconfig
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": "1.0",
|
||||
"components": [
|
||||
"Microsoft.VisualStudio.Workload.ManagedGame"
|
||||
]
|
||||
}
|
||||
@@ -5,7 +5,7 @@ TextureImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 12
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
mipMapMode: 1
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
|
||||
@@ -5,7 +5,7 @@ TextureImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 12
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
mipMapMode: 1
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
|
||||
@@ -5,7 +5,7 @@ TextureImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 12
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
mipMapMode: 1
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
|
||||
@@ -5,7 +5,7 @@ TextureImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 12
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
mipMapMode: 1
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
|
||||
@@ -5,7 +5,7 @@ TextureImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 12
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
mipMapMode: 1
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -44,14 +44,14 @@
|
||||
|
||||
public void Spawn()
|
||||
{
|
||||
Debug.Log($"{gameObject} Spawned");
|
||||
// Debug.Log($"{gameObject} Spawned");
|
||||
SetActive(true);
|
||||
activeCountdown = Random.Range(9, 10);
|
||||
}
|
||||
|
||||
public void Despawn()
|
||||
{
|
||||
Debug.Log($"{gameObject} Despawned");
|
||||
// Debug.Log($"{gameObject} Despawned");
|
||||
SetActive(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,120 +1,120 @@
|
||||
namespace Marro.PacManUdon
|
||||
{
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor.Animations;
|
||||
using UnityEditor;
|
||||
//namespace Marro.PacManUdon
|
||||
//{
|
||||
// using System.Collections;
|
||||
// using System.Collections.Generic;
|
||||
// using UnityEngine;
|
||||
// using UnityEditor.Animations;
|
||||
// using UnityEditor;
|
||||
|
||||
public class AnimationRecorder : MonoBehaviour
|
||||
{
|
||||
[SerializeField] AnimationClip clip;
|
||||
[SerializeField] GameObject root;
|
||||
[SerializeField] GameObject[] gameObjectsToAnimate;
|
||||
private GameObjectRecorder recorder;
|
||||
// public class AnimationRecorder : MonoBehaviour
|
||||
// {
|
||||
// [SerializeField] AnimationClip clip;
|
||||
// [SerializeField] GameObject root;
|
||||
// [SerializeField] GameObject[] gameObjectsToAnimate;
|
||||
// private GameObjectRecorder recorder;
|
||||
|
||||
void Start()
|
||||
{
|
||||
recorder = new GameObjectRecorder(root);
|
||||
// void Start()
|
||||
// {
|
||||
// recorder = new GameObjectRecorder(root);
|
||||
|
||||
foreach (GameObject gameObject in gameObjectsToAnimate)
|
||||
{
|
||||
// if(gameObject.GetComponent<PacMan>() || gameObject.GetComponent<Ghost>())
|
||||
// {
|
||||
// recorder.BindComponentsOfType<Transform>(gameObject, true);
|
||||
// }
|
||||
// recorder.BindComponentsOfType<Renderer>(gameObject, true);
|
||||
// foreach (GameObject gameObject in gameObjectsToAnimate)
|
||||
// {
|
||||
// // if(gameObject.GetComponent<PacMan>() || gameObject.GetComponent<Ghost>())
|
||||
// // {
|
||||
// // recorder.BindComponentsOfType<Transform>(gameObject, true);
|
||||
// // }
|
||||
// // recorder.BindComponentsOfType<Renderer>(gameObject, true);
|
||||
|
||||
string path = AnimationUtility.CalculateTransformPath(gameObject.transform, root.transform);
|
||||
// string path = AnimationUtility.CalculateTransformPath(gameObject.transform, root.transform);
|
||||
|
||||
recorder.Bind(EditorCurveBinding.FloatCurve(path, typeof(GameObject), "m_IsActive"));
|
||||
// recorder.Bind(EditorCurveBinding.FloatCurve(path, typeof(GameObject), "m_IsActive"));
|
||||
|
||||
Pellet pellet = gameObject.GetComponent<Pellet>();
|
||||
if (pellet)
|
||||
{
|
||||
recorder.Bind(EditorCurveBinding.FloatCurve(path, typeof(SpriteRenderer), "m_Enabled"));
|
||||
if (pellet.isPowerPellet)
|
||||
{
|
||||
recorder.Bind(EditorCurveBinding.PPtrCurve(path, typeof(SpriteRenderer), "m_Sprite"));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// Pellet pellet = gameObject.GetComponent<Pellet>();
|
||||
// if (pellet)
|
||||
// {
|
||||
// recorder.Bind(EditorCurveBinding.FloatCurve(path, typeof(SpriteRenderer), "m_Enabled"));
|
||||
// if (pellet.isPowerPellet)
|
||||
// {
|
||||
// recorder.Bind(EditorCurveBinding.PPtrCurve(path, typeof(SpriteRenderer), "m_Sprite"));
|
||||
// }
|
||||
// continue;
|
||||
// }
|
||||
|
||||
if (gameObject.GetComponent<SpriteRenderer>())
|
||||
{
|
||||
recorder.Bind(EditorCurveBinding.FloatCurve(path, typeof(SpriteRenderer), "m_Enabled"));
|
||||
recorder.Bind(EditorCurveBinding.PPtrCurve(path, typeof(SpriteRenderer), "m_Sprite"));
|
||||
}
|
||||
else if (gameObject.GetComponent<MeshRenderer>())
|
||||
{
|
||||
recorder.Bind(EditorCurveBinding.DiscreteCurve(path, typeof(MeshRenderer), "m_Enabled"));
|
||||
}
|
||||
recorder.Bind(EditorCurveBinding.FloatCurve(path, typeof(Transform), "m_LocalPosition.x"));
|
||||
recorder.Bind(EditorCurveBinding.FloatCurve(path, typeof(Transform), "m_LocalPosition.y"));
|
||||
recorder.Bind(EditorCurveBinding.FloatCurve(path, typeof(Transform), "m_LocalPosition.z"));
|
||||
}
|
||||
// if (gameObject.GetComponent<SpriteRenderer>())
|
||||
// {
|
||||
// recorder.Bind(EditorCurveBinding.FloatCurve(path, typeof(SpriteRenderer), "m_Enabled"));
|
||||
// recorder.Bind(EditorCurveBinding.PPtrCurve(path, typeof(SpriteRenderer), "m_Sprite"));
|
||||
// }
|
||||
// else if (gameObject.GetComponent<MeshRenderer>())
|
||||
// {
|
||||
// recorder.Bind(EditorCurveBinding.DiscreteCurve(path, typeof(MeshRenderer), "m_Enabled"));
|
||||
// }
|
||||
// recorder.Bind(EditorCurveBinding.FloatCurve(path, typeof(Transform), "m_LocalPosition.x"));
|
||||
// recorder.Bind(EditorCurveBinding.FloatCurve(path, typeof(Transform), "m_LocalPosition.y"));
|
||||
// recorder.Bind(EditorCurveBinding.FloatCurve(path, typeof(Transform), "m_LocalPosition.z"));
|
||||
// }
|
||||
|
||||
EditorCurveBinding[] bindings = recorder.GetBindings();
|
||||
foreach (EditorCurveBinding binding in bindings)
|
||||
{
|
||||
Debug.Log($"{binding.path}, {binding.propertyName}, {binding.type}");
|
||||
}
|
||||
}
|
||||
// EditorCurveBinding[] bindings = recorder.GetBindings();
|
||||
// foreach (EditorCurveBinding binding in bindings)
|
||||
// {
|
||||
// Debug.Log($"{binding.path}, {binding.propertyName}, {binding.type}");
|
||||
// }
|
||||
// }
|
||||
|
||||
private static string GetGameObjectPathToObject(GameObject obj, Transform target)
|
||||
{
|
||||
string path = "/" + obj.name;
|
||||
while (!obj.transform.parent.Equals(target))
|
||||
{
|
||||
obj = obj.transform.parent.gameObject;
|
||||
path = "/" + obj.name + path;
|
||||
}
|
||||
Debug.Log($"GetGameObjectPathToTransform from {obj} to {target.gameObject} gives {path}");
|
||||
return path;
|
||||
}
|
||||
// private static string GetGameObjectPathToObject(GameObject obj, Transform target)
|
||||
// {
|
||||
// string path = "/" + obj.name;
|
||||
// while (!obj.transform.parent.Equals(target))
|
||||
// {
|
||||
// obj = obj.transform.parent.gameObject;
|
||||
// path = "/" + obj.name + path;
|
||||
// }
|
||||
// Debug.Log($"GetGameObjectPathToTransform from {obj} to {target.gameObject} gives {path}");
|
||||
// return path;
|
||||
// }
|
||||
|
||||
void LateUpdate()
|
||||
{
|
||||
if (clip == null)
|
||||
return;
|
||||
// void LateUpdate()
|
||||
// {
|
||||
// if (clip == null)
|
||||
// return;
|
||||
|
||||
recorder.TakeSnapshot(Time.deltaTime);
|
||||
}
|
||||
// recorder.TakeSnapshot(Time.deltaTime);
|
||||
// }
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
if (clip == null)
|
||||
return;
|
||||
// void OnDisable()
|
||||
// {
|
||||
// if (clip == null)
|
||||
// return;
|
||||
|
||||
if (recorder.isRecording)
|
||||
{
|
||||
recorder.SaveToClip(clip);
|
||||
RemoveUnneededCurves(clip);
|
||||
}
|
||||
}
|
||||
// if (recorder.isRecording)
|
||||
// {
|
||||
// recorder.SaveToClip(clip);
|
||||
// RemoveUnneededCurves(clip);
|
||||
// }
|
||||
// }
|
||||
|
||||
private static void RemoveUnneededCurves(AnimationClip clip)
|
||||
{
|
||||
// Collect curves to process
|
||||
EditorCurveBinding[] bindings = AnimationUtility.GetCurveBindings(clip);
|
||||
List<EditorCurveBinding> unneededCurves = new List<EditorCurveBinding>();
|
||||
// private static void RemoveUnneededCurves(AnimationClip clip)
|
||||
// {
|
||||
// // Collect curves to process
|
||||
// EditorCurveBinding[] bindings = AnimationUtility.GetCurveBindings(clip);
|
||||
// List<EditorCurveBinding> unneededCurves = new List<EditorCurveBinding>();
|
||||
|
||||
foreach (var binding in bindings)
|
||||
{
|
||||
AnimationCurve curve = AnimationUtility.GetEditorCurve(clip, binding);
|
||||
// foreach (var binding in bindings)
|
||||
// {
|
||||
// AnimationCurve curve = AnimationUtility.GetEditorCurve(clip, binding);
|
||||
|
||||
if (curve == null || curve.keys.Length <= 2)
|
||||
{
|
||||
unneededCurves.Add(binding);
|
||||
}
|
||||
}
|
||||
// if (curve == null || curve.keys.Length <= 2)
|
||||
// {
|
||||
// unneededCurves.Add(binding);
|
||||
// }
|
||||
// }
|
||||
|
||||
// Remove unchanged curves
|
||||
foreach (var binding in unneededCurves)
|
||||
{
|
||||
AnimationUtility.SetEditorCurve(clip, binding, null);
|
||||
Debug.Log($"Removed unchanged curve for property: {binding.propertyName}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// // Remove unchanged curves
|
||||
// foreach (var binding in unneededCurves)
|
||||
// {
|
||||
// AnimationUtility.SetEditorCurve(clip, binding, null);
|
||||
// Debug.Log($"Removed unchanged curve for property: {binding.propertyName}");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,13 +5,10 @@ namespace Marro.PacManUdon
|
||||
using System;
|
||||
using UdonSharp;
|
||||
using UnityEngine;
|
||||
using VRC.SDKBase;
|
||||
using VRC.Udon;
|
||||
using VRC.SDK3.Components;
|
||||
using VRC.Udon.Common.Interfaces;
|
||||
using VRC.SDK3.Data;
|
||||
using VRC.SDKBase;
|
||||
|
||||
public partial class GameManager : UdonSharpBehaviour
|
||||
public partial class GameManager : SyncedObject
|
||||
{
|
||||
[Header("Static game components")]
|
||||
[SerializeField] private Maze[] mazes;
|
||||
@@ -26,6 +23,7 @@ namespace Marro.PacManUdon
|
||||
[SerializeField] private PlayerInput playerInput;
|
||||
[SerializeField] private Animator demo;
|
||||
[SerializeField] private SoundManager soundManager;
|
||||
[SerializeField] private NetworkManager networkManager;
|
||||
|
||||
[SerializeField] private GameObject recorder;
|
||||
|
||||
@@ -46,7 +44,7 @@ namespace Marro.PacManUdon
|
||||
private GameObject[] attractScreenElements;
|
||||
private GameObject[] intermissionScreenElements;
|
||||
|
||||
[UdonSynced, FieldChangeCallback(nameof(GameState))] private PacManGameState gameState;
|
||||
private PacManGameState gameState;
|
||||
[UdonSynced, FieldChangeCallback(nameof(Score))] private int score;
|
||||
[UdonSynced, FieldChangeCallback(nameof(Level))] private int level;
|
||||
[UdonSynced, FieldChangeCallback(nameof(HighScore))] private int highScore;
|
||||
@@ -79,6 +77,7 @@ namespace Marro.PacManUdon
|
||||
playerInput.Initialize(this);
|
||||
soundManager.Initialize();
|
||||
intermission2Pole.Initialize(this, ghostManager.Ghosts[0]);
|
||||
networkManager.Initialize();
|
||||
|
||||
HideEverything();
|
||||
|
||||
@@ -89,7 +88,7 @@ namespace Marro.PacManUdon
|
||||
StartAttractMode();
|
||||
}
|
||||
|
||||
public void FixedUpdate()
|
||||
public override void FixedUpdate()
|
||||
{
|
||||
TimeSequenceUpdate(Time.deltaTime);
|
||||
}
|
||||
@@ -106,6 +105,12 @@ namespace Marro.PacManUdon
|
||||
StartTimeSequence(PacManTimeSequence.WaitForStartTimeout);
|
||||
}
|
||||
|
||||
public void ResetButtonPressed()
|
||||
{
|
||||
Debug.Log($"{gameObject} Reset button was pressed!");
|
||||
Start();
|
||||
}
|
||||
|
||||
public void StartGameButtonPressed()
|
||||
{
|
||||
Debug.Log($"{gameObject} Start Game Button was pressed!");
|
||||
@@ -113,35 +118,16 @@ namespace Marro.PacManUdon
|
||||
StartTimeSequence(PacManTimeSequence.StartNewGame);
|
||||
}
|
||||
|
||||
public void SkipLevelButtonPressed()
|
||||
{
|
||||
if (Networking.IsOwner(gameObject))
|
||||
{
|
||||
Debug.Log($"{gameObject} Skip level button pressed!");
|
||||
StartTimeSequence(PacManTimeSequence.BoardClear);
|
||||
TimeSequenceSkipToNextStep();
|
||||
}
|
||||
}
|
||||
|
||||
public void StartDemoButtonPressed()
|
||||
{
|
||||
if (Networking.IsOwner(gameObject))
|
||||
{
|
||||
Debug.Log($"{gameObject} Start demo button pressed!");
|
||||
StartTimeSequence(PacManTimeSequence.Intermission1);
|
||||
}
|
||||
}
|
||||
|
||||
private void StartAttractMode()
|
||||
{
|
||||
#if RECORDING_DEMO
|
||||
// #if RECORDING_DEMO
|
||||
// recorder.gameObject.SetActive(true);
|
||||
StartTimeSequence(PacManTimeSequence.AttractScreenIntroduction);
|
||||
#else
|
||||
SetGameState(PacManGameState.AttractMode);
|
||||
HideEverything();
|
||||
demo.gameObject.SetActive(true);
|
||||
#endif
|
||||
// #else
|
||||
// SetGameState(PacManGameState.AttractMode);
|
||||
// HideEverything();
|
||||
// demo.gameObject.SetActive(true);
|
||||
// #endif
|
||||
}
|
||||
|
||||
private void InitializeNewGame()
|
||||
@@ -156,19 +142,16 @@ namespace Marro.PacManUdon
|
||||
{
|
||||
Debug.Log($"{gameObject} New level started!");
|
||||
|
||||
if (Networking.IsOwner(gameObject))
|
||||
pelletCountTotal = pelletPool.Pool.Length;
|
||||
pelletCountRemaining = pelletCountTotal;
|
||||
ghostManager.SetPelletsRemaining(pelletCountRemaining);
|
||||
ghostManager.NewLevel();
|
||||
|
||||
pelletManager.RestoreAllPellets();
|
||||
|
||||
if (pelletCountOverride > 0)
|
||||
{
|
||||
pelletCountTotal = pelletPool.Pool.Length;
|
||||
pelletCountRemaining = pelletCountTotal;
|
||||
ghostManager.SetPelletsRemaining(pelletCountRemaining);
|
||||
ghostManager.NewLevel();
|
||||
|
||||
pelletManager.RestoreAllPellets();
|
||||
|
||||
if (pelletCountOverride > 0)
|
||||
{
|
||||
pelletCountRemaining = pelletCountOverride;
|
||||
}
|
||||
pelletCountRemaining = pelletCountOverride;
|
||||
}
|
||||
mazeSpriteAnimator.SetBool("Blinking", false);
|
||||
}
|
||||
@@ -186,6 +169,13 @@ namespace Marro.PacManUdon
|
||||
pelletManager.SetPowerPelletsBlink(false);
|
||||
}
|
||||
|
||||
private void PrepareForCutscene()
|
||||
{
|
||||
HideEverything();
|
||||
RestartLevel();
|
||||
SetFrozen(true);
|
||||
}
|
||||
|
||||
public void GotPellet(bool addScore = true)
|
||||
{
|
||||
pelletCountRemaining--;
|
||||
@@ -274,10 +264,9 @@ namespace Marro.PacManUdon
|
||||
mazeSpriteAnimator.SetBool("Blinking", true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void HideEverything()
|
||||
{
|
||||
SetMazeActive(false);
|
||||
SetPelletsActive(false);
|
||||
SetMazeVisible(false);
|
||||
SetGhostsActive(false);
|
||||
@@ -292,11 +281,6 @@ namespace Marro.PacManUdon
|
||||
demo.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
void SetMazeActive(bool active)
|
||||
{
|
||||
maze.gameObject.SetActive(active);
|
||||
}
|
||||
|
||||
void SetPelletsActive(bool active)
|
||||
{
|
||||
pelletPool.gameObject.SetActive(active);
|
||||
@@ -438,6 +422,27 @@ namespace Marro.PacManUdon
|
||||
ghostManager.SetOwner(Networking.LocalPlayer);
|
||||
}
|
||||
|
||||
public override void AppendSyncedData(byte[][] data, ref int offset, NetworkEventType eventType)
|
||||
{
|
||||
data[offset++] = new byte[] { Int32ToByte((int)gameState) };
|
||||
data[offset++] = BitConverter.GetBytes(currentlyInTimeSequence);
|
||||
data[offset++] = new byte[] { Int32ToByte((int)currentTimeSequence) };
|
||||
data[offset++] = BitConverter.GetBytes(timeSequenceProgress);
|
||||
}
|
||||
|
||||
public override bool SetSyncedData(byte[] data, ref int offset, NetworkEventType eventType)
|
||||
{
|
||||
SetGameState((PacManGameState)data[offset++]);
|
||||
|
||||
var currentlyInTimeSequence = BitConverter.ToBoolean(data, offset++);
|
||||
var currentTimeSequence = (PacManTimeSequence)data[offset++];
|
||||
var timeSequenceProgress = BitConverter.ToSingle(data, offset);
|
||||
offset += 4;
|
||||
TimeSequenceSyncWithRemote(currentlyInTimeSequence, currentTimeSequence, timeSequenceProgress);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int ExtraLives
|
||||
{
|
||||
set
|
||||
@@ -492,226 +497,8 @@ namespace Marro.PacManUdon
|
||||
get => level;
|
||||
}
|
||||
|
||||
#region TIME SEQUENCE BEHAVIOUR
|
||||
// A note about the quality of the code here:
|
||||
// I intended to write this using proper classes, right until I realized Udon does not support instantiating classes.
|
||||
// While I'm not a big fan of the partial class solution that I ended up doing (static classes would still be neater, or perhaps separate UdonSharpBehaviour instances),
|
||||
// I'm not redoing this unless I get instantiatable classes before I wrap up this project.
|
||||
|
||||
bool currentlyInTimeSequence;
|
||||
PacManTimeSequence currentTimeSequence;
|
||||
bool hasTimeSequenceQueued;
|
||||
private DataList timeSequenceQueue;
|
||||
[UdonSynced] float timeSequenceSecondsPassed;
|
||||
int timeSequenceProgress;
|
||||
float[] timeSequenceKeyframeTimes;
|
||||
|
||||
private void StartTimeSequence(PacManTimeSequence timeSequence)
|
||||
{
|
||||
if (timeSequenceQueue == null)
|
||||
{
|
||||
timeSequenceQueue = new DataList();
|
||||
}
|
||||
|
||||
if (currentlyInTimeSequence == true)
|
||||
{
|
||||
int timeSequenceInt = (int)timeSequence; // Doing the conversion in the line below crashes the script. I love working in Udon
|
||||
timeSequenceQueue.Add(timeSequenceInt);
|
||||
hasTimeSequenceQueued = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Log($"StartTimeSequence: {timeSequence}");
|
||||
|
||||
currentlyInTimeSequence = true;
|
||||
currentTimeSequence = timeSequence;
|
||||
timeSequenceProgress = 0;
|
||||
timeSequenceSecondsPassed = 0;
|
||||
timeSequenceKeyframeTimes = GetTimeSequenceKeyframeTimes(timeSequence);
|
||||
TimeSequenceProgressToTime(timeSequenceSecondsPassed);
|
||||
}
|
||||
|
||||
private void InsertTimeSequence(PacManTimeSequence timeSequence)
|
||||
{
|
||||
StartTimeSequence(timeSequence);
|
||||
}
|
||||
|
||||
private void TimeSequenceUpdate(float deltaSeconds)
|
||||
{
|
||||
if (!currentlyInTimeSequence && hasTimeSequenceQueued)
|
||||
{
|
||||
timeSequenceQueue.TryGetValue(0, out DataToken nextTimeSequence);
|
||||
StartTimeSequence((PacManTimeSequence)nextTimeSequence.Int);
|
||||
timeSequenceQueue.RemoveAt(0);
|
||||
hasTimeSequenceQueued = timeSequenceQueue.Count > 0 ? true : false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentlyInTimeSequence)
|
||||
{
|
||||
if (hasTimeSequenceQueued)
|
||||
{
|
||||
while (currentlyInTimeSequence)
|
||||
{
|
||||
TimeSequenceSkipToNextStep();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TimeSequenceProgressToTime(timeSequenceSecondsPassed + deltaSeconds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void TimeSequenceSkipToNextStep()
|
||||
{
|
||||
// Debug.Log($"{gameObject} TimeSequenceSkipToNextStep");
|
||||
if (timeSequenceProgress < timeSequenceKeyframeTimes.Length)
|
||||
{
|
||||
TimeSequenceProgressToTime(timeSequenceKeyframeTimes[timeSequenceProgress]);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"{gameObject} Tried skipping to next time sequence step when already on last step!");
|
||||
currentlyInTimeSequence = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void TimeSequenceProgressToTime(float seconds)
|
||||
{
|
||||
timeSequenceSecondsPassed = seconds;
|
||||
while (timeSequenceSecondsPassed >= timeSequenceKeyframeTimes[timeSequenceProgress])
|
||||
{
|
||||
TimeSequenceExecuteStep(timeSequenceProgress);
|
||||
|
||||
timeSequenceProgress += 1;
|
||||
if (timeSequenceProgress >= timeSequenceKeyframeTimes.Length)
|
||||
{
|
||||
currentlyInTimeSequence = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void TimeSequenceExecuteStep(int sequenceProgress)
|
||||
{
|
||||
// Debug.Log($"{gameObject} Triggered time sequence step for sequence {currentTimeSequence} with progress {sequenceProgress}");
|
||||
switch (currentTimeSequence)
|
||||
{
|
||||
default:
|
||||
Debug.LogError($"{gameObject} No time sequence keyframes known for sequence {currentTimeSequence}");
|
||||
break;
|
||||
case PacManTimeSequence.AttractScreenIntroduction:
|
||||
TimeSequenceStepAttractScreenIntroduction(sequenceProgress);
|
||||
break;
|
||||
case PacManTimeSequence.AttractScreenDemo:
|
||||
TimeSequenceStepAttractScreenDemo(sequenceProgress);
|
||||
break;
|
||||
case PacManTimeSequence.WaitForStart:
|
||||
TimeSequenceStepWaitForStart(sequenceProgress);
|
||||
break;
|
||||
case PacManTimeSequence.WaitForStartTimeout:
|
||||
TimeSequenceStepWaitForStartTimeout(sequenceProgress);
|
||||
break;
|
||||
case PacManTimeSequence.StartNewGame:
|
||||
TimeSequenceStepStartNewGame(sequenceProgress);
|
||||
break;
|
||||
case PacManTimeSequence.BoardClear:
|
||||
TimeSequenceStepBoardClear(sequenceProgress);
|
||||
break;
|
||||
case PacManTimeSequence.StartNewLevel:
|
||||
TimeSequenceStepStartNewLevel(sequenceProgress);
|
||||
break;
|
||||
case PacManTimeSequence.GhostCaught:
|
||||
TimeSequenceStepGhostCaught(sequenceProgress);
|
||||
break;
|
||||
case PacManTimeSequence.PacManCaught:
|
||||
TimeSequenceStepPacManCaught(sequenceProgress);
|
||||
break;
|
||||
case PacManTimeSequence.RestartLevel:
|
||||
TimeSequenceStepRestartLevel(sequenceProgress);
|
||||
break;
|
||||
case PacManTimeSequence.GameOver:
|
||||
TimeSequenceStepGameOver(sequenceProgress);
|
||||
break;
|
||||
case PacManTimeSequence.Intermission1:
|
||||
TimeSequenceStepIntermission1(sequenceProgress);
|
||||
break;
|
||||
case PacManTimeSequence.Intermission2:
|
||||
TimeSequenceStepIntermission2(sequenceProgress);
|
||||
break;
|
||||
case PacManTimeSequence.Intermission3:
|
||||
TimeSequenceStepIntermission3(sequenceProgress);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private float[] GetTimeSequenceKeyframeTimes(PacManTimeSequence timeSequence)
|
||||
{
|
||||
switch (timeSequence)
|
||||
{
|
||||
default:
|
||||
Debug.LogError($"{gameObject} No time sequence keyframe times known for sequence {timeSequence}");
|
||||
return new float[0];
|
||||
case PacManTimeSequence.AttractScreenIntroduction:
|
||||
return DeltaToAbsolute(new float[] { 0, 0.032f, 1f, 1f, .5f, .5f, 1f, .5f, .5f, 1f, .5f, .5f, 1f, .5f, 1f, 1f, 1f,
|
||||
5f, 0.2f, 2f, 0.91667f, 2f, 0.91667f, 2f, 0.91667f, 2f, 0.91667f });
|
||||
case PacManTimeSequence.AttractScreenDemo:
|
||||
return DeltaToAbsolute(new float[] { 0, 0.016f, 0.05f, 0.16f, 0.33f, 1.85f, 54f });
|
||||
case PacManTimeSequence.WaitForStart:
|
||||
return DeltaToAbsolute(new float[] { 0, 0.016f });
|
||||
case PacManTimeSequence.WaitForStartTimeout:
|
||||
return DeltaToAbsolute(new float[] { 0, 5f });
|
||||
case PacManTimeSequence.StartNewGame:
|
||||
return DeltaToAbsolute(new float[] { 0, 0.016f, 2.2f, 0.032f, 0.032f, 1.92f, 0.032f });
|
||||
case PacManTimeSequence.BoardClear:
|
||||
return DeltaToAbsolute(new float[] { 0, 2f, 0.016f, 1.6f - 0.016f, 0.016f, 0.032f, 0.3f });
|
||||
case PacManTimeSequence.StartNewLevel:
|
||||
return DeltaToAbsolute(new float[] { 0, 0.064f, 0.032f, 1.85f, 0.016f });
|
||||
case PacManTimeSequence.GhostCaught:
|
||||
return DeltaToAbsolute(new float[] { 0, 0.91667f });
|
||||
case PacManTimeSequence.PacManCaught:
|
||||
return DeltaToAbsolute(new float[] { 0, 1, 0.35f, 2.40f, 2f });
|
||||
case PacManTimeSequence.RestartLevel:
|
||||
return DeltaToAbsolute(new float[] { 0, 0.016f, 0.064f, 0.032f, 1.85f, 0.016f });
|
||||
case PacManTimeSequence.GameOver:
|
||||
return DeltaToAbsolute(new float[] { 0, 1.95f });
|
||||
case PacManTimeSequence.Intermission1:
|
||||
return DeltaToAbsolute(new float[] { 0, 0.316f, 0.3f, 3.96f, 2.25f, 3.93f });
|
||||
case PacManTimeSequence.Intermission2:
|
||||
return DeltaToAbsolute(new float[] { 0, 0.25f, 0.083f, 0.3f, 1.43f, 2.5f, 1.816f, 1.25f, 0.017f, 1f, 1.966f, 0.033f });
|
||||
case PacManTimeSequence.Intermission3:
|
||||
return DeltaToAbsolute(new float[] { 0, 0.316f, 0.7f, 3.35f, 0.83f, 3.67f });
|
||||
}
|
||||
}
|
||||
|
||||
private static float[] DeltaToAbsolute(float[] delta)
|
||||
{
|
||||
if (delta.Length < 1)
|
||||
{
|
||||
return new float[0];
|
||||
}
|
||||
|
||||
float[] absolute = new float[delta.Length];
|
||||
absolute[0] = delta[0];
|
||||
for (int i = 1; i < delta.Length; i++)
|
||||
{
|
||||
absolute[i] = delta[i] + absolute[i - 1];
|
||||
}
|
||||
return absolute;
|
||||
}
|
||||
|
||||
public int TimeSequenceProgress
|
||||
{
|
||||
get => timeSequenceProgress;
|
||||
}
|
||||
|
||||
public float TimeSequenceSecondsPassed
|
||||
{
|
||||
get => timeSequenceSecondsPassed;
|
||||
set => TimeSequenceProgressToTime(value);
|
||||
}
|
||||
#endregion
|
||||
public static byte Int32ToByte(int value) =>
|
||||
(byte)value;
|
||||
//byte.Parse(value.ToString()); // This is the only way I could find to cast an int to byte in Udon, a regular cast crashes in runtime...
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -72,21 +72,20 @@ namespace Marro.PacManUdon
|
||||
private Vector2[] predefinedPath;
|
||||
private int predefinedPathIndex;
|
||||
|
||||
[UdonSynced] int rngState;
|
||||
[UdonSynced] private Vector2 syncedPosition;
|
||||
[UdonSynced] private float speed;
|
||||
[UdonSynced] private Vector2 direction;
|
||||
[UdonSynced] private Vector2 target;
|
||||
[UdonSynced] private bool offGrid;
|
||||
[UdonSynced] private bool inTunnel;
|
||||
[UdonSynced] private PacManGhostState ghostState;
|
||||
[UdonSynced] private bool isScared;
|
||||
[UdonSynced] private bool scattering;
|
||||
[UdonSynced] private PacManGhostFrozenState frozenState;
|
||||
[UdonSynced] private bool hideUntilUnfrozen;
|
||||
[UdonSynced] private int housePelletCounter;
|
||||
[UdonSynced] private bool housePelletCounterActive;
|
||||
[UdonSynced] private bool turnAroundSoon;
|
||||
int rngState;
|
||||
private Vector2 syncedPosition;
|
||||
private float speed;
|
||||
private Vector2 target;
|
||||
private bool offGrid;
|
||||
private bool inTunnel;
|
||||
private PacManGhostState ghostState;
|
||||
private bool isScared;
|
||||
private bool scattering;
|
||||
private PacManGhostFrozenState frozenState;
|
||||
private bool hideUntilUnfrozen;
|
||||
private int housePelletCounter;
|
||||
private bool housePelletCounterActive;
|
||||
private bool turnAroundSoon;
|
||||
|
||||
public void Initialize(PacMan pacMan, Ghost blinky, Vector2 homePosition, Vector2 idlePosition1, Vector2 idlePosition2, Vector2 cornerPosition)
|
||||
{
|
||||
@@ -151,7 +150,7 @@ namespace Marro.PacManUdon
|
||||
// Debug.Log($"{gameObject} reset with state: {state}, target: {target}, offGrid: {offGrid}");
|
||||
}
|
||||
|
||||
void FixedUpdate()
|
||||
public override void FixedUpdate()
|
||||
{
|
||||
if (ghostType == PacManGhostType.Blinky)
|
||||
{
|
||||
@@ -478,7 +477,7 @@ namespace Marro.PacManUdon
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateAnimator()
|
||||
protected override void UpdateAnimator()
|
||||
{
|
||||
if (!gameObject.activeInHierarchy)
|
||||
return;
|
||||
@@ -558,10 +557,10 @@ namespace Marro.PacManUdon
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateSpeed()
|
||||
public void UpdateSpeed()
|
||||
{
|
||||
speed = ghostManager.GetTargetSpeed(this, ghostState, isScared, inTunnel);
|
||||
Debug.Log($"Ghost updated speed to {speed}, level: {ghostManager.elroyLevel}");
|
||||
// Debug.Log($"Ghost with type {ghostType} updated speed to {speed}, ghostState: {ghostState}, isScared: {isScared}, inTunnel: {inTunnel}, elroyLevel: {ghostManager.elroyLevel}");
|
||||
}
|
||||
|
||||
public void ResetHousePelletCounter()
|
||||
@@ -639,10 +638,6 @@ namespace Marro.PacManUdon
|
||||
ghostState = state;
|
||||
UpdateAnimator();
|
||||
UpdateSpeed();
|
||||
if (Networking.IsOwner(gameObject))
|
||||
{
|
||||
RequestSerialization();
|
||||
}
|
||||
}
|
||||
|
||||
private void SetScared(bool scared)
|
||||
@@ -655,11 +650,6 @@ namespace Marro.PacManUdon
|
||||
{
|
||||
SetWhite(false);
|
||||
}
|
||||
|
||||
if (Networking.IsOwner(gameObject))
|
||||
{
|
||||
RequestSerialization();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetScattering(bool scattering, bool reverseDirection = true)
|
||||
@@ -695,14 +685,10 @@ namespace Marro.PacManUdon
|
||||
}
|
||||
animator.speed = frozen && !keepAnimating ? 0 : 1; // This would cause issues if the returning sprite was animated, luckily it isn't :)
|
||||
|
||||
if (frozen == false)
|
||||
if (frozen == false && faceInStartingDirectionUntilUnfrozen)
|
||||
{
|
||||
|
||||
if (faceInStartingDirectionUntilUnfrozen)
|
||||
{
|
||||
faceInStartingDirectionUntilUnfrozen = false;
|
||||
UpdateAnimator();
|
||||
}
|
||||
faceInStartingDirectionUntilUnfrozen = false;
|
||||
UpdateAnimator();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -787,45 +773,12 @@ namespace Marro.PacManUdon
|
||||
|
||||
public bool IsScared => isScared;
|
||||
|
||||
public override Vector2 GetPosition()
|
||||
{
|
||||
return (Vector2)transform.localPosition;
|
||||
}
|
||||
|
||||
public override void SetPosition(Vector2 position)
|
||||
{
|
||||
GridMoverTools.SetPosition(position, transform);
|
||||
}
|
||||
|
||||
public override Vector2 GetDirection()
|
||||
{
|
||||
return direction;
|
||||
}
|
||||
|
||||
public void SetDirection(Vector2 direction)
|
||||
{
|
||||
this.direction = direction;
|
||||
UpdateAnimator();
|
||||
RequestSerialization();
|
||||
}
|
||||
|
||||
public void SetSpeed(float speed)
|
||||
{
|
||||
this.speed = speed;
|
||||
UpdateAnimator();
|
||||
}
|
||||
|
||||
public override void OnPreSerialization()
|
||||
{
|
||||
syncedPosition = GetPosition();
|
||||
}
|
||||
|
||||
public override void OnDeserialization()
|
||||
{
|
||||
SetPosition(syncedPosition);
|
||||
UpdateAnimator();
|
||||
}
|
||||
|
||||
void OnTriggerEnter(Collider other)
|
||||
{
|
||||
if (Networking.IsOwner(gameObject) && other.gameObject.GetComponent<PacManGhostCollider>())
|
||||
|
||||
@@ -190,14 +190,14 @@
|
||||
gameController.GhostCaught(0);
|
||||
return;
|
||||
}
|
||||
Debug.Log($"{gameObject} GhostCaughtQueue with ghost {ghost}");
|
||||
// Debug.Log($"{gameObject} GhostCaughtQueue with ghost {ghost}");
|
||||
ghostScaredQueue.Add(ghost);
|
||||
GhostCaughtExecute(ghost);
|
||||
}
|
||||
|
||||
public void GhostCaughtContinue()
|
||||
{
|
||||
Debug.Log($"{gameObject} GhostCaughtContinue with ghost queue length {ghostScaredQueue.Count}");
|
||||
// Debug.Log($"{gameObject} GhostCaughtContinue with ghost queue length {ghostScaredQueue.Count}");
|
||||
if (!ghostScaredQueue.TryGetValue(0, out DataToken currentGhost))
|
||||
{
|
||||
Debug.LogError("Called GhostCaughtContinue without a ghost in the queue!");
|
||||
@@ -326,9 +326,10 @@
|
||||
pelletTimeoutLimit = PacManConstants.GetGhostHousePelletTimeoutLimitForLevel(level);
|
||||
|
||||
int[] privatePelletCounterReleaseValues = PacManConstants.GetGhostHousePrivatePelletCounterLimitForLevel(level);
|
||||
for (int i = 0; i < Math.Min(sharedPelletCounterReleaseValues.Length, ghosts.Length); i++)
|
||||
for (int i = 0; i < ghosts.Length; i++)
|
||||
{
|
||||
ghosts[i].SetHousePelletCounterLimit(privatePelletCounterReleaseValues[i]);
|
||||
Reset(); // Reset needed to properly apply level
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,24 +3,53 @@ namespace Marro.PacManUdon
|
||||
using System;
|
||||
using UdonSharp;
|
||||
using UnityEngine;
|
||||
using VRC.Udon.Serialization.OdinSerializer;
|
||||
|
||||
public abstract class GridMover : UdonSharpBehaviour
|
||||
public abstract class GridMover : SyncedObject
|
||||
{
|
||||
protected Vector2 direction;
|
||||
|
||||
public virtual Vector2 GetPosition()
|
||||
{
|
||||
Debug.LogWarning($"{gameObject} does not implement GetPosition");
|
||||
return Vector2.zero;
|
||||
return (Vector2)transform.localPosition;
|
||||
}
|
||||
|
||||
public virtual void SetPosition(Vector2 position)
|
||||
{
|
||||
Debug.LogWarning($"{gameObject} does not implement SetPosition");
|
||||
transform.localPosition = new Vector3(position.x, position.y, transform.localPosition.z);
|
||||
}
|
||||
|
||||
public virtual Vector2 GetDirection()
|
||||
{
|
||||
Debug.LogWarning($"{gameObject} does not implement GetDirection");
|
||||
return Vector2.zero;
|
||||
return direction;
|
||||
}
|
||||
|
||||
public void SetDirection(Vector2 direction)
|
||||
{
|
||||
this.direction = direction;
|
||||
UpdateAnimator();
|
||||
}
|
||||
|
||||
protected abstract void UpdateAnimator();
|
||||
|
||||
public override void AppendSyncedData(byte[][] data, ref int offset, NetworkEventType eventType)
|
||||
{
|
||||
var position = GetPosition();
|
||||
data[offset++] = BitConverter.GetBytes(position.x);
|
||||
data[offset++] = BitConverter.GetBytes(position.y);
|
||||
|
||||
var direction = GetDirection();
|
||||
data[offset++] = BitConverter.GetBytes(direction.x);
|
||||
data[offset++] = BitConverter.GetBytes(direction.y);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,12 +10,6 @@ namespace Marro.PacManUdon
|
||||
return currentPosition + direction * speed * Time.deltaTime;
|
||||
}
|
||||
|
||||
public static void SetPosition(Vector2 position, Transform transform)
|
||||
{
|
||||
transform.localPosition = new Vector3(position.x, position.y, transform.localPosition.z);
|
||||
}
|
||||
|
||||
|
||||
public static Vector2 PositionToGrid(Vector2 position)
|
||||
{
|
||||
return new Vector2((float)Math.Round(position.x), (float)Math.Round(position.y));
|
||||
|
||||
@@ -101,14 +101,12 @@ namespace Marro.PacManUdon
|
||||
|
||||
if (level == PoleStrechLevels.Strech1 || level == PoleStrechLevels.Separated) // Step forward timed procedure
|
||||
{
|
||||
Debug.Log($"Intermission2Pole Intermission2PoleUpdate");
|
||||
_gameManager.Intermission2PoleUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetStrechLevel(PoleStrechLevels level)
|
||||
{
|
||||
Debug.Log($"Intermission2Pole SetStrechLevel {level}");
|
||||
_animator.SetFloat("Strech", GetAnimatorValueForStrechLevel(level));
|
||||
}
|
||||
|
||||
|
||||
640
Assets/Scripts/NetworkManager.asset
Normal file
640
Assets/Scripts/NetworkManager.asset
Normal file
@@ -0,0 +1,640 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: c333ccfdd0cbdbc4ca30cef2dd6e6b9b, type: 3}
|
||||
m_Name: NetworkManager
|
||||
m_EditorClassIdentifier:
|
||||
serializedUdonProgramAsset: {fileID: 11400000, guid: 37b60ab207700554ba5c119f63c3c7bd, type: 2}
|
||||
udonAssembly:
|
||||
assemblyError:
|
||||
sourceCsScript: {fileID: 11500000, guid: ac984c07ae3e9674a850c3916be56ca3, type: 3}
|
||||
scriptVersion: 2
|
||||
compiledVersion: 2
|
||||
behaviourSyncMode: 0
|
||||
hasInteractEvent: 0
|
||||
scriptID: -3442137929426346155
|
||||
serializationData:
|
||||
SerializedFormat: 2
|
||||
SerializedBytes:
|
||||
ReferencedUnityObjects: []
|
||||
SerializedBytesString:
|
||||
Prefab: {fileID: 0}
|
||||
PrefabModificationsReferencedUnityObjects: []
|
||||
PrefabModifications: []
|
||||
SerializationNodes:
|
||||
- Name: fieldDefinitions
|
||||
Entry: 7
|
||||
Data: 0|System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[UdonSharp.Compiler.FieldDefinition,
|
||||
UdonSharp.Editor]], mscorlib
|
||||
- Name: comparer
|
||||
Entry: 7
|
||||
Data: 1|System.Collections.Generic.GenericEqualityComparer`1[[System.String,
|
||||
mscorlib]], mscorlib
|
||||
- Name:
|
||||
Entry: 8
|
||||
Data:
|
||||
- Name:
|
||||
Entry: 12
|
||||
Data: 11
|
||||
- Name:
|
||||
Entry: 7
|
||||
Data:
|
||||
- Name: $k
|
||||
Entry: 1
|
||||
Data: syncedObjects
|
||||
- Name: $v
|
||||
Entry: 7
|
||||
Data: 2|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
|
||||
- Name: <Name>k__BackingField
|
||||
Entry: 1
|
||||
Data: syncedObjects
|
||||
- Name: <UserType>k__BackingField
|
||||
Entry: 7
|
||||
Data: 3|System.RuntimeType, mscorlib
|
||||
- Name:
|
||||
Entry: 1
|
||||
Data: Marro.PacManUdon.SyncedObject[], Assembly-CSharp
|
||||
- Name:
|
||||
Entry: 8
|
||||
Data:
|
||||
- Name: <SystemType>k__BackingField
|
||||
Entry: 7
|
||||
Data: 4|System.RuntimeType, mscorlib
|
||||
- Name:
|
||||
Entry: 1
|
||||
Data: UnityEngine.Component[], UnityEngine.CoreModule
|
||||
- Name:
|
||||
Entry: 8
|
||||
Data:
|
||||
- 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: 5|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
|
||||
- Name:
|
||||
Entry: 12
|
||||
Data: 1
|
||||
- Name:
|
||||
Entry: 7
|
||||
Data: 6|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: DebugImageToIndicateOwner
|
||||
- Name: $v
|
||||
Entry: 7
|
||||
Data: 7|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
|
||||
- Name: <Name>k__BackingField
|
||||
Entry: 1
|
||||
Data: DebugImageToIndicateOwner
|
||||
- Name: <UserType>k__BackingField
|
||||
Entry: 7
|
||||
Data: 8|System.RuntimeType, mscorlib
|
||||
- Name:
|
||||
Entry: 1
|
||||
Data: UnityEngine.Animator, UnityEngine.AnimationModule
|
||||
- Name:
|
||||
Entry: 8
|
||||
Data:
|
||||
- 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: true
|
||||
- Name: _fieldAttributes
|
||||
Entry: 7
|
||||
Data: 9|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
|
||||
- Name:
|
||||
Entry: 12
|
||||
Data: 1
|
||||
- Name:
|
||||
Entry: 7
|
||||
Data: 10|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: isOwner
|
||||
- Name: $v
|
||||
Entry: 7
|
||||
Data: 11|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
|
||||
- Name: <Name>k__BackingField
|
||||
Entry: 1
|
||||
Data: isOwner
|
||||
- Name: <UserType>k__BackingField
|
||||
Entry: 7
|
||||
Data: 12|System.RuntimeType, mscorlib
|
||||
- Name:
|
||||
Entry: 1
|
||||
Data: System.Boolean, mscorlib
|
||||
- Name:
|
||||
Entry: 8
|
||||
Data:
|
||||
- Name: <SystemType>k__BackingField
|
||||
Entry: 9
|
||||
Data: 12
|
||||
- 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: 13|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: isSynced
|
||||
- Name: $v
|
||||
Entry: 7
|
||||
Data: 14|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
|
||||
- Name: <Name>k__BackingField
|
||||
Entry: 1
|
||||
Data: isSynced
|
||||
- Name: <UserType>k__BackingField
|
||||
Entry: 9
|
||||
Data: 12
|
||||
- Name: <SystemType>k__BackingField
|
||||
Entry: 9
|
||||
Data: 12
|
||||
- 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: 15|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: startTimeTicks
|
||||
- Name: $v
|
||||
Entry: 7
|
||||
Data: 16|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
|
||||
- Name: <Name>k__BackingField
|
||||
Entry: 1
|
||||
Data: startTimeTicks
|
||||
- Name: <UserType>k__BackingField
|
||||
Entry: 7
|
||||
Data: 17|System.RuntimeType, mscorlib
|
||||
- Name:
|
||||
Entry: 1
|
||||
Data: System.Int64, mscorlib
|
||||
- Name:
|
||||
Entry: 8
|
||||
Data:
|
||||
- Name: <SystemType>k__BackingField
|
||||
Entry: 9
|
||||
Data: 17
|
||||
- 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: 18|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: nextEventTimeTicks
|
||||
- Name: $v
|
||||
Entry: 7
|
||||
Data: 19|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
|
||||
- Name: <Name>k__BackingField
|
||||
Entry: 1
|
||||
Data: nextEventTimeTicks
|
||||
- Name: <UserType>k__BackingField
|
||||
Entry: 9
|
||||
Data: 17
|
||||
- Name: <SystemType>k__BackingField
|
||||
Entry: 9
|
||||
Data: 17
|
||||
- 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: 20|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: retriesWithoutSuccess
|
||||
- Name: $v
|
||||
Entry: 7
|
||||
Data: 21|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
|
||||
- Name: <Name>k__BackingField
|
||||
Entry: 1
|
||||
Data: retriesWithoutSuccess
|
||||
- Name: <UserType>k__BackingField
|
||||
Entry: 7
|
||||
Data: 22|System.RuntimeType, mscorlib
|
||||
- Name:
|
||||
Entry: 1
|
||||
Data: System.Int32, mscorlib
|
||||
- Name:
|
||||
Entry: 8
|
||||
Data:
|
||||
- Name: <SystemType>k__BackingField
|
||||
Entry: 9
|
||||
Data: 22
|
||||
- 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: 23|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: buffer
|
||||
- Name: $v
|
||||
Entry: 7
|
||||
Data: 24|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
|
||||
- Name: <Name>k__BackingField
|
||||
Entry: 1
|
||||
Data: buffer
|
||||
- Name: <UserType>k__BackingField
|
||||
Entry: 7
|
||||
Data: 25|System.RuntimeType, mscorlib
|
||||
- Name:
|
||||
Entry: 1
|
||||
Data: System.Byte[], mscorlib
|
||||
- Name:
|
||||
Entry: 8
|
||||
Data:
|
||||
- Name: <SystemType>k__BackingField
|
||||
Entry: 9
|
||||
Data: 25
|
||||
- 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: 26|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: index
|
||||
- Name: $v
|
||||
Entry: 7
|
||||
Data: 27|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
|
||||
- Name: <Name>k__BackingField
|
||||
Entry: 1
|
||||
Data: index
|
||||
- Name: <UserType>k__BackingField
|
||||
Entry: 9
|
||||
Data: 22
|
||||
- Name: <SystemType>k__BackingField
|
||||
Entry: 9
|
||||
Data: 22
|
||||
- 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: 28|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: networkedData
|
||||
- Name: $v
|
||||
Entry: 7
|
||||
Data: 29|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
|
||||
- Name: <Name>k__BackingField
|
||||
Entry: 1
|
||||
Data: networkedData
|
||||
- Name: <UserType>k__BackingField
|
||||
Entry: 9
|
||||
Data: 25
|
||||
- Name: <SystemType>k__BackingField
|
||||
Entry: 9
|
||||
Data: 25
|
||||
- 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: 30|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
|
||||
- Name:
|
||||
Entry: 12
|
||||
Data: 1
|
||||
- Name:
|
||||
Entry: 7
|
||||
Data: 31|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: <CurrentTimeTicks>k__BackingField
|
||||
- Name: $v
|
||||
Entry: 7
|
||||
Data: 32|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
|
||||
- Name: <Name>k__BackingField
|
||||
Entry: 1
|
||||
Data: <CurrentTimeTicks>k__BackingField
|
||||
- Name: <UserType>k__BackingField
|
||||
Entry: 9
|
||||
Data: 17
|
||||
- Name: <SystemType>k__BackingField
|
||||
Entry: 9
|
||||
Data: 17
|
||||
- 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: 33|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:
|
||||
- Name:
|
||||
Entry: 8
|
||||
Data:
|
||||
8
Assets/Scripts/NetworkManager.asset.meta
Normal file
8
Assets/Scripts/NetworkManager.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a327a0e472dbf694a8e2b23bf0ce90d0
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
525
Assets/Scripts/NetworkManager.cs
Normal file
525
Assets/Scripts/NetworkManager.cs
Normal file
@@ -0,0 +1,525 @@
|
||||
using Cysharp.Threading.Tasks.Triggers;
|
||||
using JetBrains.Annotations;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
using UdonSharp;
|
||||
using UnityEngine;
|
||||
using VRC.SDK3.UdonNetworkCalling;
|
||||
using VRC.SDKBase;
|
||||
using VRC.Udon.ClientBindings.Interfaces;
|
||||
using VRC.Udon.Common;
|
||||
|
||||
namespace Marro.PacManUdon
|
||||
{
|
||||
public enum NetworkEventType
|
||||
{
|
||||
FullSync = 0,
|
||||
PacManTurn = 1,
|
||||
}
|
||||
public class NetworkManager : UdonSharpBehaviour
|
||||
{
|
||||
// The network manager works by serializing event and state data into a byte array, including a timestamp for each event.
|
||||
// If user is owner, this data is created and stored in a buffer which is cleared upon transmission.
|
||||
// If user is not owner, this data is read into the same buffer and replayed based on the included timestamp.
|
||||
// Data replay is delayed with an offset on the timestamp to hide inconsistency in latency.
|
||||
|
||||
// The timestamp is transferred in ms as a 32 bit uint, which gives a maximum time of about 49 days.
|
||||
// The maximum allowed age of a VRChat instance is 7 days, so this should not cause issues.
|
||||
|
||||
// A byte array is used as a DataList or DataDictionary can only be transmitted as JSON which is much less efficient.
|
||||
// As Udon does not support instantiating objects, I have not created classes to represent the data being sent.
|
||||
// Correct parsing is dependend upon everything being read out identially to how it was created.
|
||||
|
||||
// An event has the following structure:
|
||||
// [0-1]: (ushort) Size of event.
|
||||
// [2-5]: (uint) Time in seconds at which event occured.
|
||||
// [6]: (byte) Type of event. 0 = Full Sync, which is used to sync up from an undefinted state.
|
||||
// [7+]: Event-specific data
|
||||
|
||||
private const int BufferMaxSizeBytes = 10000;
|
||||
private const int BufferIncrementSizeBytes = 1000;
|
||||
|
||||
[SerializeField] private SyncedObject[] syncedObjects;
|
||||
|
||||
[SerializeField] private Animator DebugImageToIndicateOwner;
|
||||
|
||||
private bool isOwner;
|
||||
private bool isSynced;
|
||||
|
||||
private long startTimeTicks = DateTime.UtcNow.Ticks; // Initialize to prevent errors
|
||||
private long nextEventTimeTicks;
|
||||
|
||||
private int retriesWithoutSuccess;
|
||||
|
||||
// Main buffer of events
|
||||
private byte[] buffer;
|
||||
private int index;
|
||||
|
||||
private const ushort HeaderEventSizeIndex = 0;
|
||||
private const ushort HeaderTimestampIndex = 2;
|
||||
private const ushort HeaderEventTypeIndex = 6;
|
||||
private const ushort HeaderLength = 7;
|
||||
|
||||
private const int Delay = 250;
|
||||
|
||||
[UdonSynced] private byte[] networkedData = new byte[0];
|
||||
|
||||
public long CurrentTimeTicks { get; private set; }
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
Debug.LogError($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Fatal: NetworkManager only supports little endian! Network sync will not be possible.");
|
||||
var zero = 0;
|
||||
Debug.Log(1 / zero); // Intentionally crash
|
||||
return;
|
||||
}
|
||||
|
||||
buffer = new byte[BufferIncrementSizeBytes];
|
||||
index = 0;
|
||||
startTimeTicks = DateTime.UtcNow.Ticks;
|
||||
isSynced = false;
|
||||
retriesWithoutSuccess = 0;
|
||||
SetOwner(Networking.IsOwner(gameObject));
|
||||
|
||||
Debug.Log($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Initialized, startTimeTicks: {startTimeTicks}");
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (!isOwner)
|
||||
{
|
||||
ProgressReplayTime();
|
||||
}
|
||||
|
||||
UpdateTime(DateTime.UtcNow.Ticks);
|
||||
}
|
||||
|
||||
public void SendEvent(NetworkEventType eventType)
|
||||
{
|
||||
if (!isOwner)
|
||||
{
|
||||
Debug.LogError($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Attempted {nameof(SendEvent)} while not the owner!");
|
||||
return;
|
||||
}
|
||||
|
||||
var eventTime = GetTimestamp(CurrentTimeTicks);
|
||||
|
||||
InitializeEvent(eventType, eventTime, BufferMaxSizeBytes, out byte[][] data, out var index);
|
||||
|
||||
foreach (var obj in syncedObjects)
|
||||
{
|
||||
obj.AppendSyncedData(data, ref index, eventType);
|
||||
}
|
||||
|
||||
// Get event size, skipping over the event size which is not yet included
|
||||
ushort eventSize = 0;
|
||||
for (int i = 0; i < index; i++)
|
||||
{
|
||||
eventSize += (ushort)data[i].Length;
|
||||
}
|
||||
|
||||
if (!EnsureSpaceToStoreEvent(eventSize))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
data[0] = BitConverter.GetBytes(eventSize);
|
||||
|
||||
var oldIndex = this.index;
|
||||
|
||||
FlattenAndCopy(data, index, buffer, ref this.index);
|
||||
|
||||
Debug.Log($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Prepared event with {eventSize} bytes and timestamp {eventTime} for serialization, index went from {oldIndex} to {this.index}");
|
||||
|
||||
RequestSerialization();
|
||||
|
||||
retriesWithoutSuccess = 0; // We had success!
|
||||
}
|
||||
|
||||
public void RequestEvent(NetworkEventType eventType)
|
||||
{
|
||||
if (isOwner)
|
||||
{
|
||||
Debug.LogError($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Attempted {nameof(RequestEvent)} while we are the owner!");
|
||||
return;
|
||||
}
|
||||
|
||||
SendCustomNetworkEvent(VRC.Udon.Common.Interfaces.NetworkEventTarget.Owner, "RequestEventReceived", eventType);
|
||||
}
|
||||
|
||||
[NetworkCallable]
|
||||
public void RequestEventReceived(NetworkEventType eventType)
|
||||
{
|
||||
if (!isOwner)
|
||||
{
|
||||
Debug.LogError($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Attempted {nameof(RequestEventReceived)} while we are not the owner!");
|
||||
return;
|
||||
}
|
||||
|
||||
SendEvent(eventType);
|
||||
}
|
||||
|
||||
private void ProcessIncomingData()
|
||||
{
|
||||
if (networkedData.Length == 0)
|
||||
{
|
||||
return; // Nothing to process
|
||||
}
|
||||
|
||||
var length = networkedData.Length;
|
||||
int index = 0;
|
||||
while (index < length)
|
||||
{
|
||||
if (length - index < HeaderLength)
|
||||
{
|
||||
Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) {nameof(ProcessIncomingData)}: Remaining data in networkedData is not long enough to form a complete event!");
|
||||
HandleError();
|
||||
return;
|
||||
}
|
||||
|
||||
var eventSize = networkedData[index + HeaderEventSizeIndex];
|
||||
var eventType = (NetworkEventType)networkedData[index + HeaderEventTypeIndex];
|
||||
|
||||
if (eventType == NetworkEventType.FullSync)
|
||||
{
|
||||
ProcessIncomingFullSync(index, eventSize); // Immediately process full sync
|
||||
index += eventSize;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isSynced)
|
||||
{
|
||||
Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Received event of type {eventType} while we are not yet synced to the remote time, ignoring event.");
|
||||
index += eventSize;
|
||||
continue;
|
||||
}
|
||||
|
||||
AppendEventToBuffer(index, eventSize);
|
||||
index += eventSize;
|
||||
}
|
||||
|
||||
Debug.Log($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Received {networkedData.Length} bytes!\nBytes received:\n{BytesToString(networkedData)}");
|
||||
}
|
||||
|
||||
private void ProcessIncomingFullSync(int index, int size)
|
||||
{
|
||||
// Intentionally not doing a buffer size check here, since this is not appending to the buffer
|
||||
// (and there is no good way to continue if event is too large)
|
||||
|
||||
// Clear buffer and copy the full sync into it
|
||||
buffer = new byte[size];
|
||||
Array.Copy(networkedData, index, buffer, 0, size);
|
||||
this.index = size;
|
||||
|
||||
// Sync up to the time in the full sync
|
||||
var timestamp = BitConverter.ToUInt32(networkedData, index + HeaderTimestampIndex);
|
||||
SyncToTimestamp(timestamp);
|
||||
|
||||
// Immediately apply the full sync
|
||||
nextEventTimeTicks = GetTimeTicks(timestamp);
|
||||
isSynced = true;
|
||||
}
|
||||
|
||||
private void AppendEventToBuffer(int index, int size)
|
||||
{
|
||||
if (!EnsureSpaceToStoreEvent(size))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Array.Copy(networkedData, index, buffer, this.index, size);
|
||||
this.index += size;
|
||||
|
||||
UpdateNextEventTime();
|
||||
}
|
||||
|
||||
private void ProgressReplayTime()
|
||||
{
|
||||
while (index != 0 && nextEventTimeTicks <= CurrentTimeTicks)
|
||||
{
|
||||
ProcessIncomingEvent();
|
||||
UpdateNextEventTime();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateNextEventTime()
|
||||
{
|
||||
if (index == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var nextEventTimeTicks = GetTimeTicks(BitConverter.ToUInt32(buffer, HeaderTimestampIndex));
|
||||
if (nextEventTimeTicks >= this.nextEventTimeTicks)
|
||||
{
|
||||
this.nextEventTimeTicks = nextEventTimeTicks;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) New event is earlier than previous event!");
|
||||
HandleError();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessIncomingEvent()
|
||||
{
|
||||
var eventTimeTicks = GetTimeTicks(BitConverter.ToUInt32(buffer, HeaderTimestampIndex));
|
||||
var eventType = (NetworkEventType)buffer[HeaderEventTypeIndex];
|
||||
var index = (int)HeaderLength; // Skip header
|
||||
|
||||
UpdateTime(eventTimeTicks);
|
||||
|
||||
foreach (var obj in syncedObjects)
|
||||
{
|
||||
obj.FixedUpdate();
|
||||
}
|
||||
|
||||
foreach (var obj in syncedObjects)
|
||||
{
|
||||
var success = obj.SetSyncedData(buffer, ref index, eventType);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Malformed data reported by {obj.name} during event type {eventType}!");
|
||||
HandleError();
|
||||
return;
|
||||
}
|
||||
|
||||
if (index > this.index)
|
||||
{
|
||||
Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Buffer overflow during {nameof(SyncedObject.SetSyncedData)} for {obj.name} in event type {eventType}!");
|
||||
HandleError();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var eventSize = BitConverter.ToUInt16(buffer, HeaderEventSizeIndex);
|
||||
if (index != eventSize)
|
||||
{
|
||||
Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Amount of data read does not match event size! Expected {eventSize}, read {index}.");
|
||||
HandleError();
|
||||
return;
|
||||
}
|
||||
|
||||
RemoveProcessedDataFromBuffer(index);
|
||||
|
||||
Debug.Log($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Processed incoming event! Total {index} bytes.");
|
||||
|
||||
retriesWithoutSuccess = 0; // We had success!
|
||||
}
|
||||
|
||||
private void SyncToTimestamp(uint newTime)
|
||||
{
|
||||
var timeToSyncTo = newTime - Delay;
|
||||
startTimeTicks = DateTime.UtcNow.Ticks - timeToSyncTo * TimeSpan.TicksPerMillisecond;
|
||||
|
||||
Debug.Log($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Synced to time {newTime}, startTimeTicks is now {startTimeTicks}");
|
||||
}
|
||||
|
||||
private bool EnsureSpaceToStoreEvent(int eventSize)
|
||||
{
|
||||
if (index + eventSize <= buffer.Length)
|
||||
{
|
||||
return true; // Enough space!
|
||||
}
|
||||
|
||||
var newBufferSize = ((index + eventSize) / BufferIncrementSizeBytes + 1) * BufferIncrementSizeBytes;
|
||||
|
||||
var success = IncreaseBufferSize(newBufferSize);
|
||||
if (success)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (index == 0)
|
||||
{
|
||||
Debug.LogError($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Buffer is not large enough to store event!");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Too much data in buffer to store event!");
|
||||
}
|
||||
|
||||
HandleError(); // We can store event now that we cleared the buffer.
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool IncreaseBufferSize(int newSize)
|
||||
{
|
||||
if (newSize < buffer.Length)
|
||||
{
|
||||
Debug.Log($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Cannot decrease the size of the buffer!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (newSize > BufferMaxSizeBytes)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var oldBuffer = buffer;
|
||||
buffer = new byte[newSize];
|
||||
oldBuffer.CopyTo(buffer, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void InitializeEvent(NetworkEventType eventType, uint eventTime, int maxSize, out byte[][] data, out int index)
|
||||
{
|
||||
data = new byte[maxSize][];
|
||||
index = 3;
|
||||
|
||||
data[0] = new byte[2]; // Placeholder for event size
|
||||
data[1] = BitConverter.GetBytes(eventTime);
|
||||
data[2] = new byte[] { GameManager.Int32ToByte((int)eventType) };
|
||||
}
|
||||
|
||||
private void FlattenAndCopy(byte[][] data, int length, byte[] target, ref int index)
|
||||
{
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
var values = data[i];
|
||||
Array.Copy(values, 0, target, index, values.Length);
|
||||
index += values.Length;
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveProcessedDataFromBuffer(int amountProcessed)
|
||||
{
|
||||
var oldBuffer = buffer;
|
||||
index -= amountProcessed;
|
||||
buffer = new byte[BufferMaxSizeBytes];
|
||||
Array.Copy(oldBuffer, amountProcessed, buffer, 0, index);
|
||||
}
|
||||
|
||||
private void ClearBuffer()
|
||||
{
|
||||
buffer = new byte[BufferMaxSizeBytes];
|
||||
index = 0;
|
||||
}
|
||||
|
||||
private void HandleError()
|
||||
{
|
||||
retriesWithoutSuccess++;
|
||||
|
||||
if (retriesWithoutSuccess > 3)
|
||||
{
|
||||
Debug.LogError($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Fatal: Retried 3 times without success.");
|
||||
var zero = 0;
|
||||
Debug.Log(1 / zero); // Intentionally crash
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Encountered data error, attempting to recover via full sync.");
|
||||
|
||||
ClearBuffer();
|
||||
|
||||
if (!isOwner)
|
||||
{
|
||||
RequestEvent(NetworkEventType.FullSync);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendEvent(NetworkEventType.FullSync);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetOwner(bool isOwner)
|
||||
{
|
||||
this.isOwner = isOwner;
|
||||
|
||||
if (DebugImageToIndicateOwner != null)
|
||||
{
|
||||
DebugImageToIndicateOwner.SetFloat("Color", isOwner ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnOwnershipTransferred(VRCPlayerApi newOwner)
|
||||
{
|
||||
SetOwner(newOwner == Networking.LocalPlayer);
|
||||
|
||||
if(isOwner)
|
||||
{
|
||||
HandleError();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnPreSerialization()
|
||||
{
|
||||
if (isOwner)
|
||||
{
|
||||
networkedData = new byte[index];
|
||||
Array.Copy(buffer, networkedData, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
networkedData = new byte[0]; // Prevent exception loop in VRChat SDK
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnPostSerialization(SerializationResult result)
|
||||
{
|
||||
if (!result.success)
|
||||
{
|
||||
Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Serialization failed! Tried to send {result.byteCount} bytes.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isOwner || networkedData.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Log($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Serialized with {networkedData.Length} bytes!\nBytes sent:\n{BytesToString(networkedData)}");
|
||||
|
||||
// Remove all transferred data from the buffer, leaving data that came in after serialization
|
||||
RemoveProcessedDataFromBuffer(networkedData.Length);
|
||||
networkedData = null;
|
||||
}
|
||||
|
||||
public override void OnDeserialization()
|
||||
{
|
||||
if (!isOwner)
|
||||
{
|
||||
ProcessIncomingData();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateTime(long timeTicks)
|
||||
{
|
||||
CurrentTimeTicks = timeTicks;
|
||||
|
||||
foreach (var obj in syncedObjects)
|
||||
{
|
||||
obj.Dt = (timeTicks - obj.LastUpdateTicks) / (float)TimeSpan.TicksPerSecond;
|
||||
obj.LastUpdateTicks = timeTicks;
|
||||
}
|
||||
}
|
||||
|
||||
public uint GetTimestamp(long timeTicks)
|
||||
{
|
||||
return (uint)((timeTicks - startTimeTicks) / TimeSpan.TicksPerMillisecond);
|
||||
}
|
||||
|
||||
public long GetTimeTicks(uint timeStamp)
|
||||
{
|
||||
return timeStamp * TimeSpan.TicksPerMillisecond + startTimeTicks;
|
||||
}
|
||||
|
||||
public bool IsOwner => isOwner;
|
||||
|
||||
public string BytesToString(byte[] bytes)
|
||||
{
|
||||
var sb = new StringBuilder("new byte[] { ");
|
||||
foreach (var b in bytes)
|
||||
{
|
||||
sb.Append(b + ", ");
|
||||
}
|
||||
sb.Append("}");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a584f98f4d7e35146ae110c947f41176
|
||||
guid: ac984c07ae3e9674a850c3916be56ca3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
File diff suppressed because it is too large
Load Diff
@@ -28,11 +28,10 @@
|
||||
private Vector2[] predefinedPath;
|
||||
private int predefinedPathIndex;
|
||||
|
||||
[UdonSynced] private Vector2 syncedPosition;
|
||||
[UdonSynced] private Vector2 targetDirection;
|
||||
[UdonSynced] private Vector2 direction;
|
||||
[UdonSynced] private float freezeSeconds;
|
||||
[UdonSynced] private bool frozen;
|
||||
private Vector2 syncedPosition;
|
||||
private Vector2 targetDirection;
|
||||
private float freezeSeconds;
|
||||
private bool frozen;
|
||||
|
||||
#region Animator constants
|
||||
private const string AnimatorKeyDead = "Dead";
|
||||
@@ -76,7 +75,7 @@
|
||||
animator.SetTrigger("Reset");
|
||||
}
|
||||
|
||||
void FixedUpdate()
|
||||
public override void FixedUpdate()
|
||||
{
|
||||
// gameStateManager.statusDisplay.SetDebugText(1, this.targetDirection.ToString());
|
||||
|
||||
@@ -207,7 +206,7 @@
|
||||
return nextPosition;
|
||||
}
|
||||
|
||||
private void UpdateAnimator()
|
||||
protected override void UpdateAnimator()
|
||||
{
|
||||
// Debug.Log($"{gameObject} UpdateAnimator with direction {direction}, dead {dead}, frozen {frozen}");
|
||||
if (!gameObject.activeInHierarchy)
|
||||
@@ -316,45 +315,12 @@
|
||||
renderer.enabled = visible;
|
||||
}
|
||||
|
||||
public override Vector2 GetPosition()
|
||||
{
|
||||
return (Vector2)transform.localPosition;
|
||||
}
|
||||
|
||||
public override void SetPosition(Vector2 position)
|
||||
{
|
||||
GridMoverTools.SetPosition(position, transform);
|
||||
}
|
||||
|
||||
public override Vector2 GetDirection()
|
||||
{
|
||||
return direction;
|
||||
}
|
||||
|
||||
public void SetDirection(Vector2 direction)
|
||||
{
|
||||
this.direction = direction;
|
||||
RequestSerialization();
|
||||
UpdateAnimator();
|
||||
}
|
||||
|
||||
public void SetTargetDirection(Vector2 targetDirection)
|
||||
{
|
||||
this.targetDirection = targetDirection;
|
||||
UpdateAnimator();
|
||||
}
|
||||
|
||||
public override void OnPreSerialization()
|
||||
{
|
||||
syncedPosition = GetPosition();
|
||||
}
|
||||
|
||||
public override void OnDeserialization()
|
||||
{
|
||||
SetPosition(syncedPosition);
|
||||
UpdateAnimator();
|
||||
}
|
||||
|
||||
void OnTriggerEnter(Collider other)
|
||||
{
|
||||
Pellet pellet = other.gameObject.GetComponent<Pellet>();
|
||||
@@ -372,16 +338,14 @@
|
||||
|
||||
if (pellet.isPowerPellet)
|
||||
{
|
||||
if (Networking.IsOwner(gameObject)) gameController.GotPowerPellet();
|
||||
gameController.GotPowerPellet();
|
||||
freezeSeconds = 0.05f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Networking.IsOwner(gameObject)) gameController.GotPellet();
|
||||
gameController.GotPellet();
|
||||
freezeSeconds = 0.0166666666666667f;
|
||||
}
|
||||
|
||||
if (Networking.IsOwner(gameObject)) RequestSerialization();
|
||||
return;
|
||||
}
|
||||
else if (Networking.IsOwner(gameObject) && other.gameObject.GetComponent<BonusFruit>())
|
||||
|
||||
@@ -34,6 +34,7 @@ namespace Marro.PacManUdon
|
||||
{
|
||||
AttractScreenIntroduction,
|
||||
AttractScreenDemo,
|
||||
AttractScreenWaitToRestart,
|
||||
WaitForStart,
|
||||
WaitForStartTimeout,
|
||||
StartNewGame,
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
}
|
||||
|
||||
powerPellets = GetComponentsInChildren<Animator>(true);
|
||||
Debug.Log($"{gameObject} Initialized, powerPellets: {powerPellets}");
|
||||
// Debug.Log($"{gameObject} Initialized, powerPellets: {powerPellets}");
|
||||
powerPelletBlinkToggleInterval = PacManConstants.GetPowerPelletBlinkToggleInterval();
|
||||
SetPowerPelletsBlink(false);
|
||||
}
|
||||
|
||||
@@ -103,13 +103,13 @@ MonoBehaviour:
|
||||
Data:
|
||||
- Name: $k
|
||||
Entry: 1
|
||||
Data: gameController
|
||||
Data: gameManager
|
||||
- Name: $v
|
||||
Entry: 7
|
||||
Data: 5|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
|
||||
- Name: <Name>k__BackingField
|
||||
Entry: 1
|
||||
Data: gameController
|
||||
Data: gameManager
|
||||
- Name: <UserType>k__BackingField
|
||||
Entry: 7
|
||||
Data: 6|System.RuntimeType, mscorlib
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
public class PlayerInput : UdonSharpBehaviour
|
||||
{
|
||||
public bool active;
|
||||
private GameManager gameController;
|
||||
private GameManager gameManager;
|
||||
Vector2 inputHorizontal;
|
||||
Vector2 inputVertical;
|
||||
float horizontalValue;
|
||||
@@ -18,9 +18,9 @@
|
||||
bool horizontalPriority;
|
||||
VRCPlayerApi player;
|
||||
|
||||
public void Initialize(GameManager gameController)
|
||||
public void Initialize(GameManager gameManager)
|
||||
{
|
||||
this.gameController = gameController;
|
||||
this.gameManager = gameManager;
|
||||
inputHorizontal = Vector2.zero;
|
||||
inputVertical = Vector2.zero;
|
||||
horizontalPriority = false;
|
||||
@@ -35,7 +35,7 @@
|
||||
player.SetRunSpeed(0);
|
||||
player.SetStrafeSpeed(0);
|
||||
|
||||
gameController.JoystickGrabbed();
|
||||
gameManager.JoystickGrabbed();
|
||||
}
|
||||
|
||||
public void Deactivate()
|
||||
@@ -46,7 +46,7 @@
|
||||
player.SetStrafeSpeed(2);
|
||||
active = false;
|
||||
|
||||
gameController.JoystickReleased();
|
||||
gameManager.JoystickReleased();
|
||||
}
|
||||
|
||||
public override void InputJump(bool pressed, UdonInputEventArgs args)
|
||||
@@ -128,6 +128,7 @@
|
||||
// horizontalPriority = true;
|
||||
SetPriority(true);
|
||||
}
|
||||
|
||||
// Debug.Log("Vertical Input Event: " + value + " | Direction: " + direction + " | lastDirection : " + lastDirection);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,20 +9,17 @@ namespace Marro.PacManUdon
|
||||
switch (sequenceProgress)
|
||||
{
|
||||
case 0:
|
||||
PrepareForCutscene();
|
||||
|
||||
SetGameState(PacManGameState.AttractModeDemo);
|
||||
HideEverything();
|
||||
SetFrozen(true);
|
||||
break;
|
||||
case 1:
|
||||
InitializeLevel();
|
||||
SetMazeActive(true);
|
||||
SetMazeVisible(true);
|
||||
SetLevel(1);
|
||||
break;
|
||||
case 2:
|
||||
// Reset ghosts
|
||||
RestartLevel();
|
||||
|
||||
// Setup ghosts
|
||||
ghostManager.Ghosts[0].SetPredefinedPath(new Vector2[]{ // Blinky
|
||||
Vector2.down,
|
||||
Vector2.left,
|
||||
@@ -338,13 +335,14 @@ namespace Marro.PacManUdon
|
||||
// Unfreeze
|
||||
SetFrozen(false);
|
||||
break;
|
||||
// case 6:
|
||||
// if (!hasTimeSequenceQueued)
|
||||
// {
|
||||
// StartTimeSequence(PacManTimeSequence.AttractScreenWaitForStart);
|
||||
// }
|
||||
// break;
|
||||
case 6:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void TimeSequenceFinishedAttractScreenDemo()
|
||||
{
|
||||
StartTimeSequence(PacManTimeSequence.AttractScreenWaitToRestart);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,13 +9,12 @@ namespace Marro.PacManUdon
|
||||
switch (sequenceProgress)
|
||||
{
|
||||
case 0:
|
||||
PrepareForCutscene();
|
||||
|
||||
SetGameState(PacManGameState.AttractMode);
|
||||
|
||||
// Initialize
|
||||
soundManager.SuppressSound(true);
|
||||
RestartLevel();
|
||||
HideEverything();
|
||||
SetFrozen(true);
|
||||
attractScreen.gameObject.SetActive(true);
|
||||
attractScreen.Initialize();
|
||||
for (int i = 0; i <= 15; i++)
|
||||
@@ -165,15 +164,18 @@ namespace Marro.PacManUdon
|
||||
case 26:
|
||||
ghostManager.Ghosts[3].ReturnHome();
|
||||
ghostManager.Ghosts[3].SetActive(false);
|
||||
// Hide elements, start demo
|
||||
attractScreen.gameObject.SetActive(false);
|
||||
|
||||
if (!hasTimeSequenceQueued)
|
||||
{
|
||||
StartTimeSequence(PacManTimeSequence.AttractScreenDemo);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void TimeSequenceFinalizeAttractScreenIntroduction()
|
||||
{
|
||||
attractScreen.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
private void TimeSequenceFinishedAttractScreenIntroduction()
|
||||
{
|
||||
StartTimeSequence(PacManTimeSequence.AttractScreenDemo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
10
Assets/Scripts/Sequences/AttractScreenWaitToRestart.cs
Normal file
10
Assets/Scripts/Sequences/AttractScreenWaitToRestart.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace Marro.PacManUdon
|
||||
{
|
||||
public partial class GameManager
|
||||
{
|
||||
private void TimeSequenceFinishedAttractScreenWaitToRestart()
|
||||
{
|
||||
StartAttractMode();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ac77c2211d465d445934f6bf7398f743
|
||||
guid: 2b178dfcf6f9185448d2a2cdd4869abd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -36,29 +36,33 @@ namespace Marro.PacManUdon
|
||||
statusDisplay.SetLevelDisplayVisible(true);
|
||||
break;
|
||||
case 6:
|
||||
// Call handler for what should happen next
|
||||
PacManTimeSequence nextSequence;
|
||||
switch (level)
|
||||
{
|
||||
case 2:
|
||||
nextSequence = PacManTimeSequence.Intermission1;
|
||||
break;
|
||||
case 5:
|
||||
nextSequence = PacManTimeSequence.Intermission2;
|
||||
break;
|
||||
case 9:
|
||||
case 13:
|
||||
case 17:
|
||||
nextSequence = PacManTimeSequence.Intermission3;
|
||||
break;
|
||||
default:
|
||||
nextSequence = PacManTimeSequence.StartNewLevel;
|
||||
break;
|
||||
}
|
||||
|
||||
InsertTimeSequence(nextSequence);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void TimeSequenceFinishedBoardClear()
|
||||
{
|
||||
// Call handler for what should happen next
|
||||
PacManTimeSequence nextSequence;
|
||||
switch (level)
|
||||
{
|
||||
case 2:
|
||||
nextSequence = PacManTimeSequence.Intermission1;
|
||||
break;
|
||||
case 5:
|
||||
nextSequence = PacManTimeSequence.Intermission2;
|
||||
break;
|
||||
case 9:
|
||||
case 13:
|
||||
case 17:
|
||||
nextSequence = PacManTimeSequence.Intermission3;
|
||||
break;
|
||||
default:
|
||||
nextSequence = PacManTimeSequence.StartNewLevel;
|
||||
break;
|
||||
}
|
||||
|
||||
StartTimeSequence(nextSequence);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,11 +12,15 @@ namespace Marro.PacManUdon
|
||||
pelletManager.FreezePowerPelletsBlink(true);
|
||||
break;
|
||||
case 1:
|
||||
// Stop text blinking, transition to attract screen
|
||||
statusDisplay.SetLabel1UPTextBlinking(false);
|
||||
StartAttractMode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void TimeSequenceFinishedGameOver()
|
||||
{
|
||||
// Stop text blinking, transition to attract screen
|
||||
statusDisplay.SetLabel1UPTextBlinking(false);
|
||||
StartAttractMode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,13 +13,17 @@ namespace Marro.PacManUdon
|
||||
soundManager.PlayGhostEatSound();
|
||||
break;
|
||||
case 1:
|
||||
// Unfreeze and reveal pacman
|
||||
SetPacManActive(true);
|
||||
SetFrozen(false);
|
||||
ghostManager.GhostCaughtContinue();
|
||||
soundManager.SetGhostRetreat(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void TimeSequenceFinalizeGhostCaught()
|
||||
{
|
||||
// Unfreeze and reveal pacman
|
||||
SetPacManActive(true);
|
||||
SetFrozen(false);
|
||||
ghostManager.GhostCaughtContinue();
|
||||
soundManager.SetGhostRetreat(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,9 @@ namespace Marro.PacManUdon
|
||||
switch (sequenceProgress)
|
||||
{
|
||||
case 0:
|
||||
PrepareForCutscene();
|
||||
|
||||
// Show just level display
|
||||
RestartLevel();
|
||||
statusDisplay.SetLevelDisplayVisible(true);
|
||||
break;
|
||||
case 1:
|
||||
@@ -20,7 +21,6 @@ namespace Marro.PacManUdon
|
||||
soundManager.SuppressSound(false);
|
||||
soundManager.StartIntermissionSound();
|
||||
|
||||
pacMan.Reset();
|
||||
pacMan.SetLevel(4);
|
||||
pacMan.SetPowerPellet(false); // Update speed
|
||||
pacMan.SetKinematic(true);
|
||||
@@ -28,7 +28,6 @@ namespace Marro.PacManUdon
|
||||
pacMan.SetPosition(intermissionScreenElements[0].transform.localPosition);
|
||||
pacMan.SetDirection(Vector2.left);
|
||||
|
||||
ghostManager.Reset();
|
||||
ghostManager.SetLevel(5);
|
||||
ghostManager.SetKinematic(true);
|
||||
ghostManager.gameObject.SetActive(true);
|
||||
@@ -61,9 +60,13 @@ namespace Marro.PacManUdon
|
||||
// End cutscene
|
||||
soundManager.StopAllSound();
|
||||
SetFrozen(true);
|
||||
StartTimeSequence(PacManTimeSequence.StartNewLevel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void TimeSequenceFinishedIntermission1()
|
||||
{
|
||||
StartTimeSequence(PacManTimeSequence.StartNewLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,9 @@ namespace Marro.PacManUdon
|
||||
switch (sequenceProgress)
|
||||
{
|
||||
case 0:
|
||||
PrepareForCutscene();
|
||||
|
||||
// Show just level display
|
||||
RestartLevel();
|
||||
statusDisplay.SetLevelDisplayVisible(true);
|
||||
break;
|
||||
case 1:
|
||||
@@ -27,7 +28,6 @@ namespace Marro.PacManUdon
|
||||
break;
|
||||
case 3:
|
||||
// Start animation, pacman running and blinky prepared to chase
|
||||
pacMan.Reset();
|
||||
pacMan.SetLevel(4);
|
||||
pacMan.SetPowerPellet(false); // Update speed
|
||||
pacMan.SetKinematic(true);
|
||||
@@ -35,7 +35,6 @@ namespace Marro.PacManUdon
|
||||
pacMan.SetPosition(intermissionScreenElements[0].transform.localPosition);
|
||||
pacMan.SetDirection(Vector2.left);
|
||||
|
||||
ghostManager.Reset();
|
||||
ghostManager.SetLevel(5);
|
||||
ghostManager.SetKinematic(true);
|
||||
ghostManager.gameObject.SetActive(true);
|
||||
@@ -78,12 +77,20 @@ namespace Marro.PacManUdon
|
||||
break;
|
||||
case 11:
|
||||
// End cutscene
|
||||
SetIntermissionScreenVisible(false);
|
||||
soundManager.StopAllSound();
|
||||
SetFrozen(true);
|
||||
StartTimeSequence(PacManTimeSequence.StartNewLevel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void TimeSequenceFinalizeIntermission2()
|
||||
{
|
||||
SetIntermissionScreenVisible(false);
|
||||
soundManager.StopAllSound();
|
||||
}
|
||||
|
||||
private void TimeSequenceFinishedIntermission2()
|
||||
{
|
||||
StartTimeSequence(PacManTimeSequence.StartNewLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,9 @@ namespace Marro.PacManUdon
|
||||
switch (sequenceProgress)
|
||||
{
|
||||
case 0:
|
||||
PrepareForCutscene();
|
||||
|
||||
// Show just level display
|
||||
RestartLevel();
|
||||
statusDisplay.SetLevelDisplayVisible(true);
|
||||
break;
|
||||
case 1:
|
||||
@@ -20,7 +21,6 @@ namespace Marro.PacManUdon
|
||||
soundManager.SuppressSound(false);
|
||||
soundManager.StartIntermissionSound();
|
||||
|
||||
pacMan.Reset();
|
||||
pacMan.SetLevel(4);
|
||||
pacMan.SetPowerPellet(false); // Update speed
|
||||
pacMan.SetKinematic(true);
|
||||
@@ -28,7 +28,6 @@ namespace Marro.PacManUdon
|
||||
pacMan.SetPosition(intermissionScreenElements[0].transform.localPosition);
|
||||
pacMan.SetDirection(Vector2.left);
|
||||
|
||||
ghostManager.Reset();
|
||||
ghostManager.SetLevel(5);
|
||||
ghostManager.SetKinematic(true);
|
||||
ghostManager.gameObject.SetActive(true);
|
||||
@@ -56,11 +55,19 @@ namespace Marro.PacManUdon
|
||||
break;
|
||||
case 5:
|
||||
// End cutscene
|
||||
soundManager.StopAllSound();
|
||||
SetFrozen(true);
|
||||
StartTimeSequence(PacManTimeSequence.StartNewLevel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void TimeSequenceFinalizeIntermission3()
|
||||
{
|
||||
soundManager.StopAllSound();
|
||||
}
|
||||
|
||||
private void TimeSequenceFinishedIntermission3()
|
||||
{
|
||||
StartTimeSequence(PacManTimeSequence.StartNewLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ namespace Marro.PacManUdon
|
||||
{
|
||||
public partial class GameManager
|
||||
{
|
||||
private void TimeSequenceStepPacManCaught(int sequenceProgress)
|
||||
private void TimeSequenceStepPacManCaught(int sequenceProgress)
|
||||
{
|
||||
switch (sequenceProgress)
|
||||
{
|
||||
@@ -21,30 +21,29 @@ namespace Marro.PacManUdon
|
||||
soundManager.PlayDeathSound();
|
||||
break;
|
||||
case 3:
|
||||
// Hide pacman, start next state
|
||||
// Hide pacman
|
||||
SetPacManActive(false);
|
||||
if (gameState == PacManGameState.AttractModeDemo)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (extraLives > 0)
|
||||
{
|
||||
InsertTimeSequence(PacManTimeSequence.RestartLevel);
|
||||
break;
|
||||
}
|
||||
|
||||
InsertTimeSequence(PacManTimeSequence.GameOver);
|
||||
break;
|
||||
case 4:
|
||||
if (gameState == PacManGameState.AttractModeDemo)
|
||||
{
|
||||
#if RECORDING_DEMO
|
||||
// recorder.gameObject.SetActive(false);
|
||||
#endif
|
||||
InsertTimeSequence(PacManTimeSequence.AttractScreenIntroduction);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void TimeSequenceFinishedPacManCaught()
|
||||
{
|
||||
PacManTimeSequence nextSequence;
|
||||
if (gameState == PacManGameState.AttractModeDemo)
|
||||
{
|
||||
nextSequence = PacManTimeSequence.AttractScreenWaitToRestart;
|
||||
}
|
||||
else if (extraLives > 0)
|
||||
{
|
||||
nextSequence = PacManTimeSequence.RestartLevel;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextSequence = PacManTimeSequence.GameOver;
|
||||
}
|
||||
|
||||
StartTimeSequence(nextSequence);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,13 +32,17 @@ namespace Marro.PacManUdon
|
||||
statusDisplay.SetReadyTextVisible(false);
|
||||
break;
|
||||
case 5:
|
||||
// Unfreeze
|
||||
SetFrozen(false);
|
||||
soundManager.SuppressSound(false);
|
||||
soundManager.StartGhostSound();
|
||||
soundManager.UpdatePelletCount(pelletCountRemaining);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void TimeSequenceFinalizeRestartLevel()
|
||||
{
|
||||
// Unfreeze
|
||||
SetFrozen(false);
|
||||
soundManager.SuppressSound(false);
|
||||
soundManager.StartGhostSound();
|
||||
soundManager.UpdatePelletCount(pelletCountRemaining);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,35 +12,21 @@ namespace Marro.PacManUdon
|
||||
// Prepare new game, hide everything except score bar
|
||||
gameState = PacManGameState.InGame;
|
||||
|
||||
HideEverything();
|
||||
|
||||
SetMazeActive(true);
|
||||
|
||||
InitializeNewGame();
|
||||
InitializeLevel();
|
||||
RestartLevel();
|
||||
SetFrozen(true);
|
||||
PrepareForCutscene();
|
||||
|
||||
soundManager.SuppressSound(false);
|
||||
soundManager.PlayGameStartSound();
|
||||
break;
|
||||
case 1:
|
||||
// Show maze, lives indicator, level indicator, player 1 and ready text
|
||||
|
||||
// SOMEWHERE IN HERE UNITY (EDITOR) APPEARS TO HAVE A SMALL RANDOM CHANCE OF CRASHING !!
|
||||
Debug.Log("Log dump in case of crash");
|
||||
Debug.Log("Setting pellets visible");
|
||||
SetPelletsActive(true);
|
||||
Debug.Log("Setting maze visible");
|
||||
SetMazeVisible(true);
|
||||
Debug.Log("Setting extra lives display visible");
|
||||
statusDisplay.SetExtraLivesDisplayVisible(true);
|
||||
Debug.Log("Setting level display visible");
|
||||
statusDisplay.SetLevelDisplayVisible(true);
|
||||
Debug.Log("Setting player 1 text visible");
|
||||
statusDisplay.SetPlayer1TextVisible(true);
|
||||
Debug.Log("Setting ready text visible");
|
||||
statusDisplay.SetReadyTextVisible(true);
|
||||
Debug.Log("Starting 1UP blink");
|
||||
statusDisplay.SetLabel1UPTextBlinking(true);
|
||||
break;
|
||||
case 2:
|
||||
@@ -61,11 +47,15 @@ namespace Marro.PacManUdon
|
||||
statusDisplay.SetReadyTextVisible(false);
|
||||
break;
|
||||
case 6:
|
||||
// Start game, end sequence
|
||||
soundManager.StartGhostSound();
|
||||
SetFrozen(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void TimeSequenceFinalizeStartNewGame()
|
||||
{
|
||||
// Start game, end sequence
|
||||
soundManager.StartGhostSound();
|
||||
SetFrozen(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,12 +7,12 @@ namespace Marro.PacManUdon
|
||||
switch (sequenceProgress)
|
||||
{
|
||||
case 0:
|
||||
PrepareForCutscene();
|
||||
|
||||
// Reset, show maze and score display
|
||||
InitializeLevel();
|
||||
RestartLevel();
|
||||
SetMazeVisible(true);
|
||||
statusDisplay.SetScoreDisplayVisible(true);
|
||||
soundManager.SuppressSound(false);
|
||||
break;
|
||||
case 1:
|
||||
// Increment level, show ready, show pellets, show lives indicators
|
||||
@@ -31,11 +31,16 @@ namespace Marro.PacManUdon
|
||||
statusDisplay.SetReadyTextVisible(false);
|
||||
break;
|
||||
case 4:
|
||||
// Unfreeze
|
||||
SetFrozen(false);
|
||||
soundManager.StartGhostSound();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void TimeSequenceFinalizeStartNewLevel()
|
||||
{
|
||||
// Unfreeze
|
||||
SetFrozen(false);
|
||||
soundManager.SuppressSound(false);
|
||||
soundManager.StartGhostSound();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
462
Assets/Scripts/Sequences/TimeSequenceShared.cs
Normal file
462
Assets/Scripts/Sequences/TimeSequenceShared.cs
Normal file
@@ -0,0 +1,462 @@
|
||||
using UdonSharp;
|
||||
using UnityEngine;
|
||||
using VRC.SDKBase;
|
||||
using VRC.SDK3.Data;
|
||||
|
||||
namespace Marro.PacManUdon
|
||||
{
|
||||
public partial class GameManager
|
||||
{
|
||||
// A note about the quality of the code here:
|
||||
// I intended to write this using proper classes, right until I realized Udon does not support instantiating classes.
|
||||
// While I'm not a big fan of the partial class solution that I ended up doing (static classes would still be neater, or perhaps separate UdonSharpBehaviour instances),
|
||||
// I'm not redoing this unless I get instantiatable classes before I wrap up this project.
|
||||
bool currentlyInTimeSequence;
|
||||
bool waitingForTimeSequenceFinalize;
|
||||
bool jumpingToTimeSequence;
|
||||
PacManTimeSequence currentTimeSequence;
|
||||
[UdonSynced] float timeSequenceSecondsPassed;
|
||||
int timeSequenceProgress;
|
||||
float[] timeSequenceKeyframeTimes;
|
||||
|
||||
private void StartTimeSequence(PacManTimeSequence timeSequence)
|
||||
{
|
||||
Debug.Log($"StartTimeSequence: {timeSequence}");
|
||||
|
||||
if (currentlyInTimeSequence)
|
||||
{
|
||||
TimeSequenceEndCurrent();
|
||||
}
|
||||
|
||||
TimeSequencePrepareForStart(timeSequence);
|
||||
|
||||
currentlyInTimeSequence = true;
|
||||
currentTimeSequence = timeSequence;
|
||||
timeSequenceProgress = 0;
|
||||
timeSequenceSecondsPassed = 0;
|
||||
timeSequenceKeyframeTimes = GetTimeSequenceKeyframeTimes(timeSequence);
|
||||
TimeSequenceProgressToTime(timeSequenceSecondsPassed);
|
||||
}
|
||||
|
||||
private void TimeSequenceEndCurrent()
|
||||
{
|
||||
jumpingToTimeSequence = true;
|
||||
TimeSequenceProgressToTime(100000f);
|
||||
TryFinalizeTimeSequence();
|
||||
jumpingToTimeSequence = false;
|
||||
}
|
||||
|
||||
private void TimeSequenceUpdate(float deltaSeconds)
|
||||
{
|
||||
if (!currentlyInTimeSequence)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TimeSequenceProgressToTime(timeSequenceSecondsPassed + deltaSeconds);
|
||||
}
|
||||
|
||||
private void TimeSequenceSkipToNextStep()
|
||||
{
|
||||
// Debug.Log($"{gameObject} TimeSequenceSkipToNextStep");
|
||||
if (timeSequenceProgress < timeSequenceKeyframeTimes.Length)
|
||||
{
|
||||
TimeSequenceProgressToTime(timeSequenceKeyframeTimes[timeSequenceProgress]);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"{gameObject} Tried skipping to next time sequence step when already on last step!");
|
||||
currentlyInTimeSequence = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void TimeSequenceProgressToTime(float seconds)
|
||||
{
|
||||
timeSequenceSecondsPassed = seconds;
|
||||
while (timeSequenceSecondsPassed >= timeSequenceKeyframeTimes[timeSequenceProgress])
|
||||
{
|
||||
TimeSequenceExecuteStep(currentTimeSequence, timeSequenceProgress);
|
||||
|
||||
timeSequenceProgress += 1;
|
||||
if (timeSequenceProgress >= timeSequenceKeyframeTimes.Length)
|
||||
{
|
||||
currentlyInTimeSequence = false;
|
||||
TimeSequencePrepareForFinish(currentTimeSequence);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void TimeSequencePrepareForFinish(PacManTimeSequence timeSequence)
|
||||
{
|
||||
if (Networking.IsOwner(gameObject))
|
||||
{
|
||||
TimeSequenceExecuteFinalize(timeSequence);
|
||||
if (!jumpingToTimeSequence)
|
||||
{
|
||||
TimeSequenceExecuteFinished(timeSequence);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
waitingForTimeSequenceFinalize = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void TryFinalizeTimeSequence()
|
||||
{
|
||||
if (!waitingForTimeSequenceFinalize)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TimeSequenceExecuteFinalize(currentTimeSequence);
|
||||
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);
|
||||
}
|
||||
|
||||
// If we're (now) in a time sequence, jump our progress to match the one on the remote
|
||||
if (this.currentlyInTimeSequence)
|
||||
{
|
||||
TimeSequenceProgressToTime(timeSequenceProgress);
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
public void JumpToTimeSequenceAttractScreenIntroduction()
|
||||
{
|
||||
StartTimeSequence(PacManTimeSequence.AttractScreenIntroduction);
|
||||
}
|
||||
|
||||
public void JumpToTimeSequenceAttractScreenDemo()
|
||||
{
|
||||
StartTimeSequence(PacManTimeSequence.AttractScreenDemo);
|
||||
}
|
||||
|
||||
public void JumpToTimeSequenceAttractScreenWaitToRestart()
|
||||
{
|
||||
StartTimeSequence(PacManTimeSequence.AttractScreenWaitToRestart);
|
||||
}
|
||||
|
||||
public void JumpToTimeSequenceBoardClear()
|
||||
{
|
||||
StartTimeSequence(PacManTimeSequence.BoardClear);
|
||||
}
|
||||
|
||||
public void JumpToTimeSequenceGameOver()
|
||||
{
|
||||
StartTimeSequence(PacManTimeSequence.GameOver);
|
||||
}
|
||||
|
||||
public void JumpToTimeSequenceGhostCaught()
|
||||
{
|
||||
StartTimeSequence(PacManTimeSequence.GhostCaught);
|
||||
}
|
||||
|
||||
public void JumpToTimeSequenceIntermission1()
|
||||
{
|
||||
StartTimeSequence(PacManTimeSequence.Intermission1);
|
||||
}
|
||||
|
||||
public void JumpToTimeSequenceIntermission2()
|
||||
{
|
||||
StartTimeSequence(PacManTimeSequence.Intermission2);
|
||||
}
|
||||
|
||||
public void JumpToTimeSequenceIntermission3()
|
||||
{
|
||||
StartTimeSequence(PacManTimeSequence.Intermission3);
|
||||
}
|
||||
|
||||
public void JumpToTimeSequencePacManCaught()
|
||||
{
|
||||
StartTimeSequence(PacManTimeSequence.PacManCaught);
|
||||
}
|
||||
|
||||
public void JumpToTimeSequenceRestartLevel()
|
||||
{
|
||||
StartTimeSequence(PacManTimeSequence.RestartLevel);
|
||||
}
|
||||
|
||||
public void JumpToTimeSequenceStartNewGame()
|
||||
{
|
||||
StartTimeSequence(PacManTimeSequence.StartNewGame);
|
||||
}
|
||||
|
||||
public void JumpToTimeSequenceStartNewLevel()
|
||||
{
|
||||
StartTimeSequence(PacManTimeSequence.StartNewLevel);
|
||||
}
|
||||
|
||||
public void JumpToTimeSequenceWaitForStart()
|
||||
{
|
||||
StartTimeSequence(PacManTimeSequence.WaitForStart);
|
||||
}
|
||||
|
||||
public void JumpToTimeSequenceWaitForStartTimeout()
|
||||
{
|
||||
StartTimeSequence(PacManTimeSequence.WaitForStartTimeout);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Jump tables
|
||||
|
||||
private void TimeSequencePrepareForStart(PacManTimeSequence timeSequence)
|
||||
{
|
||||
switch (timeSequence)
|
||||
{
|
||||
default:
|
||||
Debug.LogError($"{gameObject} No time sequence start known for sequence {currentTimeSequence}");
|
||||
break;
|
||||
case PacManTimeSequence.AttractScreenIntroduction:
|
||||
case PacManTimeSequence.AttractScreenDemo:
|
||||
case PacManTimeSequence.StartNewGame:
|
||||
case PacManTimeSequence.WaitForStart:
|
||||
case PacManTimeSequence.StartNewLevel:
|
||||
case PacManTimeSequence.Intermission1:
|
||||
case PacManTimeSequence.Intermission2:
|
||||
case PacManTimeSequence.Intermission3:
|
||||
case PacManTimeSequence.AttractScreenWaitToRestart:
|
||||
case PacManTimeSequence.WaitForStartTimeout:
|
||||
case PacManTimeSequence.GhostCaught:
|
||||
case PacManTimeSequence.GameOver:
|
||||
case PacManTimeSequence.PacManCaught:
|
||||
case PacManTimeSequence.BoardClear:
|
||||
case PacManTimeSequence.RestartLevel:
|
||||
// These don't have start logic
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void TimeSequenceExecuteStep(PacManTimeSequence timeSequence, int sequenceProgress)
|
||||
{
|
||||
// Debug.Log($"{gameObject} Triggered time sequence step for sequence {currentTimeSequence} with progress {sequenceProgress}");
|
||||
switch (timeSequence)
|
||||
{
|
||||
default:
|
||||
Debug.LogError($"{gameObject} No time sequence keyframes known for sequence {currentTimeSequence}");
|
||||
break;
|
||||
case PacManTimeSequence.AttractScreenIntroduction:
|
||||
TimeSequenceStepAttractScreenIntroduction(sequenceProgress);
|
||||
break;
|
||||
case PacManTimeSequence.AttractScreenDemo:
|
||||
TimeSequenceStepAttractScreenDemo(sequenceProgress);
|
||||
break;
|
||||
case PacManTimeSequence.WaitForStart:
|
||||
TimeSequenceStepWaitForStart(sequenceProgress);
|
||||
break;
|
||||
case PacManTimeSequence.StartNewGame:
|
||||
TimeSequenceStepStartNewGame(sequenceProgress);
|
||||
break;
|
||||
case PacManTimeSequence.BoardClear:
|
||||
TimeSequenceStepBoardClear(sequenceProgress);
|
||||
break;
|
||||
case PacManTimeSequence.StartNewLevel:
|
||||
TimeSequenceStepStartNewLevel(sequenceProgress);
|
||||
break;
|
||||
case PacManTimeSequence.GhostCaught:
|
||||
TimeSequenceStepGhostCaught(sequenceProgress);
|
||||
break;
|
||||
case PacManTimeSequence.PacManCaught:
|
||||
TimeSequenceStepPacManCaught(sequenceProgress);
|
||||
break;
|
||||
case PacManTimeSequence.RestartLevel:
|
||||
TimeSequenceStepRestartLevel(sequenceProgress);
|
||||
break;
|
||||
case PacManTimeSequence.GameOver:
|
||||
TimeSequenceStepGameOver(sequenceProgress);
|
||||
break;
|
||||
case PacManTimeSequence.Intermission1:
|
||||
TimeSequenceStepIntermission1(sequenceProgress);
|
||||
break;
|
||||
case PacManTimeSequence.Intermission2:
|
||||
TimeSequenceStepIntermission2(sequenceProgress);
|
||||
break;
|
||||
case PacManTimeSequence.Intermission3:
|
||||
TimeSequenceStepIntermission3(sequenceProgress);
|
||||
break;
|
||||
case PacManTimeSequence.AttractScreenWaitToRestart:
|
||||
case PacManTimeSequence.WaitForStartTimeout:
|
||||
// These don't have steps
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void TimeSequenceExecuteFinalize(PacManTimeSequence timeSequence)
|
||||
{
|
||||
// Debug.Log($"{gameObject} Triggered time sequence step for sequence {currentTimeSequence} with progress {sequenceProgress}");
|
||||
switch (timeSequence)
|
||||
{
|
||||
default:
|
||||
Debug.LogError($"{gameObject} No time sequence finalize known for sequence {currentTimeSequence}");
|
||||
break;
|
||||
case PacManTimeSequence.AttractScreenIntroduction:
|
||||
TimeSequenceFinalizeAttractScreenIntroduction();
|
||||
break;
|
||||
case PacManTimeSequence.WaitForStart:
|
||||
TimeSequenceFinalizeWaitForStart();
|
||||
break;
|
||||
case PacManTimeSequence.StartNewGame:
|
||||
TimeSequenceFinalizeStartNewGame();
|
||||
break;
|
||||
case PacManTimeSequence.StartNewLevel:
|
||||
TimeSequenceFinalizeStartNewLevel();
|
||||
break;
|
||||
case PacManTimeSequence.GhostCaught:
|
||||
TimeSequenceFinalizeGhostCaught();
|
||||
break;
|
||||
case PacManTimeSequence.RestartLevel:
|
||||
TimeSequenceFinalizeRestartLevel();
|
||||
break;
|
||||
case PacManTimeSequence.Intermission2:
|
||||
TimeSequenceFinalizeIntermission2();
|
||||
break;
|
||||
case PacManTimeSequence.Intermission3:
|
||||
TimeSequenceFinalizeIntermission3();
|
||||
break;
|
||||
case PacManTimeSequence.AttractScreenDemo:
|
||||
case PacManTimeSequence.WaitForStartTimeout:
|
||||
case PacManTimeSequence.AttractScreenWaitToRestart:
|
||||
case PacManTimeSequence.GameOver:
|
||||
case PacManTimeSequence.Intermission1:
|
||||
case PacManTimeSequence.PacManCaught:
|
||||
case PacManTimeSequence.BoardClear:
|
||||
// These don't have a finalize
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void TimeSequenceExecuteFinished(PacManTimeSequence timeSequence)
|
||||
{
|
||||
// Debug.Log($"{gameObject} Triggered time sequence step for sequence {currentTimeSequence} with progress {sequenceProgress}");
|
||||
switch (timeSequence)
|
||||
{
|
||||
default:
|
||||
Debug.LogError($"{gameObject} No time sequence finish known for sequence {currentTimeSequence}");
|
||||
break;
|
||||
case PacManTimeSequence.AttractScreenIntroduction:
|
||||
TimeSequenceFinishedAttractScreenIntroduction();
|
||||
break;
|
||||
case PacManTimeSequence.AttractScreenDemo:
|
||||
TimeSequenceFinishedAttractScreenDemo();
|
||||
break;
|
||||
case PacManTimeSequence.AttractScreenWaitToRestart:
|
||||
TimeSequenceFinishedAttractScreenWaitToRestart();
|
||||
break;
|
||||
case PacManTimeSequence.WaitForStartTimeout:
|
||||
TimeSequenceFinishedWaitForStartTimeout();
|
||||
break;
|
||||
case PacManTimeSequence.BoardClear:
|
||||
TimeSequenceFinishedBoardClear();
|
||||
break;
|
||||
case PacManTimeSequence.PacManCaught:
|
||||
TimeSequenceFinishedPacManCaught();
|
||||
break;
|
||||
case PacManTimeSequence.GameOver:
|
||||
TimeSequenceFinishedGameOver();
|
||||
break;
|
||||
case PacManTimeSequence.Intermission1:
|
||||
TimeSequenceFinishedIntermission1();
|
||||
break;
|
||||
case PacManTimeSequence.Intermission2:
|
||||
TimeSequenceFinishedIntermission2();
|
||||
break;
|
||||
case PacManTimeSequence.Intermission3:
|
||||
TimeSequenceFinishedIntermission3();
|
||||
break;
|
||||
case PacManTimeSequence.RestartLevel:
|
||||
case PacManTimeSequence.StartNewLevel:
|
||||
case PacManTimeSequence.GhostCaught:
|
||||
case PacManTimeSequence.WaitForStart:
|
||||
case PacManTimeSequence.StartNewGame:
|
||||
// These don't have a finished
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private float[] GetTimeSequenceKeyframeTimes(PacManTimeSequence timeSequence)
|
||||
{
|
||||
switch (timeSequence)
|
||||
{
|
||||
default:
|
||||
Debug.LogError($"{gameObject} No time sequence keyframe times known for sequence {timeSequence}");
|
||||
return new float[0];
|
||||
case PacManTimeSequence.AttractScreenIntroduction:
|
||||
return DeltaToAbsolute(new float[] { 0, 0.032f, 1f, 1f, .5f, .5f, 1f, .5f, .5f, 1f, .5f, .5f, 1f, .5f, 1f, 1f, 1f,
|
||||
5f, 0.2f, 2f, 0.91667f, 2f, 0.91667f, 2f, 0.91667f, 2f, 0.91667f });
|
||||
case PacManTimeSequence.AttractScreenDemo:
|
||||
return DeltaToAbsolute(new float[] { 0, 0.016f, 0.05f, 0.16f, 0.33f, 1.85f, 54f });
|
||||
case PacManTimeSequence.AttractScreenWaitToRestart:
|
||||
return DeltaToAbsolute(new float[] { 0, 2f });
|
||||
case PacManTimeSequence.WaitForStart:
|
||||
return DeltaToAbsolute(new float[] { 0, 0.016f });
|
||||
case PacManTimeSequence.WaitForStartTimeout:
|
||||
return DeltaToAbsolute(new float[] { 0, 5f });
|
||||
case PacManTimeSequence.StartNewGame:
|
||||
return DeltaToAbsolute(new float[] { 0, 0.016f, 2.2f, 0.032f, 0.032f, 1.92f, 0.032f });
|
||||
case PacManTimeSequence.BoardClear:
|
||||
return DeltaToAbsolute(new float[] { 0, 2f, 0.016f, 1.6f - 0.016f, 0.016f, 0.032f, 0.3f });
|
||||
case PacManTimeSequence.StartNewLevel:
|
||||
return DeltaToAbsolute(new float[] { 0, 0.064f, 0.032f, 1.85f, 0.016f });
|
||||
case PacManTimeSequence.GhostCaught:
|
||||
return DeltaToAbsolute(new float[] { 0, 0.91667f });
|
||||
case PacManTimeSequence.PacManCaught:
|
||||
return DeltaToAbsolute(new float[] { 0, 1, 0.35f, 2.40f });
|
||||
case PacManTimeSequence.RestartLevel:
|
||||
return DeltaToAbsolute(new float[] { 0, 0.016f, 0.064f, 0.032f, 1.85f, 0.016f });
|
||||
case PacManTimeSequence.GameOver:
|
||||
return DeltaToAbsolute(new float[] { 0, 1.95f });
|
||||
case PacManTimeSequence.Intermission1:
|
||||
return DeltaToAbsolute(new float[] { 0, 0.316f, 0.3f, 3.96f, 2.25f, 3.93f });
|
||||
case PacManTimeSequence.Intermission2:
|
||||
return DeltaToAbsolute(new float[] { 0, 0.25f, 0.083f, 0.3f, 1.43f, 2.5f, 1.816f, 1.25f, 0.017f, 1f, 1.966f, 0.033f });
|
||||
case PacManTimeSequence.Intermission3:
|
||||
return DeltaToAbsolute(new float[] { 0, 0.316f, 0.7f, 3.35f, 0.83f, 3.67f });
|
||||
}
|
||||
}
|
||||
|
||||
private static float[] DeltaToAbsolute(float[] delta)
|
||||
{
|
||||
if (delta.Length < 1)
|
||||
{
|
||||
return new float[0];
|
||||
}
|
||||
|
||||
float[] absolute = new float[delta.Length];
|
||||
absolute[0] = delta[0];
|
||||
for (int i = 1; i < delta.Length; i++)
|
||||
{
|
||||
absolute[i] = delta[i] + absolute[i - 1];
|
||||
}
|
||||
return absolute;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public int TimeSequenceProgress
|
||||
{
|
||||
get => timeSequenceProgress;
|
||||
}
|
||||
|
||||
public float TimeSequenceSecondsPassed
|
||||
{
|
||||
get => timeSequenceSecondsPassed;
|
||||
set => TimeSequenceProgressToTime(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Sequences/TimeSequenceShared.cs.meta
Normal file
11
Assets/Scripts/Sequences/TimeSequenceShared.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 506fd020620e6d24787a909c153b2da5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -7,19 +7,24 @@ namespace Marro.PacManUdon
|
||||
switch (sequenceProgress)
|
||||
{
|
||||
case 0:
|
||||
PrepareForCutscene();
|
||||
|
||||
SetGameState(PacManGameState.WaitForStart);
|
||||
HideEverything();
|
||||
soundManager.SuppressSound(false);
|
||||
soundManager.PlayCoinSound();
|
||||
break;
|
||||
case 1:
|
||||
SetPressStartButtonScreenVisible(true);
|
||||
if (playerInput.active == false && hasTimeSequenceQueued == false)
|
||||
{
|
||||
StartTimeSequence(PacManTimeSequence.WaitForStartTimeout);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void TimeSequenceFinalizeWaitForStart()
|
||||
{
|
||||
if (playerInput.active == false)
|
||||
{
|
||||
StartTimeSequence(PacManTimeSequence.WaitForStartTimeout);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
13
Assets/Scripts/Sequences/WaitForStartTimeout.cs
Normal file
13
Assets/Scripts/Sequences/WaitForStartTimeout.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace Marro.PacManUdon
|
||||
{
|
||||
public partial class GameManager
|
||||
{
|
||||
private void TimeSequenceFinishedWaitForStartTimeout()
|
||||
{
|
||||
if (playerInput.active == false)
|
||||
{
|
||||
StartAttractMode();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Sequences/WaitForStartTimeout.cs.meta
Normal file
11
Assets/Scripts/Sequences/WaitForStartTimeout.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 445b4cd5c436f3645824ef18948c8593
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace Marro.PacManUdon
|
||||
{
|
||||
public partial class GameManager
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
namespace Marro.PacManUdon
|
||||
{
|
||||
public partial class GameManager
|
||||
{
|
||||
private void TimeSequenceStepWaitForStartTimeout(int sequenceProgress)
|
||||
{
|
||||
switch (sequenceProgress)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
if (playerInput.active == false && hasTimeSequenceQueued == false)
|
||||
{
|
||||
StartAttractMode();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -188,17 +188,17 @@ public class SoundManager : UdonSharpBehaviour
|
||||
return;
|
||||
}
|
||||
|
||||
if (!audioSource.isPlaying || audioSource.clip == null)
|
||||
{
|
||||
PlaySound(audioSource, audioClip, loop);
|
||||
}
|
||||
|
||||
if (audioSource.clip == audioClip)
|
||||
{
|
||||
// No need to switch
|
||||
return;
|
||||
}
|
||||
|
||||
if (!audioSource.isPlaying || audioSource.clip == null)
|
||||
{
|
||||
PlaySound(audioSource, audioClip, loop);
|
||||
}
|
||||
|
||||
var newTimeSamples = (int)(audioSource.timeSamples / (double)audioSource.clip.samples * audioClip.samples);
|
||||
|
||||
audioSource.clip = audioClip;
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
{
|
||||
extraLifeIndicators[i - 1] = extraLifeIndicatorTransforms[i].gameObject;
|
||||
}
|
||||
Debug.Log($"{gameObject} extraLifeIndicators.Length: {extraLifeIndicators.Length}");
|
||||
// Debug.Log($"{gameObject} extraLifeIndicators.Length: {extraLifeIndicators.Length}");
|
||||
}
|
||||
|
||||
|
||||
|
||||
15
Assets/Scripts/SyncedObject.cs
Normal file
15
Assets/Scripts/SyncedObject.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System.Collections;
|
||||
using UdonSharp;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Marro.PacManUdon
|
||||
{
|
||||
public abstract class SyncedObject : UdonSharpBehaviour
|
||||
{
|
||||
public long LastUpdateTicks { get; set; }
|
||||
public float Dt { get; set; }
|
||||
public abstract void FixedUpdate();
|
||||
public abstract void AppendSyncedData(byte[][] data, ref int index, NetworkEventType eventType);
|
||||
public abstract bool SetSyncedData(byte[] data, ref int index, NetworkEventType eventType);
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/SyncedObject.cs.meta
Normal file
11
Assets/Scripts/SyncedObject.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d09fe6fd5a83df9468f5ffcb43d73af3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Test stuff.meta
Normal file
8
Assets/Test stuff.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1ab80220efbebb2489a3218f3ee9b00b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
109
Assets/Test stuff/ColoredTexture.controller
Normal file
109
Assets/Test stuff/ColoredTexture.controller
Normal file
@@ -0,0 +1,109 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!91 &9100000
|
||||
AnimatorController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: ColoredTexture
|
||||
serializedVersion: 5
|
||||
m_AnimatorParameters:
|
||||
- m_Name: Color
|
||||
m_Type: 1
|
||||
m_DefaultFloat: 0
|
||||
m_DefaultInt: 0
|
||||
m_DefaultBool: 0
|
||||
m_Controller: {fileID: 0}
|
||||
m_AnimatorLayers:
|
||||
- serializedVersion: 5
|
||||
m_Name: Base Layer
|
||||
m_StateMachine: {fileID: 2235177317997810699}
|
||||
m_Mask: {fileID: 0}
|
||||
m_Motions: []
|
||||
m_Behaviours: []
|
||||
m_BlendingMode: 0
|
||||
m_SyncedLayerIndex: -1
|
||||
m_DefaultWeight: 0
|
||||
m_IKPass: 0
|
||||
m_SyncedLayerAffectsTiming: 0
|
||||
m_Controller: {fileID: 9100000}
|
||||
--- !u!1107 &2235177317997810699
|
||||
AnimatorStateMachine:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Base Layer
|
||||
m_ChildStates:
|
||||
- serializedVersion: 1
|
||||
m_State: {fileID: 6251436573727931732}
|
||||
m_Position: {x: 384.82895, y: 133.70117, z: 0}
|
||||
m_ChildStateMachines: []
|
||||
m_AnyStateTransitions: []
|
||||
m_EntryTransitions: []
|
||||
m_StateMachineTransitions: {}
|
||||
m_StateMachineBehaviours: []
|
||||
m_AnyStatePosition: {x: 50, y: 20, z: 0}
|
||||
m_EntryPosition: {x: 50, y: 120, z: 0}
|
||||
m_ExitPosition: {x: 800, y: 120, z: 0}
|
||||
m_ParentStateMachinePosition: {x: 800, y: 20, z: 0}
|
||||
m_DefaultState: {fileID: 6251436573727931732}
|
||||
--- !u!1102 &6251436573727931732
|
||||
AnimatorState:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Blend Tree
|
||||
m_Speed: 1
|
||||
m_CycleOffset: 0
|
||||
m_Transitions: []
|
||||
m_StateMachineBehaviours: []
|
||||
m_Position: {x: 50, y: 50, z: 0}
|
||||
m_IKOnFeet: 0
|
||||
m_WriteDefaultValues: 1
|
||||
m_Mirror: 0
|
||||
m_SpeedParameterActive: 0
|
||||
m_MirrorParameterActive: 0
|
||||
m_CycleOffsetParameterActive: 0
|
||||
m_TimeParameterActive: 0
|
||||
m_Motion: {fileID: 7315205519034161812}
|
||||
m_Tag:
|
||||
m_SpeedParameter:
|
||||
m_MirrorParameter:
|
||||
m_CycleOffsetParameter:
|
||||
m_TimeParameter:
|
||||
--- !u!206 &7315205519034161812
|
||||
BlendTree:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Blend Tree
|
||||
m_Childs:
|
||||
- serializedVersion: 2
|
||||
m_Motion: {fileID: 7400000, guid: f06a4450a22bb184bb3881fbc7ddc36f, type: 2}
|
||||
m_Threshold: 0
|
||||
m_Position: {x: 0, y: 0}
|
||||
m_TimeScale: 1
|
||||
m_CycleOffset: 0
|
||||
m_DirectBlendParameter: Color
|
||||
m_Mirror: 0
|
||||
- serializedVersion: 2
|
||||
m_Motion: {fileID: 7400000, guid: 152a2df117ac1c948b25f28a386ac289, type: 2}
|
||||
m_Threshold: 1
|
||||
m_Position: {x: 0, y: 0}
|
||||
m_TimeScale: 1
|
||||
m_CycleOffset: 0
|
||||
m_DirectBlendParameter: Color
|
||||
m_Mirror: 0
|
||||
m_BlendParameter: Color
|
||||
m_BlendParameterY: Blend
|
||||
m_MinThreshold: 0
|
||||
m_MaxThreshold: 1
|
||||
m_UseAutomaticThresholds: 0
|
||||
m_NormalizedBlendValues: 0
|
||||
m_BlendType: 0
|
||||
8
Assets/Test stuff/ColoredTexture.controller.meta
Normal file
8
Assets/Test stuff/ColoredTexture.controller.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 72593807222e776478e455c600f7ccf9
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 9100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
206
Assets/Test stuff/GreenTexture.anim
Normal file
206
Assets/Test stuff/GreenTexture.anim
Normal file
@@ -0,0 +1,206 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!74 &7400000
|
||||
AnimationClip:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: GreenTexture
|
||||
serializedVersion: 7
|
||||
m_Legacy: 0
|
||||
m_Compressed: 0
|
||||
m_UseHighQualityCurve: 1
|
||||
m_RotationCurves: []
|
||||
m_CompressedRotationCurves: []
|
||||
m_EulerCurves: []
|
||||
m_PositionCurves: []
|
||||
m_ScaleCurves: []
|
||||
m_FloatCurves:
|
||||
- serializedVersion: 2
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 0
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 136
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
attribute: m_Color.r
|
||||
path:
|
||||
classID: 114
|
||||
script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
flags: 0
|
||||
- serializedVersion: 2
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 1
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 136
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
attribute: m_Color.g
|
||||
path:
|
||||
classID: 114
|
||||
script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
flags: 0
|
||||
- serializedVersion: 2
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 0
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 136
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
attribute: m_Color.b
|
||||
path:
|
||||
classID: 114
|
||||
script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
flags: 0
|
||||
m_PPtrCurves: []
|
||||
m_SampleRate: 1
|
||||
m_WrapMode: 0
|
||||
m_Bounds:
|
||||
m_Center: {x: 0, y: 0, z: 0}
|
||||
m_Extent: {x: 0, y: 0, z: 0}
|
||||
m_ClipBindingConstant:
|
||||
genericBindings:
|
||||
- serializedVersion: 2
|
||||
path: 0
|
||||
attribute: 2526845255
|
||||
script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
typeID: 114
|
||||
customType: 0
|
||||
isPPtrCurve: 0
|
||||
isIntCurve: 0
|
||||
isSerializeReferenceCurve: 0
|
||||
- serializedVersion: 2
|
||||
path: 0
|
||||
attribute: 4215373228
|
||||
script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
typeID: 114
|
||||
customType: 0
|
||||
isPPtrCurve: 0
|
||||
isIntCurve: 0
|
||||
isSerializeReferenceCurve: 0
|
||||
- serializedVersion: 2
|
||||
path: 0
|
||||
attribute: 2334886179
|
||||
script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
typeID: 114
|
||||
customType: 0
|
||||
isPPtrCurve: 0
|
||||
isIntCurve: 0
|
||||
isSerializeReferenceCurve: 0
|
||||
pptrCurveMapping: []
|
||||
m_AnimationClipSettings:
|
||||
serializedVersion: 2
|
||||
m_AdditiveReferencePoseClip: {fileID: 0}
|
||||
m_AdditiveReferencePoseTime: 0
|
||||
m_StartTime: 0
|
||||
m_StopTime: 0
|
||||
m_OrientationOffsetY: 0
|
||||
m_Level: 0
|
||||
m_CycleOffset: 0
|
||||
m_HasAdditiveReferencePose: 0
|
||||
m_LoopTime: 0
|
||||
m_LoopBlend: 0
|
||||
m_LoopBlendOrientation: 0
|
||||
m_LoopBlendPositionY: 0
|
||||
m_LoopBlendPositionXZ: 0
|
||||
m_KeepOriginalOrientation: 0
|
||||
m_KeepOriginalPositionY: 1
|
||||
m_KeepOriginalPositionXZ: 0
|
||||
m_HeightFromFeet: 0
|
||||
m_Mirror: 0
|
||||
m_EditorCurves:
|
||||
- serializedVersion: 2
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 0
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 136
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
attribute: m_Color.r
|
||||
path:
|
||||
classID: 114
|
||||
script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
flags: 0
|
||||
- serializedVersion: 2
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 1
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 136
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
attribute: m_Color.g
|
||||
path:
|
||||
classID: 114
|
||||
script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
flags: 0
|
||||
- serializedVersion: 2
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 0
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 136
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
attribute: m_Color.b
|
||||
path:
|
||||
classID: 114
|
||||
script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
flags: 0
|
||||
m_EulerEditorCurves: []
|
||||
m_HasGenericRootTransform: 0
|
||||
m_HasMotionFloatCurves: 0
|
||||
m_Events: []
|
||||
8
Assets/Test stuff/GreenTexture.anim.meta
Normal file
8
Assets/Test stuff/GreenTexture.anim.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 152a2df117ac1c948b25f28a386ac289
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 7400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
206
Assets/Test stuff/RedTexture.anim
Normal file
206
Assets/Test stuff/RedTexture.anim
Normal file
@@ -0,0 +1,206 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!74 &7400000
|
||||
AnimationClip:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: RedTexture
|
||||
serializedVersion: 7
|
||||
m_Legacy: 0
|
||||
m_Compressed: 0
|
||||
m_UseHighQualityCurve: 1
|
||||
m_RotationCurves: []
|
||||
m_CompressedRotationCurves: []
|
||||
m_EulerCurves: []
|
||||
m_PositionCurves: []
|
||||
m_ScaleCurves: []
|
||||
m_FloatCurves:
|
||||
- serializedVersion: 2
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 1
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 136
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
attribute: m_Color.r
|
||||
path:
|
||||
classID: 114
|
||||
script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
flags: 0
|
||||
- serializedVersion: 2
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 0
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 136
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
attribute: m_Color.g
|
||||
path:
|
||||
classID: 114
|
||||
script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
flags: 0
|
||||
- serializedVersion: 2
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 0
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 136
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
attribute: m_Color.b
|
||||
path:
|
||||
classID: 114
|
||||
script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
flags: 0
|
||||
m_PPtrCurves: []
|
||||
m_SampleRate: 1
|
||||
m_WrapMode: 0
|
||||
m_Bounds:
|
||||
m_Center: {x: 0, y: 0, z: 0}
|
||||
m_Extent: {x: 0, y: 0, z: 0}
|
||||
m_ClipBindingConstant:
|
||||
genericBindings:
|
||||
- serializedVersion: 2
|
||||
path: 0
|
||||
attribute: 2526845255
|
||||
script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
typeID: 114
|
||||
customType: 0
|
||||
isPPtrCurve: 0
|
||||
isIntCurve: 0
|
||||
isSerializeReferenceCurve: 0
|
||||
- serializedVersion: 2
|
||||
path: 0
|
||||
attribute: 4215373228
|
||||
script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
typeID: 114
|
||||
customType: 0
|
||||
isPPtrCurve: 0
|
||||
isIntCurve: 0
|
||||
isSerializeReferenceCurve: 0
|
||||
- serializedVersion: 2
|
||||
path: 0
|
||||
attribute: 2334886179
|
||||
script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
typeID: 114
|
||||
customType: 0
|
||||
isPPtrCurve: 0
|
||||
isIntCurve: 0
|
||||
isSerializeReferenceCurve: 0
|
||||
pptrCurveMapping: []
|
||||
m_AnimationClipSettings:
|
||||
serializedVersion: 2
|
||||
m_AdditiveReferencePoseClip: {fileID: 0}
|
||||
m_AdditiveReferencePoseTime: 0
|
||||
m_StartTime: 0
|
||||
m_StopTime: 0
|
||||
m_OrientationOffsetY: 0
|
||||
m_Level: 0
|
||||
m_CycleOffset: 0
|
||||
m_HasAdditiveReferencePose: 0
|
||||
m_LoopTime: 0
|
||||
m_LoopBlend: 0
|
||||
m_LoopBlendOrientation: 0
|
||||
m_LoopBlendPositionY: 0
|
||||
m_LoopBlendPositionXZ: 0
|
||||
m_KeepOriginalOrientation: 0
|
||||
m_KeepOriginalPositionY: 1
|
||||
m_KeepOriginalPositionXZ: 0
|
||||
m_HeightFromFeet: 0
|
||||
m_Mirror: 0
|
||||
m_EditorCurves:
|
||||
- serializedVersion: 2
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 1
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 136
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
attribute: m_Color.r
|
||||
path:
|
||||
classID: 114
|
||||
script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
flags: 0
|
||||
- serializedVersion: 2
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 0
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 136
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
attribute: m_Color.g
|
||||
path:
|
||||
classID: 114
|
||||
script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
flags: 0
|
||||
- serializedVersion: 2
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 0
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 136
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
attribute: m_Color.b
|
||||
path:
|
||||
classID: 114
|
||||
script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
flags: 0
|
||||
m_EulerEditorCurves: []
|
||||
m_HasGenericRootTransform: 0
|
||||
m_HasMotionFloatCurves: 0
|
||||
m_Events: []
|
||||
8
Assets/Test stuff/RedTexture.anim.meta
Normal file
8
Assets/Test stuff/RedTexture.anim.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f06a4450a22bb184bb3881fbc7ddc36f
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 7400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
442
Assets/Test stuff/TestBall.asset
Normal file
442
Assets/Test stuff/TestBall.asset
Normal file
@@ -0,0 +1,442 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: c333ccfdd0cbdbc4ca30cef2dd6e6b9b, type: 3}
|
||||
m_Name: TestBall
|
||||
m_EditorClassIdentifier:
|
||||
serializedUdonProgramAsset: {fileID: 11400000, guid: 8968388b0e4fe434fb8da62328c108a0, type: 2}
|
||||
udonAssembly:
|
||||
assemblyError:
|
||||
sourceCsScript: {fileID: 11500000, guid: 0980d82a15346eb45b49fd33db0ffee9, type: 3}
|
||||
scriptVersion: 2
|
||||
compiledVersion: 2
|
||||
behaviourSyncMode: 0
|
||||
hasInteractEvent: 0
|
||||
scriptID: -3035274785675086507
|
||||
serializationData:
|
||||
SerializedFormat: 2
|
||||
SerializedBytes:
|
||||
ReferencedUnityObjects: []
|
||||
SerializedBytesString:
|
||||
Prefab: {fileID: 0}
|
||||
PrefabModificationsReferencedUnityObjects: []
|
||||
PrefabModifications: []
|
||||
SerializationNodes:
|
||||
- Name: fieldDefinitions
|
||||
Entry: 7
|
||||
Data: 0|System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[UdonSharp.Compiler.FieldDefinition,
|
||||
UdonSharp.Editor]], mscorlib
|
||||
- Name: comparer
|
||||
Entry: 7
|
||||
Data: 1|System.Collections.Generic.GenericEqualityComparer`1[[System.String,
|
||||
mscorlib]], mscorlib
|
||||
- Name:
|
||||
Entry: 8
|
||||
Data:
|
||||
- Name:
|
||||
Entry: 12
|
||||
Data: 7
|
||||
- Name:
|
||||
Entry: 7
|
||||
Data:
|
||||
- Name: $k
|
||||
Entry: 1
|
||||
Data: <LastUpdateTicks>k__BackingField
|
||||
- Name: $v
|
||||
Entry: 7
|
||||
Data: 2|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
|
||||
- Name: <Name>k__BackingField
|
||||
Entry: 1
|
||||
Data: <LastUpdateTicks>k__BackingField
|
||||
- Name: <UserType>k__BackingField
|
||||
Entry: 7
|
||||
Data: 3|System.RuntimeType, mscorlib
|
||||
- Name:
|
||||
Entry: 1
|
||||
Data: System.Int64, mscorlib
|
||||
- Name:
|
||||
Entry: 8
|
||||
Data:
|
||||
- Name: <SystemType>k__BackingField
|
||||
Entry: 9
|
||||
Data: 3
|
||||
- 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: 4|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: <Dt>k__BackingField
|
||||
- Name: $v
|
||||
Entry: 7
|
||||
Data: 5|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
|
||||
- Name: <Name>k__BackingField
|
||||
Entry: 1
|
||||
Data: <Dt>k__BackingField
|
||||
- Name: <UserType>k__BackingField
|
||||
Entry: 7
|
||||
Data: 6|System.RuntimeType, mscorlib
|
||||
- Name:
|
||||
Entry: 1
|
||||
Data: System.Single, mscorlib
|
||||
- Name:
|
||||
Entry: 8
|
||||
Data:
|
||||
- Name: <SystemType>k__BackingField
|
||||
Entry: 9
|
||||
Data: 6
|
||||
- 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: 7|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: networkManager
|
||||
- Name: $v
|
||||
Entry: 7
|
||||
Data: 8|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
|
||||
- Name: <Name>k__BackingField
|
||||
Entry: 1
|
||||
Data: networkManager
|
||||
- Name: <UserType>k__BackingField
|
||||
Entry: 7
|
||||
Data: 9|System.RuntimeType, mscorlib
|
||||
- Name:
|
||||
Entry: 1
|
||||
Data: Marro.PacManUdon.NetworkManager, Assembly-CSharp
|
||||
- Name:
|
||||
Entry: 8
|
||||
Data:
|
||||
- Name: <SystemType>k__BackingField
|
||||
Entry: 7
|
||||
Data: 10|System.RuntimeType, mscorlib
|
||||
- Name:
|
||||
Entry: 1
|
||||
Data: VRC.Udon.UdonBehaviour, VRC.Udon
|
||||
- Name:
|
||||
Entry: 8
|
||||
Data:
|
||||
- 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: 11|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
|
||||
- Name:
|
||||
Entry: 12
|
||||
Data: 1
|
||||
- Name:
|
||||
Entry: 7
|
||||
Data: 12|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: start
|
||||
- Name: $v
|
||||
Entry: 7
|
||||
Data: 13|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
|
||||
- Name: <Name>k__BackingField
|
||||
Entry: 1
|
||||
Data: start
|
||||
- Name: <UserType>k__BackingField
|
||||
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: 14
|
||||
- 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: 15|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
|
||||
- Name:
|
||||
Entry: 12
|
||||
Data: 1
|
||||
- Name:
|
||||
Entry: 7
|
||||
Data: 16|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: end
|
||||
- Name: $v
|
||||
Entry: 7
|
||||
Data: 17|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
|
||||
- Name: <Name>k__BackingField
|
||||
Entry: 1
|
||||
Data: end
|
||||
- Name: <UserType>k__BackingField
|
||||
Entry: 9
|
||||
Data: 14
|
||||
- Name: <SystemType>k__BackingField
|
||||
Entry: 9
|
||||
Data: 14
|
||||
- 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: 18|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
|
||||
- Name:
|
||||
Entry: 12
|
||||
Data: 1
|
||||
- Name:
|
||||
Entry: 7
|
||||
Data: 19|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: amountUp
|
||||
- Name: $v
|
||||
Entry: 7
|
||||
Data: 20|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
|
||||
- Name: <Name>k__BackingField
|
||||
Entry: 1
|
||||
Data: amountUp
|
||||
- Name: <UserType>k__BackingField
|
||||
Entry: 9
|
||||
Data: 6
|
||||
- Name: <SystemType>k__BackingField
|
||||
Entry: 9
|
||||
Data: 6
|
||||
- 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: 21|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: loopOffset
|
||||
- Name: $v
|
||||
Entry: 7
|
||||
Data: 22|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
|
||||
- Name: <Name>k__BackingField
|
||||
Entry: 1
|
||||
Data: loopOffset
|
||||
- Name: <UserType>k__BackingField
|
||||
Entry: 7
|
||||
Data: 23|System.RuntimeType, mscorlib
|
||||
- Name:
|
||||
Entry: 1
|
||||
Data: System.Int32, mscorlib
|
||||
- Name:
|
||||
Entry: 8
|
||||
Data:
|
||||
- Name: <SystemType>k__BackingField
|
||||
Entry: 9
|
||||
Data: 23
|
||||
- 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: 24|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:
|
||||
- Name:
|
||||
Entry: 8
|
||||
Data:
|
||||
8
Assets/Test stuff/TestBall.asset.meta
Normal file
8
Assets/Test stuff/TestBall.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1845851c6c8f8254baa6b40646c66d59
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
90
Assets/Test stuff/TestBall.cs
Normal file
90
Assets/Test stuff/TestBall.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
using librsync.net;
|
||||
using Marro.PacManUdon;
|
||||
using System;
|
||||
using System.Drawing.Text;
|
||||
using UnityEngine;
|
||||
|
||||
public class TestBall : SyncedObject
|
||||
{
|
||||
[SerializeField] private NetworkManager networkManager;
|
||||
[SerializeField] private Transform start;
|
||||
[SerializeField] private Transform end;
|
||||
|
||||
private const int LoopTimeMs = 1000;
|
||||
private const float MaxUp = 0.7f;
|
||||
private const float UpPerPress = 0.4f;
|
||||
private const float DownPerSecond = 1;
|
||||
|
||||
private float amountUp = 0;
|
||||
private int loopOffset = 0;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
networkManager.Initialize();
|
||||
}
|
||||
|
||||
public override void FixedUpdate()
|
||||
{
|
||||
DeltaUp(-DownPerSecond * Dt);
|
||||
|
||||
float progress = GetProgress();
|
||||
transform.position = Vector3.Lerp(start.position, end.position, progress) + amountUp * MaxUp * Vector3.up;;
|
||||
}
|
||||
|
||||
private void DeltaUp(float delta)
|
||||
{
|
||||
amountUp = Mathf.Clamp(amountUp + delta, 0, 1);
|
||||
}
|
||||
|
||||
private void SetProgress(float progress)
|
||||
{
|
||||
var currentTimestamp = networkManager.GetTimestamp(networkManager.CurrentTimeTicks);
|
||||
loopOffset = (int)(currentTimestamp - progress * LoopTimeMs);
|
||||
}
|
||||
|
||||
private float GetProgress()
|
||||
{
|
||||
var currentTimestamp = networkManager.GetTimestamp(networkManager.CurrentTimeTicks);
|
||||
return ((int)currentTimestamp - loopOffset) % LoopTimeMs / (float)LoopTimeMs; // "uint % int" is not exposed, I love working in Udon
|
||||
}
|
||||
|
||||
public void UpButtonPressed()
|
||||
{
|
||||
DeltaUp(UpPerPress);
|
||||
Debug.Log($"({nameof(TestBall)}) Up button pressed, jumped up at {GetProgress()} to {amountUp}.");
|
||||
networkManager.SendEvent((NetworkEventType)1);
|
||||
}
|
||||
|
||||
public void SyncButtonPressed()
|
||||
{
|
||||
networkManager.SendEvent((NetworkEventType)0);
|
||||
Debug.Log($"({nameof(TestBall)}) Sync button pressed, synced at progress {GetProgress()} and amountUp {amountUp}.");
|
||||
}
|
||||
|
||||
public override void AppendSyncedData(byte[][] data, ref int index, NetworkEventType eventType)
|
||||
{
|
||||
if (eventType == 0)
|
||||
{
|
||||
data[index++] = BitConverter.GetBytes(amountUp);
|
||||
data[index++] = BitConverter.GetBytes(GetProgress());
|
||||
}
|
||||
}
|
||||
|
||||
public override bool SetSyncedData(byte[] data, ref int index, NetworkEventType eventType)
|
||||
{
|
||||
if (eventType == 0)
|
||||
{
|
||||
amountUp = BitConverter.ToSingle(data, index);
|
||||
SetProgress(BitConverter.ToSingle(data, index + 4));
|
||||
Debug.Log($"({nameof(TestBall)}) Received sync event, synced to progress {GetProgress()} and amountUp {amountUp}.");
|
||||
index += 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
DeltaUp(UpPerPress);
|
||||
Debug.Log($"({nameof(TestBall)}) Received up event, jumped up at {GetProgress()} to {amountUp}.");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
11
Assets/Test stuff/TestBall.cs.meta
Normal file
11
Assets/Test stuff/TestBall.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0980d82a15346eb45b49fd33db0ffee9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -18,7 +18,7 @@ PhysicsManager:
|
||||
m_ClothInterCollisionDistance: 0
|
||||
m_ClothInterCollisionStiffness: 0
|
||||
m_ContactsGeneration: 1
|
||||
m_LayerCollisionMatrix: dfaff7ffdfaff7ffdfaff7ffffffffffdfaff7ffc800c0ffffffffffffffffffdfaff7ffdf09f4ffdf09f4ffdfaff7ffc800c0ffdfe9c3ffc820c0ffdfa9f7ffdfa9f7ffdfa9f7ffdf8ff7ffc800c0ffdf8ff7ffdf8ff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
m_LayerCollisionMatrix: d7aff7ffd7aff7ffd7aff7ff0800c0ffd7aff7ffc000c0fff7fffffff7ffffffd7aff7ffd709f4ffd709f4ffd7aff7ffc000c0ffd7e9c3ffc020c0ffd7a9f7ffd7a9f7ffd7a9f7ffd78ff7ffc000c0ffd78ff7ffd78ff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
m_SimulationMode: 0
|
||||
m_AutoSyncTransforms: 0
|
||||
m_ReuseCollisionCallbacks: 1
|
||||
|
||||
@@ -511,7 +511,7 @@ PlayerSettings:
|
||||
m_Automatic: 0
|
||||
- m_BuildTarget: iOSSupport
|
||||
m_APIs: 10000000
|
||||
m_Automatic: 1
|
||||
m_Automatic: 0
|
||||
- m_BuildTarget: WindowsStandaloneSupport
|
||||
m_APIs: 02000000
|
||||
m_Automatic: 0
|
||||
|
||||
@@ -8,7 +8,7 @@ TagManager:
|
||||
- Default
|
||||
- TransparentFX
|
||||
- Ignore Raycast
|
||||
- reserved3
|
||||
- Item
|
||||
- Water
|
||||
- UI
|
||||
- reserved6
|
||||
@@ -29,7 +29,7 @@ TagManager:
|
||||
- reserved4
|
||||
- MazeWalls
|
||||
- GhostStations
|
||||
-
|
||||
- reserved3
|
||||
-
|
||||
-
|
||||
-
|
||||
|
||||
Reference in New Issue
Block a user