public class GameManager : MonoBehaviour | |
{ | |
[SerializeField] | |
Player playerPrefab; | |
Timeline timeline; | |
static GameManager t; | |
List<ITimed> timedThings = new List<ITimed>(); | |
IInput currentInput; | |
Vector3 spawnPoint; | |
Transform spawner; | |
[SerializeField] | |
Transform spawnPrefab; | |
public static event System.Action<Player> ChangedPlayer; | |
[SerializeField] | |
int totalFrames = 0; | |
public static int TotalFrames { get { return t.totalFrames; } } | |
bool isFastForwarding = false; | |
int targetFrame; | |
public static int CurrentFrame { get { return t.timeline.CurrentFrame; } } | |
Player currentPlayer; | |
public static Player CurrentPlayer { get { return t.currentPlayer; } } | |
List<Player> players = new List<Player>(); | |
int _playerIndex = 0; | |
int playerIndex | |
{ | |
get { return _playerIndex; } | |
set | |
{ | |
_playerIndex = value; | |
if (_playerIndex >= players.Count) | |
{ | |
_playerIndex = _playerIndex % players.Count; | |
} | |
if (_playerIndex < 0) | |
{ | |
_playerIndex = players.Count - 1; | |
} | |
} | |
} | |
void Awake() | |
{ | |
t = this; | |
timeline = new Timeline(); | |
currentInput = new InputPlayer(); | |
players = FindObjectsOfType<Player>().ToList(); | |
Player currentPlayer = players.FirstOrDefault((player) => player.IsStartingPlayer); | |
Vector3 spawnPos = (currentPlayer != null) ? currentPlayer.transform.position : Vector3.zero; | |
spawner = Instantiate(spawnPrefab, spawnPos, Quaternion.identity); | |
} | |
void FixedUpdate() | |
{ | |
if (isFastForwarding) | |
{ | |
if (CurrentFrame == targetFrame) | |
{ | |
isFastForwarding = false; | |
Time.fixedDeltaTime = GameSettings.PhysStep; | |
} | |
RunFrame(); | |
} | |
else | |
{ | |
if (currentInput.ShouldPlay) | |
{ | |
RunFrame(); | |
totalFrames++; | |
} | |
} | |
} | |
void Update() | |
{ | |
currentInput.GetInput(); | |
} | |
void RunFrame() | |
{ | |
int frame = timeline.CurrentFrame; | |
if (timeline.HasStateAtFrame(frame)) | |
{ | |
if (timeline.CurrentFrame == 0 || IsCurrentFrameAFuturePoint(frame)) | |
{ | |
SerializeTimedAtCurrentFrame(); | |
} | |
else | |
{ | |
timeline.RemoveStateAtFrame(frame); | |
} | |
} | |
ProcessFrame(); | |
PassTime(); | |
timeline.CurrentFrame++; | |
} | |
void SerializeTimedAtCurrentFrame() | |
{ | |
timeline.RecordCurrentState( | |
timedThings.Select((timed) => timed.Serialize()) | |
.ToList() | |
); | |
} | |
public static void AddSerielizedState(TimedState state) | |
{ | |
t.timeline.AddSerielizedState(state); | |
} | |
public static void SelectPlayer(Player player) | |
{ | |
t.currentPlayer = player; | |
} | |
void SetFrame(int frame) | |
{ | |
if (frame < timeline.CurrentFrame) | |
{ | |
timeline.SetStateToClosestFrame(frame); | |
} | |
if (timeline.CurrentFrame < frame) | |
{ | |
BeginFastFowarding(frame); | |
} | |
} | |
void BeginFastFowarding(int _targetFrame) | |
{ | |
isFastForwarding = true; | |
targetFrame = _targetFrame; | |
int frameDiff = _targetFrame - CurrentFrame; | |
Time.fixedDeltaTime = GameSettings.CameraLerpDuration / frameDiff; | |
} | |
bool IsCurrentFrameAFuturePoint(int frame) | |
{ | |
return players.Any((player) => | |
{ | |
return player.FuturistFrame == frame && player != currentPlayer; | |
}); | |
} | |
public static void SetSpawnPoint(Vector3 pos) | |
{ | |
t.spawnPoint = pos; | |
t.spawner.transform.position = pos; | |
} | |
public static void SwitchPlayer(int indexMod) | |
{ | |
if (t.players.Count > 1) | |
{ | |
t.currentPlayer.Deselect(); | |
t.SerializeTimedAtCurrentFrame(); | |
t.playerIndex += indexMod; | |
t.currentPlayer = t.players[t.playerIndex]; | |
t.currentPlayer.Select(); | |
t.SetFrame(t.currentPlayer.FuturistFrame); | |
ChangedPlayer(t.currentPlayer); | |
SwitchInputType(InputTypes.TapPause); | |
} | |
} | |
public static void MakeNewPlayer() | |
{ | |
t.currentInput.EndInput(); | |
t.currentPlayer.Deselect(); | |
t.SetFrame(0); | |
t.currentPlayer = Instantiate(t.playerPrefab, t.spawnPoint, Quaternion.identity); | |
t.players.Add(t.currentPlayer); | |
t.playerIndex = t.players.Count - 1; | |
t.currentInput.StartInput(); | |
ChangedPlayer(t.currentPlayer); | |
SwitchInputType(InputTypes.TapPause); | |
} | |
public static void SwitchInputType(InputTypes nextInput) | |
{ | |
t.currentInput.EndInput(); | |
switch (nextInput) | |
{ | |
case InputTypes.Player: | |
t.currentInput = new InputPlayer(); | |
break; | |
case InputTypes.TapPause: | |
t.currentInput = new InputTapPause(); | |
break; | |
} | |
t.currentInput.StartInput(); | |
} | |
public static void AddActionToTimeline(Action action) | |
{ | |
t.timeline.AddAction(action); | |
} | |
public static void RegisterTimedThing(ITimed timed) | |
{ | |
t.timedThings.Add(timed); | |
} | |
public static void RegisterPlayer(Player player) | |
{ | |
t.players.Add(player); | |
} | |
void ProcessFrame() | |
{ | |
timeline.ProcessFrame(); | |
} | |
void PassTime() | |
{ | |
timedThings.ForEach((timed) => timed.Play(GameSettings.PhysStep)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment