From 22339f3795e27e664e1b5019b29a0e2491b38df0 Mon Sep 17 00:00:00 2001 From: Mister_Nebula <41904486+misternebula@users.noreply.github.com> Date: Fri, 7 May 2021 14:58:37 +0100 Subject: [PATCH] fix variable sync --- QNetWeaver/NetworkBehaviourProcessor.cs | 9 +- QSB/Animation/Player/AnimationSync.cs | 11 ++ .../FlamesAndBubbles/SetUpThrusterFlames.cs | 6 - .../Thrusters/JetpackAccelerationSync.cs | 38 +++++++ .../RemotePlayerParticlesController.cs | 12 ++ .../Thrusters/RemoteThrusterWashController.cs | 104 ++++++++++++++++++ .../Player/Thrusters/ThrusterManager.cs | 49 +++++++++ QSB/Player/PlayerInfo.cs | 2 + QSB/QSB.csproj | 5 +- QSB/QSBCore.cs | 4 +- QSB/QSBNetworkManager.cs | 2 + QuantumUNET/Components/QNetworkIdentity.cs | 3 + QuantumUNET/Messages/QMsgType.cs | 8 +- QuantumUNET/QNetworkBehaviour.cs | 3 +- QuantumUNET/QNetworkServer.cs | 7 +- 15 files changed, 241 insertions(+), 22 deletions(-) delete mode 100644 QSB/Animation/Player/Thrusters/FlamesAndBubbles/SetUpThrusterFlames.cs create mode 100644 QSB/Animation/Player/Thrusters/JetpackAccelerationSync.cs create mode 100644 QSB/Animation/Player/Thrusters/RemotePlayerParticlesController.cs create mode 100644 QSB/Animation/Player/Thrusters/RemoteThrusterWashController.cs create mode 100644 QSB/Animation/Player/Thrusters/ThrusterManager.cs diff --git a/QNetWeaver/NetworkBehaviourProcessor.cs b/QNetWeaver/NetworkBehaviourProcessor.cs index 28ccb63d..8166fe7f 100644 --- a/QNetWeaver/NetworkBehaviourProcessor.cs +++ b/QNetWeaver/NetworkBehaviourProcessor.cs @@ -1959,14 +1959,7 @@ namespace QNetWeaver var name = typeDefinition.Module.Name; if (name != Weaver.scriptDef.MainModule.Name && name != Weaver.UnityAssemblyDefinition.MainModule.Name && name != Weaver.QNetAssemblyDefinition.MainModule.Name && name != Weaver.corLib.Name && name != "System.Runtime.dll") { - Log.Error(string.Concat(new string[] - { - "SyncVar [", - fieldDefinition.FullName, - "] from ", - typeDefinition.Module.ToString(), - " cannot be a different module." - })); + Log.Error($"SyncVar [{fieldDefinition.FullName}] is from an inaccessible module! : [{name}]"); Weaver.fail = true; return; } diff --git a/QSB/Animation/Player/AnimationSync.cs b/QSB/Animation/Player/AnimationSync.cs index 17f0a158..c4b5669e 100644 --- a/QSB/Animation/Player/AnimationSync.cs +++ b/QSB/Animation/Player/AnimationSync.cs @@ -1,5 +1,6 @@ using OWML.Common; using OWML.Utils; +using QSB.Animation.Player.Thrusters; using QSB.Events; using QSB.Player; using QSB.Utility; @@ -94,6 +95,7 @@ namespace QSB.Animation.Player _playerController = body.parent.GetComponent(); InitCrouchSync(); + InitThrusters(); } public void InitRemote(Transform body) @@ -118,11 +120,20 @@ namespace QSB.Animation.Player SetAnimationType(AnimationType.PlayerUnsuited); InitCrouchSync(); + InitThrusters(); + ThrusterManager.CreateRemotePlayerVFX(Player); var ikSync = body.gameObject.AddComponent(); QSBCore.UnityEvents.RunWhen(() => Player.CameraBody != null, () => ikSync.Init(Player.CameraBody.transform)); } + private void InitThrusters() + { + Player.JetpackAcceleration = GetComponent(); + var thrusterModel = HasAuthority ? Locator.GetPlayerBody().GetComponent() : null; + Player.JetpackAcceleration.Init(thrusterModel); + } + private void InitCrouchSync() { _crouchSync = GetComponent(); diff --git a/QSB/Animation/Player/Thrusters/FlamesAndBubbles/SetUpThrusterFlames.cs b/QSB/Animation/Player/Thrusters/FlamesAndBubbles/SetUpThrusterFlames.cs deleted file mode 100644 index 54dab357..00000000 --- a/QSB/Animation/Player/Thrusters/FlamesAndBubbles/SetUpThrusterFlames.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace QSB.Animation.Player.Thrusters.FlamesAndBubbles -{ - internal class SetUpThrusterFlames - { - } -} diff --git a/QSB/Animation/Player/Thrusters/JetpackAccelerationSync.cs b/QSB/Animation/Player/Thrusters/JetpackAccelerationSync.cs new file mode 100644 index 00000000..31863a92 --- /dev/null +++ b/QSB/Animation/Player/Thrusters/JetpackAccelerationSync.cs @@ -0,0 +1,38 @@ +using QSB.Utility; +using QuantumUNET; +using QuantumUNET.Transport; +using System.Runtime.InteropServices; +using System.Text; +using UnityEngine; +using UnityEngine.Networking; + +namespace QSB.Animation.Player.Thrusters +{ + public class JetpackAccelerationSync : QNetworkBehaviour + { + [SyncVar] + private Vector3 _localAcceleration; + private ThrusterModel _thrusterModel; + + public Vector3 LocalAcceleration => _localAcceleration; + + public void Init(ThrusterModel model) + => _thrusterModel = model; + + public void Update() + { + if (IsLocalPlayer) + { + SyncLocalAccel(); + } + } + + private void SyncLocalAccel() + { + if (_thrusterModel != null) + { + _localAcceleration = _thrusterModel.GetLocalAcceleration(); + } + } + } +} diff --git a/QSB/Animation/Player/Thrusters/RemotePlayerParticlesController.cs b/QSB/Animation/Player/Thrusters/RemotePlayerParticlesController.cs new file mode 100644 index 00000000..274049e3 --- /dev/null +++ b/QSB/Animation/Player/Thrusters/RemotePlayerParticlesController.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; + +namespace QSB.Animation.Player.Thrusters +{ + class RemotePlayerParticlesController : MonoBehaviour + { + } +} diff --git a/QSB/Animation/Player/Thrusters/RemoteThrusterWashController.cs b/QSB/Animation/Player/Thrusters/RemoteThrusterWashController.cs new file mode 100644 index 00000000..ef055a87 --- /dev/null +++ b/QSB/Animation/Player/Thrusters/RemoteThrusterWashController.cs @@ -0,0 +1,104 @@ +using QSB.Player; +using QSB.Utility; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; + +namespace QSB.Animation.Player.Thrusters +{ + class RemoteThrusterWashController : MonoBehaviour + { + private float _raycastDistance = 10f; + private AnimationCurve _emissionDistanceScale; + private AnimationCurve _emissionThrusterScale; + private ParticleSystem _defaultParticleSystem; + + private ParticleSystem.MainModule _defaultMainModule; + private ParticleSystem.EmissionModule _defaultEmissionModule; + private float _baseDefaultEmissionRate; + + private PlayerInfo _attachedPlayer; + + private bool _isReady; + private bool _initialised; + + public void InitFromOld(AnimationCurve distanceScale, AnimationCurve thrusterScale, ParticleSystem defaultParticleSystem, PlayerInfo player) + { + DebugLog.DebugWrite($"InitFromOld for player {player.PlayerId}"); + _emissionDistanceScale = distanceScale; + _emissionThrusterScale = thrusterScale; + _defaultParticleSystem = defaultParticleSystem; + _attachedPlayer = player; + _isReady = true; + } + + private void Init() + { + DebugLog.DebugWrite($"Init for player {_attachedPlayer.PlayerId}"); + if (_defaultParticleSystem == null) + { + DebugLog.ToConsole($"Error - DefaultParticleSystem is null!", OWML.Common.MessageType.Error); + return; + } + else + { + DebugLog.DebugWrite($"DefaultParticleSystem OK."); + } + _defaultMainModule = _defaultParticleSystem.main; + _defaultEmissionModule = _defaultParticleSystem.emission; + _baseDefaultEmissionRate = _defaultEmissionModule.rateOverTime.constant; + _initialised = true; + } + + private void Update() + { + if (_isReady && !_initialised) + { + Init(); + } + + if (!_initialised) + { + return; + } + + RaycastHit hitInfo = default; + var aboveSurface = false; + var emissionThrusterScale = _emissionThrusterScale.Evaluate(_attachedPlayer.JetpackAcceleration.LocalAcceleration.y); + if (emissionThrusterScale > 0f) + { + aboveSurface = Physics.Raycast(transform.position, transform.forward, out hitInfo, _raycastDistance, OWLayerMask.physicalMask); + } + + emissionThrusterScale = (!aboveSurface) ? 0f : (emissionThrusterScale * _emissionDistanceScale.Evaluate(hitInfo.distance)); + + if (emissionThrusterScale > 0f) + { + var position = hitInfo.point + (hitInfo.normal * 0.25f); + var rotation = Quaternion.LookRotation(hitInfo.normal); + if (!_defaultParticleSystem.isPlaying) + { + DebugLog.DebugWrite($"{_attachedPlayer.PlayerId} play"); + _defaultParticleSystem.Play(); + } + _defaultEmissionModule.rateOverTimeMultiplier = _baseDefaultEmissionRate * emissionThrusterScale; + _defaultParticleSystem.transform.SetPositionAndRotation(position, rotation); + if (_defaultMainModule.customSimulationSpace != hitInfo.transform) + { + _defaultMainModule.customSimulationSpace = hitInfo.transform; + _defaultParticleSystem.Clear(); + } + } + else + { + if (_defaultParticleSystem.isPlaying) + { + DebugLog.DebugWrite($"{_attachedPlayer.PlayerId} stop"); + _defaultParticleSystem.Stop(false, ParticleSystemStopBehavior.StopEmitting); + } + } + } + } +} diff --git a/QSB/Animation/Player/Thrusters/ThrusterManager.cs b/QSB/Animation/Player/Thrusters/ThrusterManager.cs new file mode 100644 index 00000000..2d6d80dc --- /dev/null +++ b/QSB/Animation/Player/Thrusters/ThrusterManager.cs @@ -0,0 +1,49 @@ +using OWML.Utils; +using QSB.Player; +using QSB.Utility; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; + +namespace QSB.Animation.Player.Thrusters +{ + class ThrusterManager + { + public static GameObject CreateRemotePlayerVFX(PlayerInfo player) + { + DebugLog.DebugWrite($"Create PlayerVFX for player {player.PlayerId}"); + var localPlayerVfx = GameObject.Find("PlayerVFX"); + var newVfx = UnityEngine.Object.Instantiate(localPlayerVfx); + + CreateParticlesController(newVfx); + CreateThrusterWashController(newVfx.transform.Find("ThrusterWash").gameObject, player); + + return newVfx; + } + + private static void CreateParticlesController(GameObject root) + { + + } + + private static void CreateThrusterWashController(GameObject root, PlayerInfo player) + { + var old = root.GetComponent(); + var oldDistanceScale = old.GetValue("_emissionDistanceScale"); + var oldThrusterScale = old.GetValue("_emissionThrusterScale"); + var defaultParticleSystem = old.GetValue("_defaultParticleSystem"); + + UnityEngine.Object.Destroy(old); + + var newObj = root.AddComponent(); + newObj.InitFromOld(oldDistanceScale, oldThrusterScale, defaultParticleSystem, player); + } + + private static void CreateThrusterFlameController(GameObject root) + { + + } + } +} diff --git a/QSB/Player/PlayerInfo.cs b/QSB/Player/PlayerInfo.cs index 590a3f6a..b973b8d3 100644 --- a/QSB/Player/PlayerInfo.cs +++ b/QSB/Player/PlayerInfo.cs @@ -1,4 +1,5 @@ using QSB.Animation.Player; +using QSB.Animation.Player.Thrusters; using QSB.CampfireSync.WorldObjects; using QSB.Player.TransformSync; using QSB.ProbeSync; @@ -47,6 +48,7 @@ namespace QSB.Player public AnimationSync AnimationSync => QSBPlayerManager.GetSyncObject(PlayerId); public bool PlayingInstrument => AnimationSync.CurrentType != AnimationType.PlayerSuited && AnimationSync.CurrentType != AnimationType.PlayerUnsuited; + public JetpackAccelerationSync JetpackAcceleration { get; set; } // Misc public bool IsInMoon; // TODO : move into PlayerStates? diff --git a/QSB/QSB.csproj b/QSB/QSB.csproj index 7169eba1..16818177 100644 --- a/QSB/QSB.csproj +++ b/QSB/QSB.csproj @@ -124,7 +124,10 @@ - + + + + diff --git a/QSB/QSBCore.cs b/QSB/QSBCore.cs index 00726406..b927afa6 100644 --- a/QSB/QSBCore.cs +++ b/QSB/QSBCore.cs @@ -174,7 +174,7 @@ namespace QSB GUI.Label(new Rect(220, offset, 200f, 20f), $"Probe Active : {Locator.GetProbe().gameObject.activeInHierarchy}"); offset += _debugLineSpacing; - GUI.Label(new Rect(220, offset, 200f, 20f), $"Player positions :"); + GUI.Label(new Rect(220, offset, 200f, 20f), $"Player data :"); offset += _debugLineSpacing; foreach (var player in QSBPlayerManager.PlayerList.Where(x => x.PlayerStates.IsReady)) { @@ -183,6 +183,8 @@ namespace QSB GUI.Label(new Rect(220, offset, 400f, 20f), $"- {player.PlayerId} : {networkTransform.transform.localPosition} from {(sector == null ? "NULL" : sector.Name)}"); offset += _debugLineSpacing; + GUI.Label(new Rect(220, offset, 400f, 20f), $"- LocalAccel : {player.JetpackAcceleration?.LocalAcceleration}"); + offset += _debugLineSpacing; } if (SocketedObjToDebug == -1) diff --git a/QSB/QSBNetworkManager.cs b/QSB/QSBNetworkManager.cs index 309795f7..4e4dcf7a 100644 --- a/QSB/QSBNetworkManager.cs +++ b/QSB/QSBNetworkManager.cs @@ -1,6 +1,7 @@ using OWML.Common; using OWML.Utils; using QSB.Animation.Player; +using QSB.Animation.Player.Thrusters; using QSB.DeathSync; using QSB.Events; using QSB.Instruments; @@ -59,6 +60,7 @@ namespace QSB playerPrefab.AddComponent(); playerPrefab.AddComponent(); playerPrefab.AddComponent(); + playerPrefab.AddComponent(); playerPrefab.AddComponent(); _shipPrefab = _assetBundle.LoadAsset("assets/networkship.prefab"); diff --git a/QuantumUNET/Components/QNetworkIdentity.cs b/QuantumUNET/Components/QNetworkIdentity.cs index b233e000..0f1ca4ef 100644 --- a/QuantumUNET/Components/QNetworkIdentity.cs +++ b/QuantumUNET/Components/QNetworkIdentity.cs @@ -37,6 +37,9 @@ namespace QuantumUNET.Components set => m_LocalPlayerAuthority = value; } + public QNetworkBehaviour[] GetNetworkBehaviours() + => m_NetworkBehaviours; + public void SetRootIdentity(QNetworkIdentity newRoot) { if (RootIdentity != null) diff --git a/QuantumUNET/Messages/QMsgType.cs b/QuantumUNET/Messages/QMsgType.cs index 252d1fbb..40dbdbfc 100644 --- a/QuantumUNET/Messages/QMsgType.cs +++ b/QuantumUNET/Messages/QMsgType.cs @@ -5,7 +5,7 @@ public static string MsgTypeToString(short value) { string result; - if (value < 0 || value > 47) + if (value < 0 || value > 48) { result = string.Empty; } @@ -61,7 +61,8 @@ public const short LobbyAddPlayerFailed = 45; public const short LobbyReturnToLobby = 46; public const short ReconnectPlayer = 47; - public const short Highest = 47; + public const short ClientUpdateVars = 48; + public const short Highest = 48; internal static string[] msgLabels = { "none", @@ -111,7 +112,8 @@ "LobbySceneLoaded", "LobbyAddPlayerFailed", "LobbyReturnToLobby", - "ReconnectPlayer" + "ReconnectPlayer", + "ClientUpdateVars" }; } } diff --git a/QuantumUNET/QNetworkBehaviour.cs b/QuantumUNET/QNetworkBehaviour.cs index 939cacd5..0e6c6770 100644 --- a/QuantumUNET/QNetworkBehaviour.cs +++ b/QuantumUNET/QNetworkBehaviour.cs @@ -57,8 +57,9 @@ namespace QuantumUNET protected void ClientSendUpdateVars() { var writer = new QNetworkWriter(); - writer.StartMessage(QMsgType.UpdateVars); + writer.StartMessage(QMsgType.ClientUpdateVars); writer.Write(NetId); + writer.Write(GetType().Name); if (OnSerialize(writer, false)) { ClearAllDirtyBits(); diff --git a/QuantumUNET/QNetworkServer.cs b/QuantumUNET/QNetworkServer.cs index ebf4d799..c0274ed8 100644 --- a/QuantumUNET/QNetworkServer.cs +++ b/QuantumUNET/QNetworkServer.cs @@ -109,7 +109,7 @@ namespace QuantumUNET internal void RegisterMessageHandlers() { - m_SimpleServerSimple.RegisterHandlerSafe(QMsgType.UpdateVars, OnUpdateVarsMessage); + m_SimpleServerSimple.RegisterHandlerSafe(QMsgType.ClientUpdateVars, OnUpdateVarsMessage); m_SimpleServerSimple.RegisterHandlerSafe(QMsgType.Ready, OnClientReadyMessage); m_SimpleServerSimple.RegisterHandlerSafe(QMsgType.Command, OnCommandMessage); m_SimpleServerSimple.RegisterHandlerSafe(QMsgType.LocalPlayerTransform, QNetworkTransform.HandleTransform); @@ -124,9 +124,12 @@ namespace QuantumUNET private static void OnUpdateVarsMessage(QNetworkMessage netMsg) { var networkInstanceId = netMsg.Reader.ReadNetworkId(); + var typeName = netMsg.Reader.ReadString(); if (instance.m_NetworkScene.GetNetworkIdentity(networkInstanceId, out var networkIdentity)) { - networkIdentity.OnUpdateVars(netMsg.Reader, false); + var allBehaviours = networkIdentity.GetNetworkBehaviours(); + var target = allBehaviours.First(x => x.GetType().Name == typeName); + target.OnDeserialize(netMsg.Reader, false); } else {