217 lines
6.3 KiB
C#
Raw Normal View History

using Mirror;
using OWML.Common;
2022-01-15 20:27:24 -08:00
using OWML.Utils;
2021-12-25 18:23:20 -08:00
using QSB.Animation.Player.Messages;
2021-05-07 14:58:37 +01:00
using QSB.Animation.Player.Thrusters;
2021-12-25 18:23:20 -08:00
using QSB.Messaging;
2020-11-03 21:33:48 +00:00
using QSB.Player;
2020-11-08 14:41:16 +00:00
using QSB.Utility;
2022-08-15 11:14:23 +01:00
using QSB.WorldSync;
2022-01-23 16:14:42 +00:00
using System;
2022-08-15 11:14:23 +01:00
using System.Reflection;
using UnityEngine;
2022-03-02 19:46:33 -08:00
namespace QSB.Animation.Player;
public class AnimationSync : PlayerSyncObject
{
2022-03-02 19:46:33 -08:00
private RuntimeAnimatorController _suitedAnimController;
private AnimatorOverrideController _unsuitedAnimController;
private GameObject _suitedGraphics;
private GameObject _unsuitedGraphics;
public AnimatorMirror Mirror { get; private set; }
public bool InSuitedUpState { get; set; }
public Animator VisibleAnimator { get; private set; }
public Animator InvisibleAnimator { get; private set; }
public NetworkAnimator NetworkAnimator { get; private set; }
protected void Awake()
2020-12-02 21:29:53 +00:00
{
2022-03-02 19:46:33 -08:00
InvisibleAnimator = gameObject.GetRequiredComponent<Animator>();
NetworkAnimator = gameObject.GetRequiredComponent<NetworkAnimator>();
NetworkAnimator.enabled = false;
}
2022-08-15 11:14:23 +01:00
protected void Start()
=> RequestInitialStatesMessage.SendInitialState += SendInitialState;
protected void OnDestroy()
=> RequestInitialStatesMessage.SendInitialState -= SendInitialState;
private void SendInitialState(uint to)
{
if (PlayerId == to)
{
return;
}
/*
* This wipes the NetworkAnimator's "last_X_Parameters" fields, so it assumes the parameters have changed.
* Basically just forces the networkanimator to set all it's dirty flags.
* I tried just manually sending the parameter message myself, but that made the client get very angry and disconnect.
*/
var parameters = (AnimatorControllerParameter[])NetworkAnimator.GetType().GetField("parameters", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(NetworkAnimator);
var lastIntParams = NetworkAnimator.GetType().GetField("lastIntParameters", BindingFlags.NonPublic | BindingFlags.Instance);
var lastFloatParams = NetworkAnimator.GetType().GetField("lastFloatParameters", BindingFlags.NonPublic | BindingFlags.Instance);
var lastBoolParams = NetworkAnimator.GetType().GetField("lastBoolParameters", BindingFlags.NonPublic | BindingFlags.Instance);
lastIntParams.SetValue(NetworkAnimator, new int[parameters.Length]);
lastFloatParams.SetValue(NetworkAnimator, new float[parameters.Length]);
lastBoolParams.SetValue(NetworkAnimator, new bool[parameters.Length]);
}
2022-03-02 19:46:33 -08:00
private void InitCommon(Transform modelRoot)
{
try
2020-12-02 21:29:53 +00:00
{
2022-03-02 19:46:33 -08:00
if (modelRoot == null)
2020-12-02 21:29:53 +00:00
{
2022-03-02 19:46:33 -08:00
DebugLog.ToConsole($"Error - Trying to InitCommon with null body!", MessageType.Error);
return;
}
2022-01-23 16:14:42 +00:00
2022-03-02 19:46:33 -08:00
VisibleAnimator = modelRoot.GetComponent<Animator>();
Mirror = modelRoot.gameObject.AddComponent<AnimatorMirror>();
if (isLocalPlayer)
{
2022-08-14 12:33:04 +01:00
Mirror.Init(VisibleAnimator, InvisibleAnimator, NetworkAnimator);
2020-12-02 21:29:53 +00:00
}
2022-03-02 19:46:33 -08:00
else
2020-12-02 21:29:53 +00:00
{
2022-08-14 12:33:04 +01:00
Mirror.Init(InvisibleAnimator, VisibleAnimator, null);
2020-12-02 21:29:53 +00:00
}
2022-03-02 19:46:33 -08:00
NetworkAnimator.enabled = true;
NetworkAnimator.Invoke("Awake");
2022-03-02 19:46:33 -08:00
_suitedAnimController = Instantiate(QSBCore.NetworkAssetBundle.LoadAsset<RuntimeAnimatorController>("Assets/GameAssets/AnimatorController/Player.controller"));
_unsuitedAnimController = Instantiate(QSBCore.NetworkAssetBundle.LoadAsset<AnimatorOverrideController>("Assets/GameAssets/AnimatorOverrideController/PlayerUnsuitedOverride.overrideController"));
_suitedGraphics = modelRoot.GetChild(1).gameObject;
_unsuitedGraphics = modelRoot.GetChild(0).gameObject;
2022-03-02 19:46:33 -08:00
VisibleAnimator.SetLayerWeight(2, 1f);
2021-05-07 14:58:37 +01:00
}
2022-03-02 19:46:33 -08:00
catch (Exception ex)
2020-12-02 21:29:53 +00:00
{
2022-03-02 19:46:33 -08:00
DebugLog.ToConsole($"Exception thrown when running InitCommon on {(modelRoot != null ? modelRoot.name : "NULL BODY")}. {ex.Message} Stacktrace: {ex.StackTrace}", MessageType.Error);
}
2022-03-02 19:46:33 -08:00
}
2021-06-18 22:38:32 +01:00
2022-03-02 19:46:33 -08:00
public void InitLocal(Transform body)
{
InitCommon(body);
InitAccelerationSync();
}
public void InitRemote(Transform body)
{
InitCommon(body);
SetSuitState(QSBSceneManager.CurrentScene == OWScene.EyeOfTheUniverse);
InitAccelerationSync();
ThrusterManager.CreateRemotePlayerVFX(Player);
Delay.RunWhen(() => Player.CameraBody != null,
() => body.GetComponent<PlayerHeadRotationSync>().Init(Player.CameraBody.transform));
}
private void InitAccelerationSync()
{
2022-05-19 14:34:49 +01:00
Player.JetpackAcceleration = GetComponent<JetpackAccelerationSync>();
2022-03-02 19:46:33 -08:00
var thrusterModel = hasAuthority ? Locator.GetPlayerBody().GetComponent<ThrusterModel>() : null;
Player.JetpackAcceleration.Init(thrusterModel);
}
public void SetSuitState(bool suitedUp)
{
if (!Player.IsReady)
{
2022-03-02 19:46:33 -08:00
return;
}
2021-06-18 22:38:32 +01:00
2022-03-02 19:46:33 -08:00
if (Player == QSBPlayerManager.LocalPlayer)
{
2022-03-02 19:46:33 -08:00
new PlayerSuitMessage(suitedUp).Send();
}
2021-12-10 22:13:39 +00:00
2022-03-02 19:46:33 -08:00
if (InSuitedUpState == suitedUp)
{
2022-03-02 19:46:33 -08:00
return;
}
2021-12-10 14:54:51 +00:00
2022-03-02 19:46:33 -08:00
InSuitedUpState = suitedUp;
if (_unsuitedAnimController == null)
{
DebugLog.ToConsole($"Error - Unsuited controller is null. ({PlayerId})", MessageType.Error);
}
2021-12-10 14:54:51 +00:00
2022-03-02 19:46:33 -08:00
if (_suitedAnimController == null)
{
DebugLog.ToConsole($"Error - Suited controller is null. ({PlayerId})", MessageType.Error);
}
2021-12-11 20:06:02 +00:00
2022-03-02 19:46:33 -08:00
if (_unsuitedGraphics == null)
{
DebugLog.ToConsole($"Warning - _unsuitedGraphics is null! ({PlayerId})", MessageType.Warning);
}
2021-06-18 22:38:32 +01:00
2022-03-02 19:46:33 -08:00
if (_suitedGraphics == null)
{
DebugLog.ToConsole($"Warning - _suitedGraphics is null! ({PlayerId})", MessageType.Warning);
}
2022-03-02 19:46:33 -08:00
var controller = suitedUp ? _suitedAnimController : _unsuitedAnimController;
if (_unsuitedGraphics != null)
{
_unsuitedGraphics?.SetActive(!suitedUp);
}
2022-03-02 19:46:33 -08:00
if (_suitedGraphics != null)
{
_suitedGraphics?.SetActive(suitedUp);
}
2022-03-02 19:46:33 -08:00
if (InvisibleAnimator == null)
{
DebugLog.ToConsole($"Error - InvisibleAnimator is null. ({PlayerId})", MessageType.Error);
}
else
{
InvisibleAnimator.runtimeAnimatorController = controller;
}
2022-03-02 19:46:33 -08:00
if (VisibleAnimator == null)
{
DebugLog.ToConsole($"Error - VisibleAnimator is null. ({PlayerId})", MessageType.Error);
}
else
{
VisibleAnimator.runtimeAnimatorController = controller;
}
2022-03-02 19:46:33 -08:00
// Avoids "jumping" when putting on suit
if (VisibleAnimator != null)
{
2022-08-13 20:11:48 +01:00
VisibleAnimator.SetBool("Grounded", true);
2022-03-02 19:46:33 -08:00
}
2022-03-02 19:46:33 -08:00
if (InvisibleAnimator != null)
{
2022-08-13 20:11:48 +01:00
InvisibleAnimator.SetBool("Grounded", true);
2022-03-02 19:46:33 -08:00
}
2022-03-02 19:46:33 -08:00
if (NetworkAnimator == null)
{
DebugLog.ToConsole($"Error - NetworkAnimator is null. ({PlayerId})", MessageType.Error);
}
2022-03-02 19:46:33 -08:00
else if (Mirror == null)
{
DebugLog.ToConsole($"Error - Mirror is null. ({PlayerId})", MessageType.Error);
}
Mirror.RebuildFloatParams();
NetworkAnimator.Invoke("Awake");
2020-12-02 21:29:53 +00:00
}
2020-11-08 16:13:10 +00:00
}