Init
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Netcode;
|
||||
using UnityEngine;
|
||||
#if ENABLE_INPUT_SYSTEM
|
||||
using UnityEngine.InputSystem;
|
||||
#endif
|
||||
|
||||
namespace Learning.UnityNGO
|
||||
{
|
||||
/// <summary>
|
||||
/// Player controller with per-frame position recording and playback.
|
||||
/// Attach to the player prefab instead of ClientAuthoritativeMovement.
|
||||
/// </summary>
|
||||
public class PlayerRecordingController : NetworkBehaviour
|
||||
{
|
||||
public enum Mode
|
||||
{
|
||||
Control,
|
||||
Recording,
|
||||
Playback
|
||||
}
|
||||
|
||||
[Header("Movement")]
|
||||
public float Speed = 5f;
|
||||
|
||||
[Header("Recording")]
|
||||
public KeyCode RecordToggleKey = KeyCode.R;
|
||||
public KeyCode PlayKey = KeyCode.P;
|
||||
public KeyCode StopPlaybackKey = KeyCode.Escape;
|
||||
public bool LoopPlayback;
|
||||
|
||||
readonly List<Vector3> m_RecordedPositions = new();
|
||||
int m_PlaybackFrameIndex;
|
||||
Mode m_Mode = Mode.Control;
|
||||
|
||||
public Mode CurrentMode => m_Mode;
|
||||
public int RecordedFrameCount => m_RecordedPositions.Count;
|
||||
public bool HasRecording => m_RecordedPositions.Count > 0;
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (!IsOwner || !IsSpawned)
|
||||
return;
|
||||
|
||||
HandleInput();
|
||||
|
||||
if (m_Mode == Mode.Control || m_Mode == Mode.Recording)
|
||||
ApplyMovement();
|
||||
else if (m_Mode == Mode.Playback)
|
||||
AdvancePlayback();
|
||||
}
|
||||
|
||||
void LateUpdate()
|
||||
{
|
||||
if (!IsOwner || !IsSpawned || m_Mode != Mode.Recording)
|
||||
return;
|
||||
|
||||
m_RecordedPositions.Add(transform.position);
|
||||
}
|
||||
|
||||
void HandleInput()
|
||||
{
|
||||
if (WasKeyPressed(RecordToggleKey))
|
||||
{
|
||||
if (m_Mode == Mode.Recording)
|
||||
StopRecording();
|
||||
else if (m_Mode == Mode.Control)
|
||||
StartRecording();
|
||||
}
|
||||
|
||||
if (WasKeyPressed(PlayKey) && m_Mode == Mode.Control && HasRecording)
|
||||
StartPlayback();
|
||||
|
||||
if (WasKeyPressed(StopPlaybackKey) && m_Mode == Mode.Playback)
|
||||
StopPlayback();
|
||||
}
|
||||
|
||||
void ApplyMovement()
|
||||
{
|
||||
var delta = Speed * Time.deltaTime;
|
||||
|
||||
if (IsKeyHeld(KeyCode.A))
|
||||
transform.position += Vector3.left * delta;
|
||||
else if (IsKeyHeld(KeyCode.D))
|
||||
transform.position += Vector3.right * delta;
|
||||
else if (IsKeyHeld(KeyCode.W))
|
||||
transform.position += Vector3.forward * delta;
|
||||
else if (IsKeyHeld(KeyCode.S))
|
||||
transform.position += Vector3.back * delta;
|
||||
}
|
||||
|
||||
private IEnumerator TestCoroutine()
|
||||
{
|
||||
yield return new WaitForSeconds(2f);
|
||||
Debug.Log("TestCoroutine");
|
||||
}
|
||||
|
||||
void AdvancePlayback()
|
||||
{
|
||||
if (!HasRecording)
|
||||
{
|
||||
StopPlayback();
|
||||
return;
|
||||
}
|
||||
|
||||
transform.position = m_RecordedPositions[m_PlaybackFrameIndex];
|
||||
m_PlaybackFrameIndex++;
|
||||
|
||||
if (m_PlaybackFrameIndex < m_RecordedPositions.Count)
|
||||
return;
|
||||
|
||||
if (LoopPlayback)
|
||||
{
|
||||
m_PlaybackFrameIndex = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
StopPlayback();
|
||||
}
|
||||
|
||||
public void StartRecording()
|
||||
{
|
||||
if (m_Mode == Mode.Playback)
|
||||
return;
|
||||
|
||||
m_RecordedPositions.Clear();
|
||||
m_Mode = Mode.Recording;
|
||||
Debug.Log("[PlayerRecording] Recording started.");
|
||||
}
|
||||
|
||||
public void StopRecording()
|
||||
{
|
||||
if (m_Mode != Mode.Recording)
|
||||
return;
|
||||
|
||||
m_Mode = Mode.Control;
|
||||
Debug.Log($"[PlayerRecording] Recording stopped. Frames: {m_RecordedPositions.Count}");
|
||||
}
|
||||
|
||||
public void StartPlayback()
|
||||
{
|
||||
if (!HasRecording || m_Mode == Mode.Recording)
|
||||
return;
|
||||
|
||||
m_Mode = Mode.Playback;
|
||||
m_PlaybackFrameIndex = 0;
|
||||
transform.position = m_RecordedPositions[0];
|
||||
Debug.Log($"[PlayerRecording] Playback started. Frames: {m_RecordedPositions.Count}");
|
||||
}
|
||||
|
||||
public void StopPlayback()
|
||||
{
|
||||
if (m_Mode != Mode.Playback)
|
||||
return;
|
||||
|
||||
m_Mode = Mode.Control;
|
||||
m_PlaybackFrameIndex = 0;
|
||||
Debug.Log("[PlayerRecording] Playback stopped.");
|
||||
}
|
||||
|
||||
public void ClearRecording()
|
||||
{
|
||||
if (m_Mode == Mode.Playback)
|
||||
StopPlayback();
|
||||
|
||||
m_RecordedPositions.Clear();
|
||||
Debug.Log("[PlayerRecording] Recording cleared.");
|
||||
}
|
||||
|
||||
static bool IsKeyHeld(KeyCode keyCode)
|
||||
{
|
||||
#if ENABLE_INPUT_SYSTEM
|
||||
if (Keyboard.current == null)
|
||||
return false;
|
||||
|
||||
return keyCode switch
|
||||
{
|
||||
KeyCode.W => Keyboard.current.wKey.isPressed,
|
||||
KeyCode.A => Keyboard.current.aKey.isPressed,
|
||||
KeyCode.S => Keyboard.current.sKey.isPressed,
|
||||
KeyCode.D => Keyboard.current.dKey.isPressed,
|
||||
_ => Input.GetKey(keyCode)
|
||||
};
|
||||
#else
|
||||
return Input.GetKey(keyCode);
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool WasKeyPressed(KeyCode keyCode)
|
||||
{
|
||||
#if ENABLE_INPUT_SYSTEM
|
||||
if (Keyboard.current == null)
|
||||
return false;
|
||||
|
||||
return keyCode switch
|
||||
{
|
||||
KeyCode.W => Keyboard.current.wKey.wasPressedThisFrame,
|
||||
KeyCode.A => Keyboard.current.aKey.wasPressedThisFrame,
|
||||
KeyCode.S => Keyboard.current.sKey.wasPressedThisFrame,
|
||||
KeyCode.D => Keyboard.current.dKey.wasPressedThisFrame,
|
||||
KeyCode.R => Keyboard.current.rKey.wasPressedThisFrame,
|
||||
KeyCode.P => Keyboard.current.pKey.wasPressedThisFrame,
|
||||
KeyCode.Escape => Keyboard.current.escapeKey.wasPressedThisFrame,
|
||||
_ => Input.GetKeyDown(keyCode)
|
||||
};
|
||||
#else
|
||||
return Input.GetKeyDown(keyCode);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7f3c2a1b9e4d5f6081728394a5b6c7d8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user