_asdf
This commit is contained in:
@@ -4616,301 +4616,209 @@
|
||||
}
|
||||
// entity 10
|
||||
{
|
||||
"origin" "612 -512 72"
|
||||
"classname" "ammo_shells"
|
||||
}
|
||||
// entity 11
|
||||
{
|
||||
"origin" "668 -512 72"
|
||||
"classname" "ammo_bullets"
|
||||
}
|
||||
// entity 12
|
||||
{
|
||||
"origin" "128 -464 72"
|
||||
"classname" "item_health_mega"
|
||||
}
|
||||
// entity 13
|
||||
// entity 11
|
||||
{
|
||||
"classname" "weapon_rocketlauncher"
|
||||
"origin" "-384 -448 144"
|
||||
}
|
||||
// entity 14
|
||||
// entity 12
|
||||
{
|
||||
"classname" "item_armor_green"
|
||||
"origin" "-544 -304 144"
|
||||
}
|
||||
// entity 15
|
||||
// entity 13
|
||||
{
|
||||
"classname" "item_ammo_lightning"
|
||||
"origin" "-192 32 144"
|
||||
}
|
||||
// entity 16
|
||||
{
|
||||
"classname" "ammo_shells"
|
||||
"origin" "492 -128 376"
|
||||
}
|
||||
// entity 17
|
||||
// entity 14
|
||||
{
|
||||
"classname" "item_ammo_lightning"
|
||||
"origin" "436 -128 376"
|
||||
}
|
||||
// entity 18
|
||||
{
|
||||
"classname" "weapon_shotgun"
|
||||
"origin" "128 0 -48"
|
||||
}
|
||||
// entity 19
|
||||
// entity 15
|
||||
{
|
||||
"classname" "item_ammo_rockets"
|
||||
"origin" "56 -352 -48"
|
||||
}
|
||||
// entity 20
|
||||
// entity 16
|
||||
{
|
||||
"classname" "info_player_deathmatch"
|
||||
"origin" "-608 -304 152"
|
||||
}
|
||||
// entity 21
|
||||
// entity 17
|
||||
{
|
||||
"origin" "928 -552 144"
|
||||
"classname" "item_health_5"
|
||||
}
|
||||
// entity 22
|
||||
// entity 18
|
||||
{
|
||||
"origin" "144 -352 -40"
|
||||
"angle" "90"
|
||||
"classname" "info_player_deathmatch"
|
||||
}
|
||||
// entity 23
|
||||
// entity 19
|
||||
{
|
||||
"classname" "item_health_25"
|
||||
"origin" "784 -224 144"
|
||||
}
|
||||
// entity 24
|
||||
// entity 20
|
||||
{
|
||||
"classname" "item_health_25"
|
||||
"origin" "-32 -96 -48"
|
||||
}
|
||||
// entity 25
|
||||
// entity 21
|
||||
{
|
||||
"classname" "info_player_deathmatch"
|
||||
"angle" "225"
|
||||
"origin" "776 12 384"
|
||||
}
|
||||
// entity 26
|
||||
// entity 22
|
||||
{
|
||||
"angle" "315"
|
||||
"classname" "info_player_deathmatch"
|
||||
"origin" "-116 356 152"
|
||||
}
|
||||
// entity 27
|
||||
// entity 23
|
||||
{
|
||||
"classname" "weapon_grenadelauncher"
|
||||
"origin" "928 -448 144"
|
||||
}
|
||||
// entity 28
|
||||
// entity 24
|
||||
{
|
||||
"classname" "item_ammo_rockets"
|
||||
"origin" "776 -520 376"
|
||||
}
|
||||
// entity 29
|
||||
// entity 25
|
||||
{
|
||||
"classname" "weapon_lightning"
|
||||
"origin" "-228 288 320"
|
||||
}
|
||||
// entity 30
|
||||
// entity 26
|
||||
{
|
||||
"origin" "368 120 152"
|
||||
"angle" "270"
|
||||
"targetname" "upper_sg"
|
||||
"classname" "info_teleport_destination"
|
||||
}
|
||||
// entity 31
|
||||
// entity 27
|
||||
{
|
||||
"origin" "160 -464 376"
|
||||
"classname" "weapon_stake"
|
||||
}
|
||||
// entity 32
|
||||
// entity 28
|
||||
{
|
||||
"origin" "448 32 376"
|
||||
"classname" "weapon_rocketlauncher"
|
||||
}
|
||||
// entity 33
|
||||
// entity 29
|
||||
{
|
||||
"origin" "148 312 448"
|
||||
"targetname" "jump1"
|
||||
"classname" "target_position"
|
||||
}
|
||||
// entity 34
|
||||
// entity 30
|
||||
{
|
||||
"origin" "980 -160 152"
|
||||
"angle" "180"
|
||||
"classname" "info_player_deathmatch"
|
||||
}
|
||||
// entity 35
|
||||
// entity 31
|
||||
{
|
||||
"origin" "-144 -184 144"
|
||||
"classname" "item_health_25"
|
||||
}
|
||||
// entity 36
|
||||
// entity 32
|
||||
{
|
||||
"spawnflags" "0"
|
||||
"classname" "item_health_25"
|
||||
"origin" "320 -464 376"
|
||||
}
|
||||
// entity 37
|
||||
// entity 33
|
||||
{
|
||||
"classname" "item_health_5"
|
||||
"origin" "928 -504 144"
|
||||
}
|
||||
// entity 38
|
||||
// entity 34
|
||||
{
|
||||
"classname" "item_health_5"
|
||||
"origin" "928 -344 144"
|
||||
}
|
||||
// entity 39
|
||||
// entity 35
|
||||
{
|
||||
"classname" "info_player_deathmatch"
|
||||
"angle" "90"
|
||||
"origin" "-384 -130 368"
|
||||
}
|
||||
// entity 40
|
||||
// entity 36
|
||||
{
|
||||
"origin" "928 -392 144"
|
||||
"classname" "item_health_5"
|
||||
}
|
||||
// entity 41
|
||||
// entity 37
|
||||
{
|
||||
"origin" "-324 -304 152"
|
||||
"targetname" "25armour"
|
||||
"classname" "info_teleport_destination"
|
||||
"angle" "180"
|
||||
}
|
||||
// entity 42
|
||||
// entity 38
|
||||
{
|
||||
"classname" "info_teleport_destination"
|
||||
"targetname" "rg"
|
||||
"origin" "16 -464 384"
|
||||
}
|
||||
// entity 43
|
||||
// entity 39
|
||||
{
|
||||
"classname" "item_ammo_stakes"
|
||||
"origin" "400 -128 144"
|
||||
}
|
||||
// entity 44
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "224 -464 220"
|
||||
}
|
||||
// entity 45
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "32 -464 220"
|
||||
}
|
||||
// entity 46
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "432 -464 196"
|
||||
}
|
||||
// entity 47
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "816 -656 272"
|
||||
}
|
||||
// entity 48
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "624 -48 288"
|
||||
}
|
||||
// entity 49
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "656 -464 280"
|
||||
}
|
||||
// entity 50
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "-560 -304 284"
|
||||
}
|
||||
// entity 51
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "-160 304 388"
|
||||
}
|
||||
// entity 52
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "96 312 492"
|
||||
}
|
||||
// entity 53
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "448 0 492"
|
||||
}
|
||||
// entity 54
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "712 -120 492"
|
||||
}
|
||||
// entity 55
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "432 -464 486"
|
||||
}
|
||||
// entity 56
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "256 -464 532"
|
||||
}
|
||||
// entity 57
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "-384 -104 416"
|
||||
}
|
||||
// entity 58
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "-384 -96 384"
|
||||
"_color" "0.85 0.2 0.2"
|
||||
"light" "200"
|
||||
"radius" "32"
|
||||
}
|
||||
// entity 59
|
||||
// entity 40
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "120 536 496"
|
||||
}
|
||||
// entity 60
|
||||
// entity 41
|
||||
{
|
||||
"classname" "item_armor_green"
|
||||
"origin" "944 0 144"
|
||||
}
|
||||
// entity 42
|
||||
{
|
||||
"classname" "item_health_50"
|
||||
"origin" "128 544 376"
|
||||
}
|
||||
// entity 43
|
||||
{
|
||||
"classname" "target_position"
|
||||
"origin" "160 40 504"
|
||||
"targetname" "light_target1"
|
||||
}
|
||||
// entity 44
|
||||
{
|
||||
"classname" "info_player_deathmatch"
|
||||
"origin" "-496 -304 152"
|
||||
"angle" "180"
|
||||
}
|
||||
// entity 45
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "704 -448 492"
|
||||
"origin" "-136 0 284"
|
||||
}
|
||||
// entity 61
|
||||
// entity 46
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "64 -464 532"
|
||||
"origin" "-384 -104 416"
|
||||
}
|
||||
// entity 62
|
||||
// entity 47
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "-384 -304 284"
|
||||
"origin" "-560 -304 284"
|
||||
}
|
||||
// entity 63
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "432 -464 96"
|
||||
"_color" "0.752941 0.752941 0"
|
||||
"light" "200"
|
||||
"radius" "32"
|
||||
}
|
||||
// entity 64
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "944 0 168"
|
||||
"_color" "0 0.752941 0"
|
||||
"light" "200"
|
||||
"radius" "32"
|
||||
}
|
||||
// entity 65
|
||||
// entity 48
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "-544 -304 168"
|
||||
@@ -4918,40 +4826,25 @@
|
||||
"light" "200"
|
||||
"radius" "32"
|
||||
}
|
||||
// entity 66
|
||||
// entity 49
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "424 0 252"
|
||||
"origin" "-384 -304 284"
|
||||
}
|
||||
// entity 67
|
||||
// entity 50
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "-136 0 284"
|
||||
}
|
||||
// entity 68
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "64 -348 24"
|
||||
}
|
||||
// entity 69
|
||||
{
|
||||
"classname" "item_armor_green"
|
||||
"origin" "944 0 144"
|
||||
}
|
||||
// entity 70
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "128 -464 96"
|
||||
"_color" "0 0 0.752941"
|
||||
"origin" "-384 -96 384"
|
||||
"_color" "0.85 0.2 0.2"
|
||||
"light" "200"
|
||||
"radius" "32"
|
||||
}
|
||||
// entity 71
|
||||
// entity 51
|
||||
{
|
||||
"classname" "item_health_50"
|
||||
"origin" "128 544 376"
|
||||
"classname" "light"
|
||||
"origin" "96 312 492"
|
||||
}
|
||||
// entity 72
|
||||
// entity 52
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "160 144 592"
|
||||
@@ -4959,15 +4852,122 @@
|
||||
"radius" "0"
|
||||
"light" "600"
|
||||
}
|
||||
// entity 53
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "-160 304 388"
|
||||
}
|
||||
// entity 54
|
||||
{
|
||||
"origin" "612 -512 72"
|
||||
"classname" "ammo_shells"
|
||||
}
|
||||
// entity 55
|
||||
{
|
||||
"origin" "668 -512 72"
|
||||
"classname" "ammo_bullets"
|
||||
}
|
||||
// entity 56
|
||||
{
|
||||
"classname" "ammo_shells"
|
||||
"origin" "492 -128 376"
|
||||
}
|
||||
// entity 57
|
||||
{
|
||||
"classname" "weapon_shotgun"
|
||||
"origin" "128 0 -48"
|
||||
}
|
||||
// entity 58
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "224 -464 220"
|
||||
}
|
||||
// entity 59
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "32 -464 220"
|
||||
}
|
||||
// entity 60
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "432 -464 196"
|
||||
}
|
||||
// entity 61
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "816 -656 272"
|
||||
}
|
||||
// entity 62
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "624 -48 288"
|
||||
}
|
||||
// entity 63
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "656 -464 280"
|
||||
}
|
||||
// entity 64
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "448 0 492"
|
||||
}
|
||||
// entity 65
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "712 -120 492"
|
||||
}
|
||||
// entity 66
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "432 -464 486"
|
||||
}
|
||||
// entity 67
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "256 -464 532"
|
||||
}
|
||||
// entity 68
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "704 -448 492"
|
||||
}
|
||||
// entity 69
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "64 -464 532"
|
||||
}
|
||||
// entity 70
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "432 -464 96"
|
||||
"_color" "0.752941 0.752941 0"
|
||||
"light" "200"
|
||||
"radius" "32"
|
||||
}
|
||||
// entity 71
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "944 0 168"
|
||||
"_color" "0 0.752941 0"
|
||||
"light" "200"
|
||||
"radius" "32"
|
||||
}
|
||||
// entity 72
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "424 0 252"
|
||||
}
|
||||
// entity 73
|
||||
{
|
||||
"classname" "target_position"
|
||||
"origin" "160 40 504"
|
||||
"targetname" "light_target1"
|
||||
"classname" "light"
|
||||
"origin" "64 -348 24"
|
||||
}
|
||||
// entity 74
|
||||
{
|
||||
"classname" "info_player_deathmatch"
|
||||
"origin" "-496 -304 152"
|
||||
"angle" "180"
|
||||
"classname" "light"
|
||||
"origin" "128 -464 96"
|
||||
"_color" "0 0 0.752941"
|
||||
"light" "200"
|
||||
"radius" "32"
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"ID": "194e05f445ece24ec5448d886e1334df",
|
||||
"TypeName": "FlaxEngine.SceneAsset",
|
||||
"EngineBuild": 6601,
|
||||
"EngineBuild": 6605,
|
||||
"Data": [
|
||||
{
|
||||
"ID": "194e05f445ece24ec5448d886e1334df",
|
||||
@@ -27,6 +27,12 @@
|
||||
"X": 3.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.0
|
||||
},
|
||||
"Orientation": {
|
||||
"X": 0.13052625954151154,
|
||||
"Y": -1.6762705001838186e-7,
|
||||
"Z": -1.6762705001838186e-7,
|
||||
"W": 0.9914449453353882
|
||||
}
|
||||
},
|
||||
"V": {}
|
||||
@@ -51,7 +57,7 @@
|
||||
}
|
||||
},
|
||||
"Data": {
|
||||
"Text": "0 tris\n 0 drawcalls\r\n262fps2\r\n285fps"
|
||||
"Text": "0 tris\n 0 drawcalls\r\n10fps2\r\n10fps"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -68,6 +74,13 @@
|
||||
"TypeName": "FlaxEngine.UIControl",
|
||||
"ParentID": "ff6b6db54b5aa08e7286ef86246149ef",
|
||||
"Name": "CrosshairWidget",
|
||||
"Transform": {
|
||||
"Translation": {
|
||||
"X": 11.0,
|
||||
"Y": 8.0,
|
||||
"Z": 0.0
|
||||
}
|
||||
},
|
||||
"Control": "FlaxEngine.GUI.Image",
|
||||
"Data": {
|
||||
"Brush": {
|
||||
@@ -110,10 +123,10 @@
|
||||
"Y": 1.0
|
||||
},
|
||||
"Offsets": {
|
||||
"Left": 0.0,
|
||||
"Right": 0.0,
|
||||
"Top": 0.0,
|
||||
"Bottom": 0.0
|
||||
"Left": 11.0,
|
||||
"Right": -11.0,
|
||||
"Top": 8.0,
|
||||
"Bottom": -8.0
|
||||
},
|
||||
"Scale": {
|
||||
"X": 1.0,
|
||||
@@ -134,6 +147,7 @@
|
||||
"B": 0.0,
|
||||
"A": 0.0
|
||||
},
|
||||
"BackgroundBrush": null,
|
||||
"Enabled": true,
|
||||
"Visible": true,
|
||||
"AutoFocus": false
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
{
|
||||
"ID": "af2e52554f7faed7b4937181dd22d166",
|
||||
"TypeName": "FlaxEditor.Content.Settings.BuildSettings",
|
||||
"EngineBuild": 6340,
|
||||
"EngineBuild": 6605,
|
||||
"Data": {
|
||||
"OutputName": "${PROJECT_NAME}",
|
||||
"MaxAssetsPerPackage": 4096,
|
||||
"MaxPackageSizeMB": 1024,
|
||||
"ContentKey": 0,
|
||||
@@ -18,7 +19,9 @@
|
||||
],
|
||||
"ShadersNoOptimize": false,
|
||||
"ShadersGenerateDebugData": false,
|
||||
"SkipDotnetPackaging": true,
|
||||
"SkipDefaultFonts": false,
|
||||
"SkipDotnetPackaging": false,
|
||||
"SkipUnusedDotnetLibsPackaging": true,
|
||||
"Presets": [
|
||||
{
|
||||
"Name": "Preset 3",
|
||||
|
||||
Binary file not shown.
@@ -1,7 +1,7 @@
|
||||
// comment
|
||||
r_shadows 1
|
||||
r_lighting 1
|
||||
cl_maxfps 0
|
||||
cl_maxfps 240
|
||||
r_upscaling 0
|
||||
r_gi 0
|
||||
r_staticbatch 1
|
||||
@@ -145,11 +145,18 @@ public class ConsoleInputTextBox : ConsoleTextBoxBase
|
||||
|
||||
public override void OnLostFocus()
|
||||
{
|
||||
// Prevent caret location getting reset back to beginning
|
||||
// Prevent caret location getting reset back to beginning,
|
||||
// and submitting the value when focus is lost.
|
||||
bool oldEditing = _isEditing;
|
||||
_isEditing = false;
|
||||
base.OnLostFocus();
|
||||
_isEditing = oldEditing;
|
||||
try
|
||||
{
|
||||
base.OnLostFocus();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isEditing = oldEditing;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnMouseDown(Float2 location, MouseButton button)
|
||||
|
||||
54
Source/Game/GameMode/Messages/AcceptConnectionMessage.cs
Normal file
54
Source/Game/GameMode/Messages/AcceptConnectionMessage.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using FlaxEngine.Networking;
|
||||
using FlaxEngine;
|
||||
|
||||
namespace Game;
|
||||
|
||||
public struct AcceptConnectionMessage
|
||||
{
|
||||
public struct PlayerInfo
|
||||
{
|
||||
public uint PlayerId;
|
||||
public Float3 PlayerPosition;
|
||||
}
|
||||
public ulong Frame;
|
||||
public float GameTime;
|
||||
public PlayerInfo[] Players;
|
||||
|
||||
public static AcceptConnectionMessage Read(ref NetworkMessage networkMessage)
|
||||
{
|
||||
AcceptConnectionMessage packet = new AcceptConnectionMessage();
|
||||
packet.Frame = networkMessage.ReadUInt64();
|
||||
packet.GameTime = networkMessage.ReadSingle();
|
||||
int numActors = (int)networkMessage.ReadUInt32();
|
||||
|
||||
packet.Players = new PlayerInfo[numActors];
|
||||
for (int i = 0; i < numActors; i++)
|
||||
{
|
||||
packet.Players[i].PlayerId = networkMessage.ReadUInt32();
|
||||
packet.Players[i].PlayerPosition.X = networkMessage.ReadSingle();
|
||||
packet.Players[i].PlayerPosition.Y = networkMessage.ReadSingle();
|
||||
packet.Players[i].PlayerPosition.Z = networkMessage.ReadSingle();
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
public void Write(ref NetworkMessage networkMessage)
|
||||
{
|
||||
networkMessage.WriteByte((byte)GameModeMessageType2.AcceptConnection);
|
||||
networkMessage.WriteUInt64(Frame);
|
||||
networkMessage.WriteSingle(GameTime);
|
||||
networkMessage.WriteUInt32((uint)Players.Length);
|
||||
foreach (PlayerInfo player in Players)
|
||||
{
|
||||
networkMessage.WriteUInt32(player.PlayerId);
|
||||
networkMessage.WriteSingle(player.PlayerPosition.X);
|
||||
networkMessage.WriteSingle(player.PlayerPosition.Y);
|
||||
networkMessage.WriteSingle(player.PlayerPosition.Z);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using FlaxEngine.Networking;
|
||||
using FlaxEngine;
|
||||
|
||||
namespace Game;
|
||||
|
||||
public struct WelcomePlayerMessage
|
||||
{
|
||||
public struct PlayerInfo
|
||||
{
|
||||
public uint playerId;
|
||||
public Float3 playerPosition;
|
||||
}
|
||||
public ulong frame;
|
||||
public float time;
|
||||
public PlayerInfo[] players;
|
||||
|
||||
public static WelcomePlayerMessage Read(ref NetworkMessage networkMessage)
|
||||
{
|
||||
WelcomePlayerMessage packet = new WelcomePlayerMessage();
|
||||
packet.frame = networkMessage.ReadUInt64();
|
||||
packet.time = networkMessage.ReadSingle();
|
||||
int numActors = (int)networkMessage.ReadUInt32();
|
||||
|
||||
packet.players = new PlayerInfo[numActors];
|
||||
for (int i = 0; i < numActors; i++)
|
||||
{
|
||||
packet.players[i].playerId = networkMessage.ReadUInt32();
|
||||
packet.players[i].playerPosition.X = networkMessage.ReadSingle();
|
||||
packet.players[i].playerPosition.Y = networkMessage.ReadSingle();
|
||||
packet.players[i].playerPosition.Z = networkMessage.ReadSingle();
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
public void Write(ref NetworkMessage networkMessage)
|
||||
{
|
||||
networkMessage.WriteByte((byte)GameModeMessageType.WelcomePlayer);
|
||||
networkMessage.WriteUInt64(frame);
|
||||
networkMessage.WriteSingle(time);
|
||||
networkMessage.WriteUInt32((uint)players.Length);
|
||||
foreach (PlayerInfo player in players)
|
||||
{
|
||||
networkMessage.WriteUInt32(player.playerId);
|
||||
networkMessage.WriteSingle(player.playerPosition.X);
|
||||
networkMessage.WriteSingle(player.playerPosition.Y);
|
||||
networkMessage.WriteSingle(player.playerPosition.Z);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,8 @@ public enum NetworkMessageType : byte
|
||||
public static partial class NetworkManager
|
||||
{
|
||||
public delegate bool OnMessageDecl(ref NetworkEvent networkEvent);
|
||||
public delegate bool OnClientConnectingDecl(NetworkConnection sender);
|
||||
public delegate void OnClientConnectedDecl(NetworkConnection sender);
|
||||
|
||||
private static bool initialized;
|
||||
|
||||
@@ -45,28 +47,76 @@ public static partial class NetworkManager
|
||||
private static readonly ushort MaximumClients = 32;
|
||||
|
||||
private static List<OnMessageDecl> OnClientMessageDelegates = new(3);
|
||||
private static List<OnClientConnectingDecl> OnClientConnectingDelegates = new(3);
|
||||
private static List<OnClientConnectedDecl> OnClientConnectedDelegates = new(3);
|
||||
private static List<OnMessageDecl> OnServerMessageDelegates = new(3);
|
||||
private static List<OnClientConnectingDecl> OnServerConnectingDelegates = new(3);
|
||||
private static List<OnClientConnectedDecl> OnServerConnectedDelegates = new(3);
|
||||
|
||||
public static void RegisterClientMessageCallback(OnMessageDecl deleg)
|
||||
public static void RegisterClientCallbacks(OnMessageDecl onMessage, OnClientConnectingDecl onClientConnecting, OnClientConnectedDecl onClientConnected)
|
||||
{
|
||||
Assert.IsTrue(!OnClientMessageDelegates.Contains(deleg));
|
||||
OnClientMessageDelegates.Add(deleg);
|
||||
Assert.IsTrue(!OnClientMessageDelegates.Contains(onMessage));
|
||||
OnClientMessageDelegates.Add(onMessage);
|
||||
|
||||
if (onClientConnecting != null)
|
||||
{
|
||||
Assert.IsTrue(!OnClientConnectingDelegates.Contains(onClientConnecting));
|
||||
OnClientConnectingDelegates.Add(onClientConnecting);
|
||||
}
|
||||
if (onClientConnected != null)
|
||||
{
|
||||
Assert.IsTrue(!OnClientConnectedDelegates.Contains(onClientConnected));
|
||||
OnClientConnectedDelegates.Add(onClientConnected);
|
||||
}
|
||||
}
|
||||
public static void UnregisterClientMessageCallback(OnMessageDecl deleg)
|
||||
public static void UnregisterClientCallbacks(OnMessageDecl onMessage, OnClientConnectingDecl onClientConnecting, OnClientConnectedDecl onClientConnected)
|
||||
{
|
||||
Assert.IsTrue(OnClientMessageDelegates.Contains(deleg));
|
||||
OnClientMessageDelegates.Remove(deleg);
|
||||
Assert.IsTrue(OnClientMessageDelegates.Contains(onMessage));
|
||||
OnClientMessageDelegates.Remove(onMessage);
|
||||
|
||||
if (onClientConnecting != null)
|
||||
{
|
||||
Assert.IsTrue(OnClientConnectingDelegates.Contains(onClientConnecting));
|
||||
OnClientConnectingDelegates.Remove(onClientConnecting);
|
||||
}
|
||||
if (onClientConnected != null)
|
||||
{
|
||||
Assert.IsTrue(OnClientConnectedDelegates.Contains(onClientConnected));
|
||||
OnClientConnectedDelegates.Remove(onClientConnected);
|
||||
}
|
||||
}
|
||||
|
||||
public static void RegisterServerMessageCallback(OnMessageDecl deleg)
|
||||
public static void RegisterServerCallbacks(OnMessageDecl onMessage, OnClientConnectingDecl onClientConnecting, OnClientConnectedDecl onClientConnected)
|
||||
{
|
||||
Assert.IsTrue(!OnServerMessageDelegates.Contains(deleg));
|
||||
OnServerMessageDelegates.Add(deleg);
|
||||
Assert.IsTrue(!OnServerMessageDelegates.Contains(onMessage));
|
||||
OnServerMessageDelegates.Add(onMessage);
|
||||
|
||||
if (onClientConnecting != null)
|
||||
{
|
||||
Assert.IsTrue(!OnServerConnectingDelegates.Contains(onClientConnecting));
|
||||
OnServerConnectingDelegates.Add(onClientConnecting);
|
||||
}
|
||||
if (onClientConnected != null)
|
||||
{
|
||||
Assert.IsTrue(!OnServerConnectedDelegates.Contains(onClientConnected));
|
||||
OnServerConnectedDelegates.Add(onClientConnected);
|
||||
}
|
||||
}
|
||||
public static void UnregisterServerMessageCallback(OnMessageDecl deleg)
|
||||
public static void UnregisterServerCallbacks(OnMessageDecl onMessage, OnClientConnectingDecl onClientConnecting, OnClientConnectedDecl onClientConnected)
|
||||
{
|
||||
Assert.IsTrue(OnServerMessageDelegates.Contains(deleg));
|
||||
OnServerMessageDelegates.Remove(deleg);
|
||||
Assert.IsTrue(OnServerMessageDelegates.Contains(onMessage));
|
||||
OnServerMessageDelegates.Remove(onMessage);
|
||||
|
||||
if (onClientConnecting != null)
|
||||
{
|
||||
Assert.IsTrue(OnServerConnectingDelegates.Contains(onClientConnecting));
|
||||
OnServerConnectingDelegates.Remove(onClientConnecting);
|
||||
}
|
||||
if (onClientConnected != null)
|
||||
{
|
||||
Assert.IsTrue(OnServerConnectedDelegates.Contains(onClientConnected));
|
||||
OnServerConnectedDelegates.Remove(onClientConnected);
|
||||
}
|
||||
}
|
||||
|
||||
public static string DebugLastHandledMessage = "";
|
||||
@@ -129,22 +179,14 @@ public static partial class NetworkManager
|
||||
client = null;
|
||||
}
|
||||
|
||||
LocalPlayerClientId = 0;
|
||||
//LocalPlayerClientId = 0;
|
||||
|
||||
#if FLAX_EDITOR
|
||||
Editor.Instance.PlayModeEnd -= Cleanup;
|
||||
//GameModeManager.Cleanup(); // FIXME
|
||||
#endif
|
||||
if (clientWorldStateManager != null)
|
||||
{
|
||||
clientWorldStateManager.Cleanup();
|
||||
clientWorldStateManager = null;
|
||||
}
|
||||
if (serverWorldStateManager != null)
|
||||
{
|
||||
serverWorldStateManager.Cleanup();
|
||||
serverWorldStateManager = null;
|
||||
}
|
||||
World.CleanupClient();
|
||||
World.CleanupServer();
|
||||
|
||||
StopRecording();
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ public static partial class NetworkManager
|
||||
|
||||
public static INetworkDriver ClientNetworkDriver { get; set; }
|
||||
|
||||
public static WorldStateManager clientWorldStateManager = null;
|
||||
//public static WorldStateManager clientWorldStateManager = null;
|
||||
|
||||
public static bool ConnectServer(string serverAddress = "localhost", bool listenServer = false)
|
||||
{
|
||||
@@ -50,7 +50,7 @@ public static partial class NetworkManager
|
||||
}
|
||||
Debug.Log("Connected...");
|
||||
|
||||
if (!listenServer)
|
||||
/*if (!listenServer)
|
||||
{
|
||||
//WorldStateManager.Init();
|
||||
clientWorldStateManager = new WorldStateManager(isClient: true);
|
||||
@@ -58,7 +58,8 @@ public static partial class NetworkManager
|
||||
else
|
||||
{
|
||||
clientWorldStateManager = new WorldStateManager(isLocalClient: true);
|
||||
}
|
||||
}*/
|
||||
World.InitClient();
|
||||
|
||||
Scripting.FixedUpdate += OnClientNetworkUpdate;
|
||||
if (!listenServer)
|
||||
@@ -106,20 +107,20 @@ public static partial class NetworkManager
|
||||
{
|
||||
case NetworkEventType.Connected:
|
||||
{
|
||||
LocalPlayerClientId = networkEvent.Sender.ConnectionId;
|
||||
Console.Print("Connected to server, ConnectionId: " + networkEvent.Sender.ConnectionId);
|
||||
foreach (var func in OnClientConnectedDelegates)
|
||||
func(networkEvent.Sender);
|
||||
break;
|
||||
}
|
||||
case NetworkEventType.Disconnected:
|
||||
{
|
||||
Console.Print("Disconnected from server, timeout.");
|
||||
LocalPlayerClientId = 0;
|
||||
//LocalPlayerClientId = 0;
|
||||
break;
|
||||
}
|
||||
case NetworkEventType.Timeout:
|
||||
{
|
||||
Console.Print("Disconnected from server, connection closed.");
|
||||
LocalPlayerClientId = 0;
|
||||
//LocalPlayerClientId = 0;
|
||||
break;
|
||||
}
|
||||
case NetworkEventType.Message:
|
||||
|
||||
@@ -38,7 +38,8 @@ public static unsafe partial class NetworkManager
|
||||
{
|
||||
{
|
||||
Cleanup();
|
||||
clientWorldStateManager = new WorldStateManager(isServer: true);
|
||||
//clientWorldStateManager = new WorldStateManager(isServer: true);
|
||||
World.InitServer();
|
||||
}
|
||||
|
||||
if (!ReadDemo(demoName))
|
||||
|
||||
@@ -18,7 +18,7 @@ public static partial class NetworkManager
|
||||
|
||||
public static INetworkDriver ServerNetworkDriver { get; set; }
|
||||
|
||||
public static WorldStateManager serverWorldStateManager = null;
|
||||
//public static WorldStateManager serverWorldStateManager = null;
|
||||
|
||||
public static bool StartServer(bool listenServer = true)
|
||||
{
|
||||
@@ -82,8 +82,9 @@ public static partial class NetworkManager
|
||||
foreach (Type type in NetworkedTypes)
|
||||
Console.Print("tracking networked type: " + type.Name);
|
||||
#endif
|
||||
serverWorldStateManager = new WorldStateManager(isServer: true);
|
||||
//serverWorldStateManager = new WorldStateManager(isServer: true);
|
||||
//WorldStateManager.Init();
|
||||
World.InitServer();
|
||||
|
||||
if (listenServer)
|
||||
return ConnectServer(listenServer: true);
|
||||
@@ -139,13 +140,21 @@ public static partial class NetworkManager
|
||||
try
|
||||
{
|
||||
//IsServer = true;
|
||||
if (serverWorldStateManager.OnClientConnecting(networkEvent.Sender))
|
||||
bool handled = false;
|
||||
foreach (var func in OnServerConnectingDelegates)
|
||||
{
|
||||
handled = func(networkEvent.Sender);
|
||||
if (handled)
|
||||
break;
|
||||
}
|
||||
if (handled)
|
||||
{
|
||||
ConnectedClients.Add(networkEvent.Sender);
|
||||
Console.Print(
|
||||
$"Client({networkEvent.Sender.ConnectionId}) connected. Total clients: {ConnectedClients.Count}");
|
||||
|
||||
serverWorldStateManager.OnClientConnected(networkEvent.Sender);
|
||||
foreach (var func in OnServerConnectedDelegates)
|
||||
func(networkEvent.Sender);
|
||||
}
|
||||
else
|
||||
Console.Print($"Client({networkEvent.Sender.ConnectionId}) connection refused");
|
||||
|
||||
549
Source/Game/GameMode/World.cs
Normal file
549
Source/Game/GameMode/World.cs
Normal file
@@ -0,0 +1,549 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.Assertions;
|
||||
using FlaxEngine.Json;
|
||||
using FlaxEngine.Networking;
|
||||
|
||||
namespace Game;
|
||||
|
||||
public enum GameModeMessageType2 : byte
|
||||
{
|
||||
AcceptConnection, // AcceptConnectionMessage
|
||||
SpawnPlayer,
|
||||
PlayerInput,
|
||||
PlayerPosition, // world update
|
||||
PlayerSnapshot, // send world state delta to client since last client's acknowledged frame
|
||||
|
||||
LastMessageType = 128,
|
||||
}
|
||||
|
||||
public class World
|
||||
{
|
||||
protected class ClientInfo
|
||||
{
|
||||
public NetworkConnection Connection;
|
||||
public PlayerActor PlayerActor;
|
||||
public PlayerFrame[] FrameHistory = new PlayerFrame[120];
|
||||
|
||||
public ClientInfo()
|
||||
{
|
||||
for (int i = 0; i < FrameHistory.Length; i++)
|
||||
FrameHistory[i] = new PlayerFrame();
|
||||
}
|
||||
}
|
||||
|
||||
public class PlayerFrame
|
||||
{
|
||||
public ulong frame;
|
||||
public Float3 position;
|
||||
public PlayerInputState2 inputState;
|
||||
public PlayerMovementState movementState;
|
||||
}
|
||||
|
||||
public bool IsServer => this is ServerWorld;
|
||||
public bool IsClient => !IsServer;
|
||||
public ulong Frame { get; protected set; }
|
||||
public ulong ServerFrame { get; protected set; } // Last received frame from server
|
||||
public float GameTime { get; protected set; } // The join time
|
||||
public float GetFrameTime(ulong frame) => GameTime + (frame * (1.0f / Time.PhysicsFPS));
|
||||
|
||||
protected Scene _scene;
|
||||
protected Actor _worldSpawn;
|
||||
protected Dictionary<uint, ClientInfo> _clients = new();
|
||||
|
||||
public static void InitClient()
|
||||
{
|
||||
WorldStore.ClientWorld = new ClientWorld();
|
||||
WorldStore.ClientWorld.Init();
|
||||
}
|
||||
public static void InitServer()
|
||||
{
|
||||
WorldStore.ServerWorld = new ServerWorld();
|
||||
WorldStore.ServerWorld.Init();
|
||||
}
|
||||
public static void CleanupClient()
|
||||
{
|
||||
WorldStore.ClientWorld?.Cleanup();
|
||||
WorldStore.ClientWorld = null;
|
||||
}
|
||||
public static void CleanupServer()
|
||||
{
|
||||
WorldStore.ServerWorld?.Cleanup();
|
||||
WorldStore.ServerWorld = null;
|
||||
}
|
||||
|
||||
virtual protected void Init()
|
||||
{
|
||||
}
|
||||
|
||||
virtual protected void Cleanup()
|
||||
{
|
||||
//Level.SceneLoaded -= OnLevelLoaded;
|
||||
//Scripting.LateUpdate -= OnLateUpdatePre;
|
||||
Scripting.LateFixedUpdate -= OnLateUpdate;
|
||||
|
||||
if (_scene)
|
||||
{
|
||||
foreach (var player in _scene.GetChildren<PlayerActor>())
|
||||
{
|
||||
FlaxEngine.Object.Destroy(player);
|
||||
}
|
||||
if (Level.UnloadScene(_scene))
|
||||
throw new Exception("Failed to unload scene");
|
||||
_scene = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected void CreateScene(string sceneNamePrefix, string sceneGuid)
|
||||
{
|
||||
string physicsSceneName = $"{sceneNamePrefix}PhysicsScene";
|
||||
PhysicsScene localPhysicsScene = Physics.FindOrCreateScene(physicsSceneName);
|
||||
|
||||
Guid guid = JsonSerializer.ParseID(sceneGuid);
|
||||
string guidStr = JsonSerializer.GetStringID(guid);
|
||||
string sceneData = $@"
|
||||
{{
|
||||
""ID"": ""{guidStr}"",
|
||||
""TypeName"": ""FlaxEngine.SceneAsset"",
|
||||
""EngineBuild"": 65046,
|
||||
""Data"": [
|
||||
{{
|
||||
""ID"": ""{guidStr}"",
|
||||
""TypeName"": ""FlaxEngine.Scene"",
|
||||
""LightmapSettings"": {{
|
||||
""IndirectLightingIntensity"": 1.0,
|
||||
""GlobalObjectsScale"": 1.0,
|
||||
""ChartsPadding"": 3,
|
||||
""AtlasSize"": 1024,
|
||||
""BounceCount"": 1,
|
||||
""CompressLightmaps"": true,
|
||||
""UseGeometryWithNoMaterials"": true,
|
||||
""Quality"": 10
|
||||
}}
|
||||
}}
|
||||
]
|
||||
}}";
|
||||
|
||||
{
|
||||
var onSceneLoaded = (Scene loadedScene, Guid id) =>
|
||||
{
|
||||
if (guid == id)
|
||||
{
|
||||
loadedScene.PhysicsScene = localPhysicsScene;
|
||||
//scene = loadedScene;
|
||||
}
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
Level.SceneLoaded += onSceneLoaded;
|
||||
//Level.LoadScene(new SceneReference(guid));
|
||||
_scene = Level.LoadSceneFromBytes(Encoding.ASCII.GetBytes(sceneData));
|
||||
}
|
||||
finally
|
||||
{
|
||||
Level.SceneLoaded -= onSceneLoaded;
|
||||
}
|
||||
}
|
||||
Assert.IsTrue(_scene);
|
||||
|
||||
_scene.Name = $"{sceneNamePrefix}Scene";
|
||||
|
||||
//Level.SceneLoaded += OnLevelLoaded;
|
||||
Scripting.LateFixedUpdate += OnLateUpdate;
|
||||
|
||||
var importer = FlaxEngine.Object.New<Q3MapImporter>();
|
||||
importer.mapPath = @"C:\dev\GoakeFlax\Assets\Maps\aerowalk.map";
|
||||
importer.LoadCollidersOnly = sceneNamePrefix != "Client"; // FIXME
|
||||
importer.Parent = _scene;
|
||||
|
||||
//importer.Enabled = true;
|
||||
_worldSpawn = _scene.FindActor("WorldSpawn");// ?? Level.FindActor("WorldSpawn");
|
||||
Assert.IsTrue(_worldSpawn);
|
||||
}
|
||||
|
||||
public void OnLateUpdate()
|
||||
{
|
||||
Frame++;
|
||||
}
|
||||
|
||||
protected void OnClientConnected(NetworkConnection connection)
|
||||
{
|
||||
uint playerId = connection.ConnectionId;
|
||||
_clients.Add(playerId, new ClientInfo() { Connection = connection });
|
||||
}
|
||||
|
||||
virtual protected PlayerActor SpawnPlayer(uint playerId, Float3 position, Vector3 eulerAngles)
|
||||
{
|
||||
string prefabPath = Path.Combine(AssetManager.ContentPath, "Common");
|
||||
var playerPrefab = Content.Load<Prefab>(Path.Combine(prefabPath, "PlayerPrefab.prefab"));
|
||||
if (playerPrefab == null)
|
||||
Console.PrintError("GameModeManager: Failed to find PlayerPrefab");
|
||||
|
||||
PlayerActor playerActor = SpawnActor<PlayerActor>(playerPrefab);
|
||||
playerActor.Initialize(playerId, position, eulerAngles);
|
||||
//playerActor.Teleport(position, eulerAngles);
|
||||
|
||||
_clients[playerId].PlayerActor = playerActor;
|
||||
IPlayerInput playerInput = playerActor.GetScript<PlayerMovement>().Input;
|
||||
playerInput.SetFrame(Frame);
|
||||
/*if (IsServer)
|
||||
{
|
||||
serverWorldState.actors.Add(playerActor);
|
||||
if (!playerLastReceivedFrames.ContainsKey(playerId))
|
||||
playerLastReceivedFrames.Add(playerId, 0);
|
||||
}*/
|
||||
|
||||
return playerActor;
|
||||
}
|
||||
|
||||
protected T SpawnActor<T>(Prefab prefab) where T : Actor
|
||||
{
|
||||
T actor = PrefabManager.SpawnPrefab(prefab, _scene).As<T>();
|
||||
actor.PhysicsScene = _scene.PhysicsScene;
|
||||
return actor;
|
||||
}
|
||||
|
||||
virtual public bool IsLocalPlayer(uint playerId) => false;
|
||||
|
||||
public PlayerFrame GetPlayerFrame(uint playerId, ulong frame)
|
||||
{
|
||||
ClientInfo player = _clients[playerId];
|
||||
PlayerFrame playerFrame = player.FrameHistory[frame % 120];
|
||||
if (playerFrame.frame != frame)
|
||||
return null;
|
||||
|
||||
return playerFrame;
|
||||
}
|
||||
|
||||
public bool HasPlayerFrame(uint playerId, ulong frame) => GetPlayerFrame(playerId, frame) != null;
|
||||
|
||||
public bool GetPlayerInputState(uint playerId, ulong frame, out PlayerInputState2 inputState)
|
||||
{
|
||||
PlayerFrame playerFrame = GetPlayerFrame(playerId, frame);
|
||||
inputState = playerFrame?.inputState ?? default;
|
||||
return playerFrame != null;
|
||||
}
|
||||
}
|
||||
|
||||
file class ServerWorld : World
|
||||
{
|
||||
protected override void Init()
|
||||
{
|
||||
NetworkManager.RegisterServerCallbacks(OnMessage, OnClientConnecting, OnClientConnected);
|
||||
GameTime = Time.GameTime;
|
||||
|
||||
CreateScene("Server", "59dd37cc444d5d7015759389c6153c4c");
|
||||
|
||||
base.Init();
|
||||
}
|
||||
|
||||
protected override void Cleanup()
|
||||
{
|
||||
NetworkManager.UnregisterServerCallbacks(OnMessage, OnClientConnecting, OnClientConnected);
|
||||
base.Cleanup();
|
||||
}
|
||||
|
||||
public bool OnMessage(ref NetworkEvent networkEvent)
|
||||
{
|
||||
byte messageTypeByte = networkEvent.Message.ReadByte();
|
||||
if (!Enum.IsDefined(typeof(GameModeMessageType2), messageTypeByte))
|
||||
{
|
||||
//Console.PrintError($"GameModeManager: Unsupported message type received from client: {messageTypeByte}");
|
||||
return false;
|
||||
}
|
||||
|
||||
GameModeMessageType2 messageType = (GameModeMessageType2)messageTypeByte;
|
||||
NetworkManager.DebugLastHandledMessage = messageType.ToString();
|
||||
|
||||
//Console.Print($"GameModeManager: {messageType}");
|
||||
switch (messageType)
|
||||
{
|
||||
case GameModeMessageType2.AcceptConnection: // Client
|
||||
{
|
||||
AcceptConnectionMessage message = AcceptConnectionMessage.Read(ref networkEvent.Message);
|
||||
Frame += message.Frame;
|
||||
GameTime = message.GameTime;
|
||||
ServerFrame = message.Frame;
|
||||
|
||||
/*foreach (var player in message.Players)
|
||||
{
|
||||
SpawnPlayer(player.PlayerId, player.PlayerPosition, new Float3(0));
|
||||
|
||||
var playerFrames = new PlayerFrame[120];
|
||||
for (int j = 0; j < playerFrames.Length; j++)
|
||||
playerFrames[j] = new PlayerFrame();
|
||||
clientWorldState.playerFrameHistory.Add(player.PlayerId, playerFrames);
|
||||
}*/
|
||||
}
|
||||
break;
|
||||
case GameModeMessageType2.PlayerPosition:
|
||||
{
|
||||
//uint playerId = networkEvent.Sender.ConnectionId;
|
||||
PlayerInputState2 inputState; //?
|
||||
PlayerActorState actorState;
|
||||
|
||||
ulong receivedFrame = networkEvent.Message.ReadUInt64();
|
||||
uint reportedPlayerId = networkEvent.Message.ReadUInt32();
|
||||
actorState.position.X = networkEvent.Message.ReadSingle();
|
||||
actorState.position.Y = networkEvent.Message.ReadSingle();
|
||||
actorState.position.Z = networkEvent.Message.ReadSingle();
|
||||
actorState.velocity.X = networkEvent.Message.ReadSingle();
|
||||
actorState.velocity.Y = networkEvent.Message.ReadSingle();
|
||||
actorState.velocity.Z = networkEvent.Message.ReadSingle();
|
||||
/*actorState.orientation.X = networkEvent.Message.ReadSingle();
|
||||
actorState.orientation.Y = networkEvent.Message.ReadSingle();
|
||||
actorState.orientation.Z = networkEvent.Message.ReadSingle();
|
||||
actorState.orientation.W = networkEvent.Message.ReadSingle();*/
|
||||
actorState.viewAngles.X = networkEvent.Message.ReadSingle();
|
||||
actorState.viewAngles.Y = networkEvent.Message.ReadSingle();
|
||||
actorState.viewAngles.Z = networkEvent.Message.ReadSingle();
|
||||
actorState.lastJumpTime = networkEvent.Message.ReadSingle();
|
||||
actorState.numJumps = networkEvent.Message.ReadInt32();
|
||||
actorState.jumped = networkEvent.Message.ReadBoolean();
|
||||
|
||||
//inputState.frame = receivedFrame;
|
||||
inputState.ViewDelta.X = networkEvent.Message.ReadSingle();
|
||||
inputState.ViewDelta.Y = networkEvent.Message.ReadSingle();
|
||||
inputState.MoveForward = networkEvent.Message.ReadSingle();
|
||||
inputState.MoveRight = networkEvent.Message.ReadSingle();
|
||||
inputState.Attack = networkEvent.Message.ReadBoolean();
|
||||
inputState.Jump = networkEvent.Message.ReadBoolean();
|
||||
|
||||
ServerFrame = receivedFrame;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool OnClientConnecting(NetworkConnection connection)
|
||||
{
|
||||
AcceptConnectionMessage message = new AcceptConnectionMessage();
|
||||
message.Frame = Frame;
|
||||
message.GameTime = GameTime;
|
||||
message.Players = new AcceptConnectionMessage.PlayerInfo[_clients.Count];
|
||||
|
||||
int playerIndex = 0;
|
||||
foreach (var player in _clients.Values)
|
||||
{
|
||||
ref AcceptConnectionMessage.PlayerInfo playerInfo = ref message.Players[playerIndex];
|
||||
playerInfo.PlayerId = player.PlayerActor.GetScript<PlayerMovement>().PlayerId;
|
||||
playerInfo.PlayerPosition = player.PlayerActor.Position;
|
||||
playerIndex++;
|
||||
}
|
||||
NetworkMessage networkMessage = NetworkManager.ServerBeginSendMessage();
|
||||
message.Write(ref networkMessage);
|
||||
NetworkManager.ServerEndSendMessage(ref networkMessage, connection);
|
||||
return true;
|
||||
}
|
||||
|
||||
public new void OnClientConnected(NetworkConnection connection)
|
||||
{
|
||||
base.OnClientConnected(connection);
|
||||
uint playerId = connection.ConnectionId;
|
||||
|
||||
|
||||
var spawns = _worldSpawn.GetChildren<Actor>().Where(x => x.Name.StartsWith("PlayerSpawn_")).ToArray();
|
||||
Console.Print($"found {spawns.Length} spawns");
|
||||
|
||||
var randomSpawn = spawns.First();
|
||||
|
||||
Float3 position = randomSpawn.Position + new Float3(0f, 4.1f, 0f);
|
||||
Float3 eulerAngles = randomSpawn.Orientation.EulerAngles;
|
||||
|
||||
SpawnPlayer(playerId, position, eulerAngles);
|
||||
{
|
||||
NetworkMessage message = NetworkManager.ServerBeginSendMessage();
|
||||
message.WriteByte((byte)GameModeMessageType.SpawnPlayer);
|
||||
message.WriteUInt32(playerId);
|
||||
message.WriteUInt64(Frame);
|
||||
message.WriteSingle(position.X);
|
||||
message.WriteSingle(position.Y);
|
||||
message.WriteSingle(position.Z);
|
||||
message.WriteSingle(eulerAngles.X);
|
||||
message.WriteSingle(eulerAngles.Y);
|
||||
message.WriteSingle(eulerAngles.Z);
|
||||
NetworkManager.ServerEndSendMessage(ref message, connection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
file class ClientWorld : World
|
||||
{
|
||||
private uint _localPlayerId;
|
||||
|
||||
protected override void Init()
|
||||
{
|
||||
NetworkManager.RegisterClientCallbacks(OnMessage, null, OnClientConnected);
|
||||
|
||||
CreateScene("Client", "c095f9ac4989a46afd7fe3821f086e2e");
|
||||
|
||||
base.Init();
|
||||
}
|
||||
|
||||
protected override void Cleanup()
|
||||
{
|
||||
NetworkManager.UnregisterClientCallbacks(OnMessage, null, OnClientConnected);
|
||||
base.Cleanup();
|
||||
}
|
||||
|
||||
public bool OnMessage(ref NetworkEvent networkEvent)
|
||||
{
|
||||
byte messageTypeByte = networkEvent.Message.ReadByte();
|
||||
if (!Enum.IsDefined(typeof(GameModeMessageType2), messageTypeByte))
|
||||
{
|
||||
//Console.PrintError($"GameModeManager: Unsupported message type received from client: {messageTypeByte}");
|
||||
return false;
|
||||
}
|
||||
|
||||
GameModeMessageType2 messageType = (GameModeMessageType2)messageTypeByte;
|
||||
NetworkManager.DebugLastHandledMessage = messageType.ToString();
|
||||
|
||||
//Console.Print($"GameModeManager: {messageType}");
|
||||
switch (messageType)
|
||||
{
|
||||
case GameModeMessageType2.AcceptConnection:
|
||||
{
|
||||
// Setup some initial state for newly connected client
|
||||
AcceptConnectionMessage welcomePlayer = AcceptConnectionMessage.Read(ref networkEvent.Message);
|
||||
ServerFrame = welcomePlayer.Frame;
|
||||
Frame += welcomePlayer.Frame;
|
||||
|
||||
GameTime = welcomePlayer.GameTime;
|
||||
foreach (var playerInfo in welcomePlayer.Players)
|
||||
{
|
||||
_clients.Add(playerInfo.PlayerId, new ClientInfo());
|
||||
SpawnPlayer(playerInfo.PlayerId, playerInfo.PlayerPosition, new Float3(0));
|
||||
}
|
||||
|
||||
Console.Print("received welcome: frame " + ServerFrame);
|
||||
}
|
||||
break;
|
||||
case GameModeMessageType2.SpawnPlayer:
|
||||
{
|
||||
uint playerId = networkEvent.Message.ReadUInt32();
|
||||
ulong playerFrameIndex = networkEvent.Message.ReadUInt64();
|
||||
Float3 position = new Float3(networkEvent.Message.ReadSingle(), networkEvent.Message.ReadSingle(), networkEvent.Message.ReadSingle());
|
||||
Vector3 eulerAngles = new Float3(networkEvent.Message.ReadSingle(), networkEvent.Message.ReadSingle(), networkEvent.Message.ReadSingle());
|
||||
|
||||
/*if (!clientWorldState.playerFrameHistory.ContainsKey(playerId))
|
||||
{
|
||||
var playerFrames = new PlayerFrame[120];
|
||||
for (int j = 0; j < playerFrames.Length; j++)
|
||||
playerFrames[j] = new PlayerFrame();
|
||||
clientWorldState.playerFrameHistory.Add(playerId, playerFrames);
|
||||
}*/
|
||||
|
||||
SpawnPlayer(playerId, position, eulerAngles);
|
||||
|
||||
//if (NetworkManager.IsClient)
|
||||
//players[playerId].GetScript<PlayerMovement>().Input.SetFrame(ClientFrame);
|
||||
}
|
||||
break;
|
||||
#if false
|
||||
case GameModeMessageType2.PlayerPosition:
|
||||
{
|
||||
//uint playerId = networkEvent.Sender.ConnectionId;
|
||||
PlayerInputState2 inputState; //?
|
||||
PlayerActorState actorState;
|
||||
|
||||
ulong receivedFrame = networkEvent.Message.ReadUInt64();
|
||||
uint reportedPlayerId = networkEvent.Message.ReadUInt32();
|
||||
actorState.position.X = networkEvent.Message.ReadSingle();
|
||||
actorState.position.Y = networkEvent.Message.ReadSingle();
|
||||
actorState.position.Z = networkEvent.Message.ReadSingle();
|
||||
actorState.velocity.X = networkEvent.Message.ReadSingle();
|
||||
actorState.velocity.Y = networkEvent.Message.ReadSingle();
|
||||
actorState.velocity.Z = networkEvent.Message.ReadSingle();
|
||||
/*actorState.orientation.X = networkEvent.Message.ReadSingle();
|
||||
actorState.orientation.Y = networkEvent.Message.ReadSingle();
|
||||
actorState.orientation.Z = networkEvent.Message.ReadSingle();
|
||||
actorState.orientation.W = networkEvent.Message.ReadSingle();*/
|
||||
actorState.viewAngles.X = networkEvent.Message.ReadSingle();
|
||||
actorState.viewAngles.Y = networkEvent.Message.ReadSingle();
|
||||
actorState.viewAngles.Z = networkEvent.Message.ReadSingle();
|
||||
actorState.lastJumpTime = networkEvent.Message.ReadSingle();
|
||||
actorState.numJumps = networkEvent.Message.ReadInt32();
|
||||
actorState.jumped = networkEvent.Message.ReadBoolean();
|
||||
|
||||
//inputState.frame = receivedFrame;
|
||||
inputState.ViewDelta.X = networkEvent.Message.ReadSingle();
|
||||
inputState.ViewDelta.Y = networkEvent.Message.ReadSingle();
|
||||
inputState.MoveForward = networkEvent.Message.ReadSingle();
|
||||
inputState.MoveRight = networkEvent.Message.ReadSingle();
|
||||
inputState.Attack = networkEvent.Message.ReadBoolean();
|
||||
inputState.Jump = networkEvent.Message.ReadBoolean();
|
||||
|
||||
ServerFrame = receivedFrame;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool IsLocalPlayer(uint playerId) => playerId == _localPlayerId;
|
||||
|
||||
public new void OnClientConnected(NetworkConnection connection)
|
||||
{
|
||||
base.OnClientConnected(connection);
|
||||
_localPlayerId = connection.ConnectionId;
|
||||
Console.Print($"ClientWorld: Connected, playerId: {_localPlayerId}");
|
||||
}
|
||||
|
||||
protected override PlayerActor SpawnPlayer(uint playerId, Float3 position, Vector3 eulerAngles)
|
||||
{
|
||||
var playerActor = base.SpawnPlayer(playerId, position, eulerAngles);
|
||||
if (playerId == _localPlayerId)
|
||||
playerActor.Input = new PlayerInput2();
|
||||
else
|
||||
playerActor.Input = new PlayerInputNetwork2(playerId, this);
|
||||
return playerActor;
|
||||
}
|
||||
}
|
||||
|
||||
public static class WorldExtensions
|
||||
{
|
||||
public static World GetWorld(this Script script) => IsServerScene(script.Scene) ? WorldStore.ServerWorld : WorldStore.ClientWorld;
|
||||
|
||||
public static World GetWorld(this Actor actor) => IsServerScene(actor.Scene) ? WorldStore.ServerWorld : WorldStore.ClientWorld;
|
||||
|
||||
private static bool IsServerScene(Scene scene) => scene.Name == "ServerScene";
|
||||
}
|
||||
|
||||
file static class WorldStore
|
||||
{
|
||||
public static ServerWorld ServerWorld;
|
||||
public static ClientWorld ClientWorld;
|
||||
}
|
||||
|
||||
/*file class WorldPlugin : GamePlugin
|
||||
{
|
||||
public WorldPlugin()
|
||||
{
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
||||
WorldStore.ClientWorld = new World(isServer: false);
|
||||
}
|
||||
|
||||
public override void Deinitialize()
|
||||
{
|
||||
WorldStore.ServerWorld = null;
|
||||
WorldStore.ClientWorld = null;
|
||||
}
|
||||
}*/
|
||||
@@ -14,7 +14,7 @@ namespace Game;
|
||||
|
||||
public enum GameModeMessageType : byte
|
||||
{
|
||||
WelcomePlayer, // WelcomePlayerMessage
|
||||
AcceptConnection, // WelcomePlayerMessage
|
||||
SpawnPlayer,
|
||||
PlayerInput,
|
||||
PlayerPosition, // world update
|
||||
@@ -97,10 +97,10 @@ public class WorldStateManager
|
||||
clientWorldState = new WorldState();
|
||||
gameMode = new GameMode();
|
||||
|
||||
if (IsServer)
|
||||
NetworkManager.RegisterServerMessageCallback(OnMessage);
|
||||
/*if (IsServer)
|
||||
NetworkManager.RegisterServerCallbacks(OnMessage);
|
||||
else
|
||||
NetworkManager.RegisterClientMessageCallback(OnMessage);
|
||||
NetworkManager.RegisterClientCallbacks(OnMessage);*/
|
||||
|
||||
Debug.Log($"WorldStateManager Init is server: {IsServer}");
|
||||
Debug.Log($"WorldStateManager Init is local client: {IsLocalClient}");
|
||||
@@ -173,10 +173,10 @@ public class WorldStateManager
|
||||
|
||||
public void Cleanup()
|
||||
{
|
||||
if (IsServer)
|
||||
NetworkManager.UnregisterServerMessageCallback(OnMessage);
|
||||
/*if (IsServer)
|
||||
NetworkManager.UnregisterServerCallbacks(OnMessage);
|
||||
else
|
||||
NetworkManager.UnregisterClientMessageCallback(OnMessage);
|
||||
NetworkManager.UnregisterClientCallbacks(OnMessage);*/
|
||||
|
||||
Level.SceneLoaded -= OnLevelLoaded;
|
||||
//Scripting.LateUpdate -= OnLateUpdatePre;
|
||||
@@ -454,26 +454,26 @@ public class WorldStateManager
|
||||
//Console.Print($"GameModeManager: {messageType}");
|
||||
switch (messageType)
|
||||
{
|
||||
case GameModeMessageType.WelcomePlayer:
|
||||
case GameModeMessageType.AcceptConnection:
|
||||
{
|
||||
welcomed = true;
|
||||
if (IsClient || IsLocalClient)
|
||||
{
|
||||
WelcomePlayerMessage welcomePlayer = WelcomePlayerMessage.Read(ref networkEvent.Message);
|
||||
AcceptConnectionMessage welcomePlayer = AcceptConnectionMessage.Read(ref networkEvent.Message);
|
||||
if (!IsLocalClient)
|
||||
serverWorldState.frame = welcomePlayer.frame;
|
||||
serverWorldState.frame = welcomePlayer.Frame;
|
||||
//lastReceivedServerFrame = welcomePlayer.frame;
|
||||
clientWorldState.frame += welcomePlayer.frame;
|
||||
clientWorldState.frame += welcomePlayer.Frame;
|
||||
|
||||
ClientTime = welcomePlayer.time;
|
||||
foreach (var playerInfo in welcomePlayer.players)
|
||||
ClientTime = welcomePlayer.GameTime;
|
||||
foreach (var playerInfo in welcomePlayer.Players)
|
||||
{
|
||||
SpawnPlayer(playerInfo.playerId, playerInfo.playerPosition, new Float3(0));
|
||||
SpawnPlayer(playerInfo.PlayerId, playerInfo.PlayerPosition, new Float3(0));
|
||||
|
||||
var playerFrames = new PlayerFrame[120];
|
||||
for (int j = 0; j < playerFrames.Length; j++)
|
||||
playerFrames[j] = new PlayerFrame();
|
||||
clientWorldState.playerFrameHistory.Add(playerInfo.playerId, playerFrames);
|
||||
clientWorldState.playerFrameHistory.Add(playerInfo.PlayerId, playerFrames);
|
||||
}
|
||||
|
||||
Console.Print("received welcome: frame " + serverWorldState.frame);
|
||||
@@ -614,17 +614,17 @@ public class WorldStateManager
|
||||
//if (connection.ConnectionId != NetworkManager.LocalPlayerClientId)
|
||||
{
|
||||
Console.Print("sending welcome: frame " + serverWorldState.frame);
|
||||
WelcomePlayerMessage welcomeMessage = new WelcomePlayerMessage();
|
||||
welcomeMessage.frame = serverWorldState.frame;
|
||||
welcomeMessage.time = ServerTime;
|
||||
welcomeMessage.players = new WelcomePlayerMessage.PlayerInfo[serverWorldState.actors.Count];
|
||||
AcceptConnectionMessage welcomeMessage = new AcceptConnectionMessage();
|
||||
welcomeMessage.Frame = serverWorldState.frame;
|
||||
welcomeMessage.GameTime = ServerTime;
|
||||
welcomeMessage.Players = new AcceptConnectionMessage.PlayerInfo[serverWorldState.actors.Count];
|
||||
|
||||
for (int i = 0; i < serverWorldState.actors.Count; i++)
|
||||
{
|
||||
PlayerActor playerActor = serverWorldState.actors[i];
|
||||
ref WelcomePlayerMessage.PlayerInfo playerInfo = ref welcomeMessage.players[i];
|
||||
playerInfo.playerId = playerActor.GetScript<PlayerMovement>().PlayerId;
|
||||
playerInfo.playerPosition = playerActor.Position;
|
||||
ref AcceptConnectionMessage.PlayerInfo playerInfo = ref welcomeMessage.Players[i];
|
||||
playerInfo.PlayerId = playerActor.GetScript<PlayerMovement>().PlayerId;
|
||||
playerInfo.PlayerPosition = playerActor.Position;
|
||||
|
||||
/*playerActor.GetScript<PlayerMovement>().Input.SetState(serverWorldState.frame, new PlayerInputState(), new PlayerActorState()
|
||||
{
|
||||
|
||||
@@ -43,7 +43,12 @@ public class PlayerActor : RigidBody//, INetworkSerializable
|
||||
public MeshCollider meshCollider;
|
||||
|
||||
//[NetworkReplicated]
|
||||
public uint PlayerId = uint.MaxValue;
|
||||
public uint PlayerId { get; private set; } = uint.MaxValue;
|
||||
|
||||
public IPlayerInput Input { get; set; } = PlayerInputNone.Instance;
|
||||
|
||||
private World _world;
|
||||
private World World => _world ??= this.GetWorld();
|
||||
|
||||
/*public PlayerActor()
|
||||
{
|
||||
@@ -103,9 +108,9 @@ public class PlayerActor : RigidBody//, INetworkSerializable
|
||||
IsActive = true;
|
||||
|
||||
PlayerId = playerId;
|
||||
playerMovement.SetInput(playerId);
|
||||
//playerMovement.SetInput(playerId);
|
||||
bool isServerScene = Scene.Name == "ServerScene";
|
||||
if (playerId == NetworkManager.LocalPlayerClientId && !isServerScene)
|
||||
if (World.IsLocalPlayer(PlayerId))
|
||||
{
|
||||
FindActor("CameraHolder").IsActive = true;
|
||||
//FindActor("ViewModelHolder").IsActive = true;
|
||||
|
||||
@@ -84,21 +84,21 @@ public class PlayerInput2 : IPlayerInput
|
||||
public class PlayerInputNetwork2 : IPlayerInput
|
||||
{
|
||||
private uint _playerId;
|
||||
private WorldStateManager _worldStateManager;
|
||||
private World _world;
|
||||
private ulong _frame;
|
||||
private PlayerInputState2 _state;
|
||||
|
||||
public PlayerInputNetwork2(uint playerId, WorldStateManager worldStateManager)
|
||||
public PlayerInputNetwork2(uint playerId, World world)
|
||||
{
|
||||
_playerId = playerId;
|
||||
_worldStateManager = worldStateManager;
|
||||
_world = world;
|
||||
}
|
||||
|
||||
public void SetFrame(ulong frame) => _frame = frame;
|
||||
|
||||
public void UpdateState()
|
||||
{
|
||||
_worldStateManager.GetPlayerInputState(_playerId, _frame, out _state);
|
||||
_world.GetPlayerInputState(_playerId, _frame, out _state);
|
||||
}
|
||||
|
||||
public PlayerInputState2 GetState() => _state;
|
||||
@@ -107,4 +107,15 @@ public class PlayerInputNetwork2 : IPlayerInput
|
||||
{
|
||||
_state = new PlayerInputState2();
|
||||
}
|
||||
}
|
||||
|
||||
public class PlayerInputNone : IPlayerInput
|
||||
{
|
||||
public static PlayerInputNone Instance { get; } = new PlayerInputNone();
|
||||
private PlayerInputNone() { }
|
||||
|
||||
public PlayerInputState2 GetState() => default;
|
||||
public void ResetState() { }
|
||||
public void SetFrame(ulong frame) { }
|
||||
public void UpdateState() { }
|
||||
}
|
||||
@@ -107,7 +107,10 @@ public class PlayerMovement : Script
|
||||
private readonly bool demoDeltasVerify = true;
|
||||
|
||||
|
||||
private WorldStateManager worldStateManager;
|
||||
//private WorldStateManager worldStateManager;
|
||||
|
||||
private World _world;
|
||||
private World World => _world ??= this.GetWorld();
|
||||
|
||||
private bool predicting = false;
|
||||
|
||||
@@ -115,8 +118,8 @@ public class PlayerMovement : Script
|
||||
//public int currentInputFrame;
|
||||
//private int currentInputFrame2;
|
||||
|
||||
|
||||
public IPlayerInput Input;
|
||||
[NoSerialize, HideInEditor]
|
||||
public IPlayerInput Input => playerActor?.Input ?? PlayerInputNone.Instance;
|
||||
|
||||
//private bool physicsInteractions = false;
|
||||
|
||||
@@ -136,7 +139,7 @@ public class PlayerMovement : Script
|
||||
public Float3 viewAngles;
|
||||
private Float3 viewAnglesLastFrame;
|
||||
|
||||
public uint PlayerId = 0;
|
||||
public uint PlayerId => playerActor ? playerActor.PlayerId : 0;
|
||||
|
||||
[ReadOnly]
|
||||
public float CurrentVelocity
|
||||
@@ -161,7 +164,6 @@ public class PlayerMovement : Script
|
||||
{
|
||||
base.OnAwake();
|
||||
|
||||
Console.Print("player awake, playerid: " + PlayerId);
|
||||
rootActor = Actor.GetChild("RootActor");
|
||||
rigidBody = Actor.As<RigidBody>();
|
||||
playerActor = Actor.As<PlayerActor>();
|
||||
@@ -176,36 +178,6 @@ public class PlayerMovement : Script
|
||||
//rigidBody.TriggerExit += OnTriggerExit;
|
||||
}
|
||||
|
||||
public void SetInput(uint playerId)
|
||||
{
|
||||
//if (playerId == 0)
|
||||
// input = new PlayerInput();
|
||||
Assert.IsTrue(playerId != uint.MaxValue);
|
||||
|
||||
PlayerId = playerId;
|
||||
bool isServerScene = Scene.Name == "ServerScene";
|
||||
if (isServerScene)
|
||||
worldStateManager = NetworkManager.serverWorldStateManager;
|
||||
else
|
||||
worldStateManager = NetworkManager.clientWorldStateManager;
|
||||
|
||||
if (PlayerId == NetworkManager.LocalPlayerClientId && !isServerScene)//if (NetworkReplicator.GetObjectRole(this.Parent) == NetworkObjectRole.OwnedAuthoritative)// if (playerId == NetworkManager.LocalPlayerClientId)
|
||||
{
|
||||
Console.Print("local player?: " + playerId.ToString());
|
||||
//string demoPath = System.IO.Path.Combine(AssetManager.DemoPath, $"{DateTimeOffset.Now.UtcTicks}.gdem");
|
||||
//input = new PlayerInputLocal(playerActor, demoPath); // TODO: support recording
|
||||
Input = new PlayerInput2();//new PlayerInputLocal(playerActor);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.Print("network player: " + playerId.ToString());
|
||||
Input = new PlayerInputNetwork2(playerId, worldStateManager);
|
||||
|
||||
}
|
||||
Assert.IsTrue(worldStateManager != null);
|
||||
}
|
||||
|
||||
#if false
|
||||
public void SetInput(string demoFile)
|
||||
{
|
||||
@@ -286,7 +258,7 @@ public class PlayerMovement : Script
|
||||
//if (Input is PlayerInputDemo /*&& currentInputFrame2 >= currentInputFrame*/)
|
||||
// return;
|
||||
|
||||
Input.SetFrame(worldStateManager.Frame);
|
||||
Input.SetFrame(World.Frame);
|
||||
Input.UpdateState();
|
||||
|
||||
/*if (input.frame > 0)
|
||||
@@ -345,7 +317,107 @@ public class PlayerMovement : Script
|
||||
|
||||
//Input.OnFixedUpdate();
|
||||
PlayerInputState2 inputState = Input.GetState();
|
||||
bool predict = World.IsClient;
|
||||
if (predict)
|
||||
{
|
||||
// Get the latest frame we have predicted
|
||||
ulong lastFrame = World.ServerFrame;
|
||||
for (; lastFrame < World.Frame; lastFrame++)
|
||||
{
|
||||
if (!World.HasPlayerFrame(PlayerId, lastFrame))
|
||||
//if (!Input.GetState(currentFrame, out var pastInputState, out var pastActorState))
|
||||
{
|
||||
//Console.Print($"not predicting");
|
||||
predict = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (predict)
|
||||
{
|
||||
var oldAngles = viewAngles;
|
||||
var oldPos = movementState.position;
|
||||
var oldVel = movementState.currentVelocity;
|
||||
|
||||
ulong currentFrame = World.ServerFrame;
|
||||
if (currentFrame == World.ServerFrame)
|
||||
{
|
||||
// Reset all state to latest confirmed state from server
|
||||
var frameInfo = World.GetPlayerFrame(PlayerId, currentFrame);
|
||||
movementState.position = frameInfo.movementState.position;
|
||||
movementState.currentVelocity = frameInfo.movementState.currentVelocity;
|
||||
movementState.lastJumped = frameInfo.movementState.lastJumped;
|
||||
movementState.numJumps = frameInfo.movementState.numJumps;
|
||||
movementState.jumped = frameInfo.movementState.jumped;
|
||||
Actor.Position = movementState.position;
|
||||
SetCameraEulerAngles(frameInfo.movementState.viewAngles, true);
|
||||
//cameraHolder.Orientation = Quaternion.Euler(pastActorState.viewAngles.Y, pastActorState.viewAngles.X, pastActorState.viewAngles.Z);
|
||||
//ApplyInputToCamera(pastInputState, true);
|
||||
|
||||
//if (pastActorState.viewAngles != new Float3(90f, 0f, 0f))
|
||||
// Console.Print($"moved server frame: {currentFrame}, {pastActorState.viewAngles}");
|
||||
|
||||
currentFrame++;
|
||||
//rootActor.Orientation = pastActorState.orientation;
|
||||
//viewAngles = pastActorState.viewAngles;
|
||||
//viewAngles = new Float3(pastActorState.viewAngles.Y, pastActorState.viewAngles.X, pastActorState.viewAngles.Z);
|
||||
}
|
||||
|
||||
// Predict the frames since last received frame from server up to latest client frame
|
||||
predicting = true;
|
||||
for (; currentFrame < lastFrame; currentFrame++)
|
||||
{
|
||||
var frameInfo = World.GetPlayerFrame(PlayerId, currentFrame);
|
||||
if (frameInfo == null)
|
||||
{
|
||||
Console.Print($"unexpected predict failure: {currentFrame}");
|
||||
break;
|
||||
}
|
||||
|
||||
ApplyInputToCamera(frameInfo.inputState, true);
|
||||
SimulatePlayerMovement(frameInfo.inputState, frameInfo.frame);
|
||||
}
|
||||
predicting = false;
|
||||
|
||||
var posDelta = (movementState.position - oldPos);
|
||||
var velDelta = (movementState.currentVelocity - oldVel);
|
||||
if (posDelta.Length > 0.001)
|
||||
Console.Print($"mispredicted final position");
|
||||
if (velDelta.Length > 0.001)
|
||||
Console.Print($"mispredicted final velocity");
|
||||
|
||||
// Run simulation for the upcoming frame
|
||||
//if (input is not PlayerInputNetwork)
|
||||
{
|
||||
/*if ((movementState.position - oldPos).Length > 0.001)
|
||||
Console.Print($"mispredicted final position");
|
||||
if ((currentVelocity - oldVel).Length > 0.001)
|
||||
Console.Print($"mispredicted final velocity");*/
|
||||
|
||||
ApplyInputToCamera(inputState, true);
|
||||
|
||||
// Ensure orientation is always up-to-date after predicting
|
||||
//rootActor.Orientation = Quaternion.Euler(0, viewAngles.X, 0);
|
||||
cameraHolder.Orientation = Quaternion.Euler(viewAngles.Y, viewAngles.X, viewAngles.Z);
|
||||
|
||||
SimulatePlayerMovement(inputState, World.Frame); // MAYBE?
|
||||
}
|
||||
|
||||
var viewDelta = (viewAngles - oldAngles);
|
||||
if (viewDelta.Length > 0.001)
|
||||
Console.Print($"mispredicted final viewangles: {viewAngles} <- {oldAngles}");
|
||||
}
|
||||
}
|
||||
|
||||
if (!predict)
|
||||
{
|
||||
SetCameraEulerAngles(viewAnglesLastFrame, true);
|
||||
ApplyInputToCamera(inputState, true);
|
||||
SimulatePlayerMovement(inputState, World.Frame); // MAYBE?
|
||||
}
|
||||
|
||||
viewAnglesLastFrame = viewAngles;
|
||||
|
||||
#if false
|
||||
if (false && Input is PlayerInputNetwork2)
|
||||
{
|
||||
#if false
|
||||
@@ -456,12 +528,13 @@ public class PlayerMovement : Script
|
||||
|
||||
//viewAngles = viewAnglesLastFrame;
|
||||
bool canpredict = true;
|
||||
if (true /*&& Input.Predict*/ /*&& !NetworkManager.IsDemoPlaying*/ && worldStateManager.ClientFrame > 0 && worldStateManager.ServerFrame > 0)
|
||||
if (true /*&& Input.Predict*/ /*&& !NetworkManager.IsDemoPlaying*/ && World.Frame > 0 && World.ServerFrame > 0)
|
||||
{
|
||||
ulong currentFrame = worldStateManager.ServerFrame;
|
||||
for (; currentFrame < worldStateManager.ClientFrame; currentFrame++)
|
||||
// Get the latest frame we have predicted
|
||||
ulong currentFrame = World.ServerFrame;
|
||||
for (; currentFrame < World.Frame; currentFrame++)
|
||||
{
|
||||
if (!worldStateManager.HasPlayerFrame(PlayerId, currentFrame))
|
||||
if (!World.HasPlayerFrame(PlayerId, currentFrame))
|
||||
//if (!Input.GetState(currentFrame, out var pastInputState, out var pastActorState))
|
||||
{
|
||||
//Console.Print($"not predicting");
|
||||
@@ -471,22 +544,19 @@ public class PlayerMovement : Script
|
||||
}
|
||||
|
||||
ulong lastFrame = currentFrame;
|
||||
|
||||
|
||||
if (canpredict)
|
||||
{
|
||||
var oldAngles = viewAngles;
|
||||
var oldPos = movementState.position;
|
||||
var oldVel = movementState.currentVelocity;
|
||||
|
||||
|
||||
|
||||
// Predict the frames since last received frame from server up to latest client frame
|
||||
predicting = true;
|
||||
currentFrame = worldStateManager.ServerFrame;
|
||||
currentFrame = World.ServerFrame;
|
||||
for (; currentFrame < lastFrame; currentFrame++)
|
||||
{
|
||||
//if (!Input.GetState(currentFrame, out var pastInputState, out var pastActorState))
|
||||
var frameInfo = worldStateManager.GetPlayerFrame(PlayerId, currentFrame);
|
||||
var frameInfo = World.GetPlayerFrame(PlayerId, currentFrame);
|
||||
if (frameInfo == null)
|
||||
{
|
||||
Console.Print($"unexpected predict failure: {currentFrame}");
|
||||
@@ -496,7 +566,7 @@ public class PlayerMovement : Script
|
||||
//if (currentFrame == inputState.frame)
|
||||
// movementState.jumped = movementState.jumped;
|
||||
|
||||
if (currentFrame == worldStateManager.ServerFrame)
|
||||
if (currentFrame == World.ServerFrame)
|
||||
{
|
||||
movementState.position = frameInfo.movementState.position;
|
||||
movementState.currentVelocity = frameInfo.movementState.currentVelocity;
|
||||
@@ -563,7 +633,7 @@ public class PlayerMovement : Script
|
||||
//rootActor.Orientation = Quaternion.Euler(0, viewAngles.X, 0);
|
||||
cameraHolder.Orientation = Quaternion.Euler(viewAngles.Y, viewAngles.X, viewAngles.Z);
|
||||
|
||||
SimulatePlayerMovement(inputState, worldStateManager.Frame); // MAYBE?
|
||||
SimulatePlayerMovement(inputState, World.Frame); // MAYBE?
|
||||
}
|
||||
|
||||
var viewDelta = (viewAngles - oldAngles);
|
||||
@@ -585,7 +655,7 @@ public class PlayerMovement : Script
|
||||
{
|
||||
SetCameraEulerAngles(viewAnglesLastFrame, true);
|
||||
ApplyInputToCamera(inputState, true);
|
||||
SimulatePlayerMovement(inputState, worldStateManager.Frame); // MAYBE?
|
||||
SimulatePlayerMovement(inputState, World.Frame); // MAYBE?
|
||||
}
|
||||
|
||||
if (movementState.position.Length < 0.1)
|
||||
@@ -625,7 +695,7 @@ public class PlayerMovement : Script
|
||||
});*/
|
||||
|
||||
//Console.Print($"recording frame {input.frame}, client: {GameModeManager.ClientFrame}, server: {GameModeManager.ServerFrame}");
|
||||
worldStateManager.RecordPlayerInput(PlayerId, worldStateManager.Frame, inputState, movementState); // MAYBE?
|
||||
World.RecordPlayerInput(PlayerId, World.Frame, inputState, movementState); // MAYBE?
|
||||
Input.ResetState();
|
||||
}
|
||||
|
||||
@@ -649,6 +719,7 @@ public class PlayerMovement : Script
|
||||
currentVelocity = pastActorState2.velocity;
|
||||
SetCameraEulerAngles(pastActorState2.viewAngles, true);
|
||||
}*/
|
||||
#endif
|
||||
}
|
||||
|
||||
public void ApplyInputToCamera(PlayerInputState2 inputState, bool wrapAround = true)
|
||||
@@ -925,10 +996,10 @@ public class PlayerMovement : Script
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (worldStateManager.IsClient)
|
||||
else if (World.IsClient)
|
||||
{
|
||||
var serverBbox = boxCollider.OrientedBox.GetBoundingBox();
|
||||
var frameInfo = worldStateManager.GetPlayerFrame(PlayerId, worldStateManager.ServerFrame);
|
||||
var frameInfo = World.GetPlayerFrame(PlayerId, World.ServerFrame);
|
||||
if (frameInfo != null)
|
||||
serverBbox.Center = frameInfo.movementState.position;
|
||||
|
||||
@@ -1178,7 +1249,7 @@ public class PlayerMovement : Script
|
||||
|
||||
public void SimulatePlayerMovement(PlayerInputState2 inputState, ulong frame)
|
||||
{
|
||||
simulationTime = worldStateManager.ClientTime + (frame * (1.0f / Time.PhysicsFPS));
|
||||
simulationTime = World.GetFrameTime(frame);
|
||||
|
||||
Vector3 inputDirection =
|
||||
new Float3(inputState.MoveRight, 0.0f, inputState.MoveForward);
|
||||
|
||||
Reference in New Issue
Block a user