demo recording stuff

This commit is contained in:
GoaLitiuM
2021-11-07 20:26:21 +02:00
parent 484038c670
commit 65cc97a46c
14 changed files with 353 additions and 84 deletions

View File

@@ -0,0 +1,20 @@
// Game: Goake
// Format: Standard
// entity 0
{
"classname" "worldspawn"
"_tb_textures" "textures/common;textures/dev"
// brush 0
{
( 832 -0 -0 ) ( 832 0 -1 ) ( 832 1 -0 ) dev/dev_128_gray [ 1 0 0 0 ] [ 0 1 0 0 ] 0 1 1
( 877.8181762695312 0 0 ) ( 877.8181762695312 -1 0 ) ( 877.8181762695312 0 1 ) dev/dev_128_gray [ 1 0 0 0 ] [ 0 1 0 0 ] 0 1 1
( 0 -272 0 ) ( -1 -272 0 ) ( 0 -272 1 ) dev/dev_128_gray [ 1 0 0 0 ] [ 0 1 0 0 ] 0 1 1
( -0 -256 -0 ) ( 0 -256 -1 ) ( 1 -256 0 ) dev/dev_128_gray [ 1 0 0 0 ] [ 0 1 0 0 ] 0 1 1
( -0 -0 48 ) ( 0 -1 48 ) ( 1 -0 48 ) dev/dev_128_gray [ 1 0 0 0 ] [ 0 1 0 0 ] 0 1 1
( 0 0 106.90908813476562 ) ( -1 0 106.90908813476562 ) ( 0 1 106.90908813476562 ) dev/dev_128_gray [ 1 0 0 0 ] [ 0 1 0 0 ] 0 1 1
( 779.4157104492188 0 -179.8651580810547 ) ( 779.190850943327 0 -180.8395493030548 ) ( 779.4157104492188 0.9743912220001221 -179.8651580810547 ) dev/dev_128_gray [ 1 0 0 0 ] [ 0 1 0 0 ] 0 1 1
( 132.8000030517578 -0 -265.6000061035156 ) ( 131.9055758714676 0 -266.04721969366074 ) ( 132.8000030517578 0.8944271802902222 -265.6000061035156 ) dev/dev_128_gray [ 1 0 0 0 ] [ 0 1 0 0 ] 0 1 1
( 702.8965454101562 0 -301.2413635253906 ) ( 702.8965454101562 -0.9191450476646423 -301.2413635253906 ) ( 703.2904646992683 0 -300.322218477726 ) dev/dev_128_gray [ 1 0 0 0 ] [ 0 1 0 0 ] 0 1 1
( 68.79999542236328 0 -206.39999389648438 ) ( 68.79999542236328 -0.9486833214759827 -206.39999389648438 ) ( 69.74867874383926 0 -206.08376613259315 ) dev/dev_128_gray [ 1 0 0 0 ] [ 0 1 0 0 ] 0 1 1
}
}

View File

@@ -1,11 +1,11 @@
{
"ID": "3c7bc3854d42f9b1b0fea9ba0d7fa8e9",
"TypeName": "FlaxEditor.Content.Settings.GameSettings",
"EngineBuild": 6225,
"EngineBuild": 6226,
"Data": {
"ProductName": "Goake",
"CompanyName": "GoaLitiuM",
"CopyrightNotice": "ddc",
"CopyrightNotice": "",
"Icon": null,
"FirstScene": "194e05f445ece24ec5448d886e1334df",
"NoSplashScreen": true,
@@ -30,6 +30,7 @@
"XboxOnePlatform": null,
"XboxScarlettPlatform": null,
"AndroidPlatform": null,
"SwitchPlatform": null
"SwitchPlatform": null,
"PS5Platform": null
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,7 +1,7 @@
{
"ID": "194e05f445ece24ec5448d886e1334df",
"TypeName": "FlaxEngine.SceneAsset",
"EngineBuild": 6225,
"EngineBuild": 6226,
"Data": [
{
"ID": "194e05f445ece24ec5448d886e1334df",
@@ -23,55 +23,6 @@
"ParentID": "194e05f445ece24ec5448d886e1334df",
"V": {}
},
{
"ID": "6c66fa4a4a5de8998eb84388d1648317",
"PrefabID": "2d0e518b47d735c98312dd87cc42d6d7",
"PrefabObjectID": "999a202c47de967d2bdfd09abcc6df4e",
"ParentID": "194e05f445ece24ec5448d886e1334df"
},
{
"ID": "d5c84d67417ddf09908c76b6f0582b43",
"PrefabID": "2d0e518b47d735c98312dd87cc42d6d7",
"PrefabObjectID": "b29a58f545071ca393afaab21faa83ad",
"ParentID": "6c66fa4a4a5de8998eb84388d1648317",
"V": {}
},
{
"ID": "d1a76c334a514c99f8f5b2bd81abae2c",
"PrefabID": "2d0e518b47d735c98312dd87cc42d6d7",
"PrefabObjectID": "a67383834fc3f6f1106e8099e5557e32",
"ParentID": "6c66fa4a4a5de8998eb84388d1648317"
},
{
"ID": "357077e9405b2a7ba50198bbed8bd5f9",
"PrefabID": "2d0e518b47d735c98312dd87cc42d6d7",
"PrefabObjectID": "b8fc420f4efe96fa2b4042bd98fd3e74",
"ParentID": "d1a76c334a514c99f8f5b2bd81abae2c"
},
{
"ID": "905d23324e7f98c9f8287e8e49a83981",
"PrefabID": "2d0e518b47d735c98312dd87cc42d6d7",
"PrefabObjectID": "226bdb004e72848777178a9d1f207cbf",
"ParentID": "357077e9405b2a7ba50198bbed8bd5f9"
},
{
"ID": "89c02cd64b640185d9947ab451453c4c",
"PrefabID": "2d0e518b47d735c98312dd87cc42d6d7",
"PrefabObjectID": "8bd80bca49ac35da66aabaa2e473851d",
"ParentID": "6c66fa4a4a5de8998eb84388d1648317"
},
{
"ID": "eebdb91647732ad3dfc7528c978cd19c",
"PrefabID": "2d0e518b47d735c98312dd87cc42d6d7",
"PrefabObjectID": "d9d61d314ad79d49ba08059cef50f802",
"ParentID": "6c66fa4a4a5de8998eb84388d1648317"
},
{
"ID": "3e0f83fe407b2d9ed7c734a62fad0826",
"PrefabID": "2d0e518b47d735c98312dd87cc42d6d7",
"PrefabObjectID": "b377cc03418270d87e8a5b92cb5374ea",
"ParentID": "6c66fa4a4a5de8998eb84388d1648317"
},
{
"ID": "ff6b6db54b5aa08e7286ef86246149ef",
"TypeName": "FlaxEngine.UICanvas",
@@ -117,13 +68,13 @@
"Transform": {
"Translation": {
"X": 0.0,
"Y": 248.0,
"Y": 254.0,
"Z": 0.0
}
},
"Control": "FlaxEngine.GUI.Label",
"Data": {
"Text": "eFPS: 719\nuFPS: 650\nrFPS: 650\npFPS: 30\nCon: NaNms\nDirectX11\nGC memory: 15.66632MB",
"Text": "eFPS: 15\nuFPS: 15\nrFPS: 15\npFPS: 30\nCon: NaNms\nDirectX11\nGC memory: 12.47396MB",
"TextColor": {
"R": 1.0,
"G": 1.0,
@@ -170,9 +121,9 @@
},
"Offsets": {
"Left": 0.0,
"Right": 30948.0,
"Right": 143.0,
"Top": -562.0,
"Bottom": 576.0
"Bottom": 112.0
},
"Scale": {
"X": 1.0,
@@ -211,7 +162,7 @@
"Transform": {
"Translation": {
"X": 45644.0,
"Y": -1.0,
"Y": 2.0,
"Z": 0.0
}
},
@@ -306,6 +257,55 @@
},
"PostFxMaterials": {}
}
},
{
"ID": "6c66fa4a4a5de8998eb84388d1648317",
"PrefabID": "2d0e518b47d735c98312dd87cc42d6d7",
"PrefabObjectID": "999a202c47de967d2bdfd09abcc6df4e",
"ParentID": "194e05f445ece24ec5448d886e1334df"
},
{
"ID": "d5c84d67417ddf09908c76b6f0582b43",
"PrefabID": "2d0e518b47d735c98312dd87cc42d6d7",
"PrefabObjectID": "b29a58f545071ca393afaab21faa83ad",
"ParentID": "6c66fa4a4a5de8998eb84388d1648317",
"V": {}
},
{
"ID": "d1a76c334a514c99f8f5b2bd81abae2c",
"PrefabID": "2d0e518b47d735c98312dd87cc42d6d7",
"PrefabObjectID": "a67383834fc3f6f1106e8099e5557e32",
"ParentID": "6c66fa4a4a5de8998eb84388d1648317"
},
{
"ID": "357077e9405b2a7ba50198bbed8bd5f9",
"PrefabID": "2d0e518b47d735c98312dd87cc42d6d7",
"PrefabObjectID": "b8fc420f4efe96fa2b4042bd98fd3e74",
"ParentID": "d1a76c334a514c99f8f5b2bd81abae2c"
},
{
"ID": "905d23324e7f98c9f8287e8e49a83981",
"PrefabID": "2d0e518b47d735c98312dd87cc42d6d7",
"PrefabObjectID": "226bdb004e72848777178a9d1f207cbf",
"ParentID": "357077e9405b2a7ba50198bbed8bd5f9"
},
{
"ID": "89c02cd64b640185d9947ab451453c4c",
"PrefabID": "2d0e518b47d735c98312dd87cc42d6d7",
"PrefabObjectID": "8bd80bca49ac35da66aabaa2e473851d",
"ParentID": "6c66fa4a4a5de8998eb84388d1648317"
},
{
"ID": "eebdb91647732ad3dfc7528c978cd19c",
"PrefabID": "2d0e518b47d735c98312dd87cc42d6d7",
"PrefabObjectID": "d9d61d314ad79d49ba08059cef50f802",
"ParentID": "6c66fa4a4a5de8998eb84388d1648317"
},
{
"ID": "3e0f83fe407b2d9ed7c734a62fad0826",
"PrefabID": "2d0e518b47d735c98312dd87cc42d6d7",
"PrefabObjectID": "b377cc03418270d87e8a5b92cb5374ea",
"ParentID": "6c66fa4a4a5de8998eb84388d1648317"
}
]
}

View File

@@ -1,11 +1,11 @@
{
"ID": "a55dc3c04da4ea3744b7f1994565beac",
"TypeName": "FlaxEditor.Content.Settings.TimeSettings",
"EngineBuild": 6224,
"EngineBuild": 6226,
"Data": {
"UpdateFPS": 240.0,
"UpdateFPS": 120.0,
"PhysicsFPS": 120.0,
"DrawFPS": 240.0,
"DrawFPS": 120.0,
"TimeScale": 1.0,
"MaxUpdateDeltaTime": 0.1
}

View File

@@ -1,7 +1,7 @@
{
"ID": "4a5eec97484253fed72934860ae62c40",
"TypeName": "FlaxEditor.Content.Settings.WindowsPlatformSettings",
"EngineBuild": 6225,
"EngineBuild": 6226,
"Data": {
"WindowMode": 0,
"ScreenWidth": 1280,

View File

@@ -93,6 +93,7 @@ namespace Cabrito
sb.Append("\nGC memory: " + (GC.GetTotalMemory(false) / 1000000.0f).ToString() + "MB");
//sb.Append("\nUpdate profiler: " + updateProfTime.ToString() + "ms");
#if false
#if BUILD_DEVELOPMENT
var nameOffset = Marshal.OffsetOf(typeof(ProfilerCPU.Event), "Name0");
foreach (var eventsCpu in FlaxEngine.ProfilingTools.EventsCPU)
@@ -119,6 +120,7 @@ namespace Cabrito
}
}
#endif
#endif
((Label) control.Control).Text = sb.ToString();

189
Source/Game/PlayerInput.cs Normal file
View File

@@ -0,0 +1,189 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Runtime.InteropServices;
using FlaxEngine;
namespace Game
{
[StructLayout(LayoutKind.Sequential)]
public struct PlayerInputState
{
public float viewDeltaX, viewDeltaY;
public float moveForward;
public float moveRight;
public bool attacking;
public bool jumping;
}
[StructLayout(LayoutKind.Sequential)]
public struct PlayerActorState
{
public Vector3 position;
public Vector3 velocity;
public Quaternion orientation;
public float viewYaw, viewPitch, viewRoll;
}
[StructLayout(LayoutKind.Sequential)]
public struct PlayerState
{
public PlayerInputState input;
public PlayerActorState actor;
}
public class PlayerInput
{
public PlayerState lastState;
public PlayerState currentState;
public int frame;
private const byte DemoVer = 1;
private List<PlayerInputState> buffer = new List<PlayerInputState>();
private bool demoPlayback = false;
private bool demoRecording = true;
private string demoPath = @"C:\dev\GoakeFlax\testdemo.gdem";
public void OpenDemo()
{
if (!File.Exists(demoPath))
return;
T RawDeserialize<T>(byte[] rawData, int position)
{
int rawsize = Marshal.SizeOf(typeof(T));
if (rawsize > rawData.Length - position)
throw new ArgumentException("Not enough data to fill struct. Array length from position: "+(rawData.Length-position) + ", Struct length: "+rawsize);
IntPtr buffer = Marshal.AllocHGlobal(rawsize);
Marshal.Copy(rawData, position, buffer, rawsize);
T retobj = (T)Marshal.PtrToStructure(buffer, typeof(T));
Marshal.FreeHGlobal(buffer);
return retobj;
}
var stream = File.OpenRead(demoPath);
var ver = (int)stream.ReadByte();
if (ver != DemoVer)
{
Console.WriteLine("demover doesn't match: " + ver + " != " + DemoVer);
stream.Close();
return;
}
while (true)
{
var expectedSize = Marshal.SizeOf(typeof(PlayerInputState));
byte[] b = new byte[expectedSize];
var readBytes = stream.Read(b, 0, b.Length);
if (readBytes < expectedSize)
break;
buffer.Add(RawDeserialize<PlayerInputState>(b, 0));
}
Console.WriteLine("demo numstates: " + buffer.Count);
demoPlayback = true;
demoRecording = false;
}
public void OnUpdate()
{
lastState = currentState;
// Record camera angles here?
if (!demoPlayback)
{
currentState.input.viewDeltaX = InputManager.GetAxisRaw("Mouse X");
currentState.input.viewDeltaY = InputManager.GetAxisRaw("Mouse Y");
}
}
public void OnFixedUpdate()
{
// Record intent here
if (!demoPlayback)
{
currentState.input.moveForward = InputManager.GetAxis("Vertical");
currentState.input.moveRight = InputManager.GetAxis("Horizontal");
currentState.input.attacking = InputManager.GetAction("Attack");
currentState.input.jumping = InputManager.GetAction("Jump");
}
}
public void OnEndFrame()
{
if (demoRecording)
buffer.Add(currentState.input);
frame++;
if (demoPlayback)
{
if (frame < buffer.Count)
{
//var actorState = currentState.actor;
currentState.input = buffer[frame];
//currentState.actor = actorState;
}
else
{
Console.WriteLine("demo ended");
demoPlayback = false;
}
}
}
public void RecordCurrentActorState(PlayerActorState actorState)
{
currentState.actor = actorState;
}
public PlayerInputState GetCurrentInputState()
{
return currentState.input;
}
public PlayerActorState GetCurrentActorState()
{
return currentState.actor;
}
public void Flush()
{
if (!demoRecording)
return;
var stream = File.Open(demoPath, FileMode.Create, FileAccess.Write);
//stream.Position = 0;
//stream.SetLength(0);
stream.WriteByte(DemoVer);
byte[] RawSerialize(object anything)
{
int rawSize = Marshal.SizeOf(anything);
IntPtr buffer = Marshal.AllocHGlobal(rawSize);
Marshal.StructureToPtr(anything, buffer, false);
byte[] rawDatas = new byte[rawSize];
Marshal.Copy(buffer, rawDatas, 0, rawSize);
Marshal.FreeHGlobal(buffer);
return rawDatas;
}
foreach (var state in buffer)
{
var bytes = RawSerialize(state);
stream.Write(bytes, 0, bytes.Length * sizeof(byte));
}
stream.Close();
Debug.Write(LogType.Info, "demo, wrote states: " + buffer.Count);
}
}
}

View File

@@ -5,6 +5,7 @@ using System.Diagnostics;
using System.Threading.Tasks;
using FlaxEngine.Assertions;
using Console = Cabrito.Console;
using Debug = FlaxEngine.Debug;
using Object = FlaxEngine.Object;
namespace Game
@@ -45,11 +46,14 @@ namespace Game
private Actor rootActor;
private RigidBody rigidBody;
private PlayerInput input;
public override void OnAwake()
{
base.OnAwake();
input = new PlayerInput();
onExit.Triggered += () =>
{
if (Console.IsSafeToQuit)
@@ -62,6 +66,16 @@ namespace Game
//rigidBody.CollisionEnter += OnCollisionEnter;
//rigidBody.TriggerEnter += OnTriggerEnter;
//rigidBody.TriggerExit += OnTriggerExit;
input.OpenDemo();
}
public override void OnDisable()
{
base.OnDisable();
if (input != null)
input.Flush();
}
private List<PhysicsColliderActor> touchingActors = new List<PhysicsColliderActor>();
@@ -103,6 +117,68 @@ namespace Game
viewRoll = initialEulerAngles.Z;
}
public override void OnUpdate()
{
input.OnUpdate();
if (input.frame > 0)
{
PlayerActorState actorState = input.GetCurrentActorState();
Actor.Position = actorState.position;
currentVelocity = actorState.velocity;
viewYaw = actorState.viewYaw;
viewPitch = actorState.viewPitch;
viewRoll = actorState.viewRoll;
}
PlayerInputState inputState = input.GetCurrentInputState();
// Update camera view
float xAxis = inputState.viewDeltaX;
float yAxis = inputState.viewDeltaY;
if (xAxis != 0.0f || yAxis != 0.0f)
{
var camera = rootActor.GetChild<Camera>();
viewPitch = Mathf.Clamp(viewPitch + yAxis, -90.0f, 90.0f);
viewYaw += xAxis;
// root orientation must be set first
rootActor.Orientation = Quaternion.Euler(0, viewYaw, 0);
camera.Orientation = Quaternion.Euler(viewPitch, viewYaw, viewRoll);
}
input.RecordCurrentActorState(new PlayerActorState()
{
position = Actor.Position,
velocity = currentVelocity,
viewYaw = viewYaw,
viewPitch = viewPitch,
viewRoll = viewRoll
});
}
public override void OnFixedUpdate()
{
input.OnFixedUpdate();
PlayerInputState inputState = input.GetCurrentInputState();
SimulatePlayerMovement(inputState);
input.RecordCurrentActorState(new PlayerActorState()
{
position = Actor.Position,
velocity = currentVelocity,
viewYaw = viewYaw,
viewPitch = viewPitch,
viewRoll = viewRoll
});
input.OnEndFrame();
}
private bool SweepPlayerCollider(Vector3 start, Vector3 end, out RayCastHit[] hits)
{
Vector3 delta = end - start;
@@ -560,25 +636,6 @@ namespace Game
return slideMoveHit;
}
public override void OnUpdate()
{
float xAxis = InputManager.GetAxisRaw("Mouse X");
float yAxis = InputManager.GetAxisRaw("Mouse Y");
if (xAxis != 0.0f || yAxis != 0.0f)
{
var camera = rootActor.GetChild<Camera>();
viewPitch += yAxis;
viewYaw += xAxis;
viewPitch = Mathf.Clamp(viewPitch, -90.0f, 90.0f);
// root orientation must be set first
rootActor.Orientation = Quaternion.Euler(0, viewYaw, 0);
camera.Orientation = Quaternion.Euler(viewPitch, viewYaw, viewRoll);
}
}
[ReadOnly] public bool onGround = false;
/*
@@ -643,12 +700,12 @@ namespace Game
private Vector3 currentVelocity;
public override void OnFixedUpdate()
public void SimulatePlayerMovement(PlayerInputState inputState)
{
Transform rootTrans = rootActor.Transform;
Vector3 inputDirection =
new Vector3(InputManager.GetAxis("Horizontal"), 0.0f, InputManager.GetAxis("Vertical"));
new Vector3(inputState.moveRight, 0.0f, inputState.moveForward);
Vector3 moveDirection = rootTrans.TransformDirection(inputDirection);
Vector3 position = rigidBody.Position;
@@ -698,7 +755,7 @@ namespace Game
// TODO: snap to ground here
bool jumpAction = InputManager.GetAction("Jump");
bool jumpAction = inputState.jumping;
if (jumped && !jumpAction)
jumped = false; // jump released