mirror of
https://github.com/misternebula/quantum-space-buddies.git
synced 2025-02-04 03:39:55 +00:00
Merge pull request #287 from misternebula/animations
Fix transform sync, fix orbs, fix quantum objects, add land anim, add head tracking
This commit is contained in:
commit
9c76f0420e
11
QSB/Animation/Character/CharacterAnimManager.cs
Normal file
11
QSB/Animation/Character/CharacterAnimManager.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using QSB.Animation.Character.WorldObjects;
|
||||
using QSB.WorldSync;
|
||||
|
||||
namespace QSB.Animation.Character
|
||||
{
|
||||
internal class CharacterAnimManager : WorldObjectManager
|
||||
{
|
||||
protected override void RebuildWorldObjects(OWScene scene)
|
||||
=> QSBWorldSync.Init<QSBCharacterAnimController, CharacterAnimController>();
|
||||
}
|
||||
}
|
111
QSB/Animation/Character/Patches/CharacterAnimationPatches.cs
Normal file
111
QSB/Animation/Character/Patches/CharacterAnimationPatches.cs
Normal file
@ -0,0 +1,111 @@
|
||||
using OWML.Common;
|
||||
using QSB.Animation.Character.WorldObjects;
|
||||
using QSB.Events;
|
||||
using QSB.Patches;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.ConversationSync.Patches
|
||||
{
|
||||
public class CharacterAnimationPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
public override void DoPatches()
|
||||
{
|
||||
QSBCore.HarmonyHelper.AddPrefix<CharacterAnimController>("OnAnimatorIK", typeof(CharacterAnimationPatches), nameof(AnimController_OnAnimatorIK));
|
||||
QSBCore.HarmonyHelper.AddPrefix<CharacterAnimController>("OnZoneEntry", typeof(CharacterAnimationPatches), nameof(AnimController_OnZoneEntry));
|
||||
QSBCore.HarmonyHelper.AddPrefix<CharacterAnimController>("OnZoneExit", typeof(CharacterAnimationPatches), nameof(AnimController_OnZoneExit));
|
||||
}
|
||||
|
||||
public override void DoUnpatches()
|
||||
{
|
||||
QSBCore.HarmonyHelper.Unpatch<CharacterAnimController>("OnAnimatorIK");
|
||||
QSBCore.HarmonyHelper.Unpatch<CharacterAnimController>("OnZoneExit");
|
||||
}
|
||||
|
||||
public static bool AnimController_OnAnimatorIK(
|
||||
CharacterAnimController __instance,
|
||||
float ___headTrackingWeight,
|
||||
bool ___lookOnlyWhenTalking,
|
||||
bool ____playerInHeadZone,
|
||||
bool ____inConversation,
|
||||
ref float ____currentLookWeight,
|
||||
ref Vector3 ____currentLookTarget,
|
||||
DampedSpring3D ___lookSpring,
|
||||
Animator ____animator,
|
||||
CharacterDialogueTree ____dialogueTree)
|
||||
{
|
||||
|
||||
var playerId = ConversationManager.Instance.GetPlayerTalkingToTree(____dialogueTree);
|
||||
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController, CharacterAnimController>(__instance); // TODO : maybe cache this somewhere... or assess how slow this is
|
||||
|
||||
Vector3 position;
|
||||
if (____inConversation)
|
||||
{
|
||||
if (playerId == uint.MaxValue)
|
||||
{
|
||||
DebugLog.DebugWrite($"Error - {__instance.name} is in conversation with a null player! Defaulting to active camera.", MessageType.Error);
|
||||
position = Locator.GetActiveCamera().transform.position;
|
||||
}
|
||||
else
|
||||
{
|
||||
var player = QSBPlayerManager.GetPlayer(playerId);
|
||||
position = player.CameraBody == null
|
||||
? Locator.GetActiveCamera().transform.position
|
||||
: player.CameraBody.transform.position;
|
||||
}
|
||||
}
|
||||
else if (!___lookOnlyWhenTalking && qsbObj.GetPlayersInHeadZone().Count != 0)
|
||||
{
|
||||
position = QSBPlayerManager.GetClosestPlayerToWorldPoint(qsbObj.GetPlayersInHeadZone(), __instance.transform.position).CameraBody.transform.position;
|
||||
}
|
||||
else
|
||||
{
|
||||
position = QSBPlayerManager.GetClosestPlayerToWorldPoint(__instance.transform.position, true).CameraBody.transform.position;
|
||||
}
|
||||
|
||||
var localPosition = ____animator.transform.InverseTransformPoint(position);
|
||||
|
||||
var targetWeight = ___headTrackingWeight;
|
||||
if (___lookOnlyWhenTalking)
|
||||
{
|
||||
if (!____inConversation || qsbObj.GetPlayersInHeadZone().Count == 0)
|
||||
{
|
||||
targetWeight *= 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (qsbObj.GetPlayersInHeadZone().Count == 0)
|
||||
{
|
||||
targetWeight *= 0;
|
||||
}
|
||||
}
|
||||
|
||||
____currentLookWeight = Mathf.Lerp(____currentLookWeight, targetWeight, Time.deltaTime * 2f);
|
||||
____currentLookTarget = ___lookSpring.Update(____currentLookTarget, localPosition, Time.deltaTime);
|
||||
____animator.SetLookAtPosition(____animator.transform.TransformPoint(____currentLookTarget));
|
||||
____animator.SetLookAtWeight(____currentLookWeight);
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public static bool AnimController_OnZoneExit(CharacterAnimController __instance)
|
||||
{
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController, CharacterAnimController>(__instance);
|
||||
QSBEventManager.FireEvent(EventNames.QSBExitHeadZone, qsbObj.ObjectId);
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool AnimController_OnZoneEntry(CharacterAnimController __instance)
|
||||
{
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController, CharacterAnimController>(__instance);
|
||||
QSBEventManager.FireEvent(EventNames.QSBEnterHeadZone, qsbObj.ObjectId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
using OWML.Utils;
|
||||
using QSB.Player;
|
||||
using QSB.WorldSync;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QSB.Animation.Character.WorldObjects
|
||||
{
|
||||
internal class QSBCharacterAnimController : WorldObject<CharacterAnimController>
|
||||
{
|
||||
private readonly List<PlayerInfo> _playersInHeadZone = new List<PlayerInfo>();
|
||||
|
||||
public override void Init(CharacterAnimController controller, int id)
|
||||
{
|
||||
ObjectId = id;
|
||||
AttachedObject = controller;
|
||||
}
|
||||
|
||||
public List<PlayerInfo> GetPlayersInHeadZone()
|
||||
=> _playersInHeadZone;
|
||||
|
||||
public void AddPlayerToHeadZone(PlayerInfo player)
|
||||
{
|
||||
if (_playersInHeadZone.Contains(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
_playersInHeadZone.Add(player);
|
||||
}
|
||||
|
||||
public void RemovePlayerFromHeadZone(PlayerInfo player)
|
||||
{
|
||||
if (!_playersInHeadZone.Contains(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
_playersInHeadZone.Remove(player);
|
||||
}
|
||||
|
||||
public void StartConversation()
|
||||
{
|
||||
AttachedObject.SetValue("_inConversation", true);
|
||||
QSBWorldSync.RaiseEvent(AttachedObject, "OnStartConversation");
|
||||
}
|
||||
|
||||
public void EndConversation()
|
||||
{
|
||||
AttachedObject.SetValue("_inConversation", false);
|
||||
QSBWorldSync.RaiseEvent(AttachedObject, "OnEndConversation");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
using OWML.Utils;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Animation
|
||||
namespace QSB.Animation.Player
|
||||
{
|
||||
public static class AnimControllerPatch
|
||||
{
|
@ -1,6 +1,6 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Animation
|
||||
namespace QSB.Animation.Player
|
||||
{
|
||||
public class AnimFloatParam
|
||||
{
|
@ -7,13 +7,10 @@ using QuantumUNET.Components;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Animation
|
||||
namespace QSB.Animation.Player
|
||||
{
|
||||
public class AnimationSync : PlayerSyncObject
|
||||
{
|
||||
private Animator _anim;
|
||||
private QNetworkAnimator _netAnim;
|
||||
|
||||
private RuntimeAnimatorController _suitedAnimController;
|
||||
private AnimatorOverrideController _unsuitedAnimController;
|
||||
private GameObject _suitedGraphics;
|
||||
@ -30,13 +27,15 @@ namespace QSB.Animation
|
||||
public AnimatorMirror Mirror { get; private set; }
|
||||
public AnimationType CurrentType { get; set; }
|
||||
public Animator VisibleAnimator { get; private set; }
|
||||
public Animator InvisibleAnimator { get; private set; }
|
||||
public QNetworkAnimator NetworkAnimator { get; private set; }
|
||||
|
||||
protected void Awake()
|
||||
{
|
||||
_anim = gameObject.AddComponent<Animator>();
|
||||
_netAnim = gameObject.AddComponent<QNetworkAnimator>();
|
||||
_netAnim.enabled = false;
|
||||
_netAnim.animator = _anim;
|
||||
InvisibleAnimator = gameObject.AddComponent<Animator>();
|
||||
NetworkAnimator = gameObject.AddComponent<QNetworkAnimator>();
|
||||
NetworkAnimator.enabled = false;
|
||||
NetworkAnimator.animator = InvisibleAnimator;
|
||||
|
||||
QSBSceneManager.OnUniverseSceneLoaded += OnUniverseSceneLoaded;
|
||||
}
|
||||
@ -44,16 +43,9 @@ namespace QSB.Animation
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
Destroy(_anim);
|
||||
Destroy(_netAnim);
|
||||
Destroy(InvisibleAnimator);
|
||||
Destroy(NetworkAnimator);
|
||||
QSBSceneManager.OnUniverseSceneLoaded -= OnUniverseSceneLoaded;
|
||||
if (_playerController == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_playerController.OnJump -= OnJump;
|
||||
_playerController.OnBecomeGrounded -= OnBecomeGrounded;
|
||||
_playerController.OnBecomeUngrounded -= OnBecomeUngrounded;
|
||||
}
|
||||
|
||||
private void OnUniverseSceneLoaded(OWScene obj) => LoadControllers();
|
||||
@ -71,21 +63,21 @@ namespace QSB.Animation
|
||||
{
|
||||
LoadControllers();
|
||||
}
|
||||
_netAnim.enabled = true;
|
||||
NetworkAnimator.enabled = true;
|
||||
VisibleAnimator = body.GetComponent<Animator>();
|
||||
Mirror = body.gameObject.AddComponent<AnimatorMirror>();
|
||||
if (IsLocalPlayer)
|
||||
{
|
||||
Mirror.Init(VisibleAnimator, _anim);
|
||||
Mirror.Init(VisibleAnimator, InvisibleAnimator);
|
||||
}
|
||||
else
|
||||
{
|
||||
Mirror.Init(_anim, VisibleAnimator);
|
||||
Mirror.Init(InvisibleAnimator, VisibleAnimator);
|
||||
}
|
||||
|
||||
for (var i = 0; i < _anim.parameterCount; i++)
|
||||
for (var i = 0; i < InvisibleAnimator.parameterCount; i++)
|
||||
{
|
||||
_netAnim.SetParameterAutoSend(i, true);
|
||||
NetworkAnimator.SetParameterAutoSend(i, true);
|
||||
}
|
||||
|
||||
var playerAnimController = body.GetComponent<PlayerAnimController>();
|
||||
@ -100,9 +92,6 @@ namespace QSB.Animation
|
||||
InitCommon(body);
|
||||
|
||||
_playerController = body.parent.GetComponent<PlayerCharacterController>();
|
||||
_playerController.OnJump += OnJump;
|
||||
_playerController.OnBecomeGrounded += OnBecomeGrounded;
|
||||
_playerController.OnBecomeUngrounded += OnBecomeUngrounded;
|
||||
|
||||
InitCrouchSync();
|
||||
}
|
||||
@ -140,12 +129,6 @@ namespace QSB.Animation
|
||||
_crouchSync.Init(this, _playerController, VisibleAnimator);
|
||||
}
|
||||
|
||||
private void OnJump() => _netAnim.SetTrigger("Jump");
|
||||
|
||||
private void OnBecomeGrounded() => _netAnim.SetTrigger("Grounded");
|
||||
|
||||
private void OnBecomeUngrounded() => _netAnim.SetTrigger("Ungrounded");
|
||||
|
||||
public void SendCrouch(float value = 0) => QSBEventManager.FireEvent(EventNames.QSBCrouch, value);
|
||||
|
||||
public void HandleCrouch(float value) => _crouchSync.CrouchParam.Target = value;
|
||||
@ -226,24 +209,24 @@ namespace QSB.Animation
|
||||
controller = _riebeckController;
|
||||
break;
|
||||
}
|
||||
_anim.runtimeAnimatorController = controller;
|
||||
InvisibleAnimator.runtimeAnimatorController = controller;
|
||||
VisibleAnimator.runtimeAnimatorController = controller;
|
||||
if (type != AnimationType.PlayerSuited && type != AnimationType.PlayerUnsuited)
|
||||
{
|
||||
VisibleAnimator.SetTrigger("Playing");
|
||||
_anim.SetTrigger("Playing");
|
||||
InvisibleAnimator.SetTrigger("Playing");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Avoids "jumping" when exiting instrument and putting on suit
|
||||
VisibleAnimator.SetTrigger("Grounded");
|
||||
_anim.SetTrigger("Grounded");
|
||||
InvisibleAnimator.SetTrigger("Grounded");
|
||||
}
|
||||
_netAnim.animator = _anim; // Probably not needed.
|
||||
NetworkAnimator.animator = InvisibleAnimator; // Probably not needed.
|
||||
Mirror.RebuildFloatParams();
|
||||
for (var i = 0; i < _anim.parameterCount; i++)
|
||||
for (var i = 0; i < InvisibleAnimator.parameterCount; i++)
|
||||
{
|
||||
_netAnim.SetParameterAutoSend(i, true);
|
||||
NetworkAnimator.SetParameterAutoSend(i, true);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
namespace QSB.Animation
|
||||
namespace QSB.Animation.Player
|
||||
{
|
||||
public enum AnimationType
|
||||
{
|
@ -4,7 +4,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Animation
|
||||
namespace QSB.Animation.Player
|
||||
{
|
||||
public class AnimatorMirror : MonoBehaviour
|
||||
{
|
@ -2,7 +2,7 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Animation
|
||||
namespace QSB.Animation.Player
|
||||
{
|
||||
public class CrouchSync : QNetworkBehaviour
|
||||
{
|
28
QSB/Animation/Player/Events/AnimationTriggerEvent.cs
Normal file
28
QSB/Animation/Player/Events/AnimationTriggerEvent.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using QSB.Events;
|
||||
using QSB.Player;
|
||||
|
||||
namespace QSB.Animation.Player.Events
|
||||
{
|
||||
internal class AnimationTriggerEvent : QSBEvent<AnimationTriggerMessage>
|
||||
{
|
||||
public override EventType Type => EventType.AnimTrigger;
|
||||
|
||||
public override void SetupListener() => GlobalMessenger<uint, string>.AddListener(EventNames.QSBAnimTrigger, Handler);
|
||||
public override void CloseListener() => GlobalMessenger<uint, string>.RemoveListener(EventNames.QSBAnimTrigger, Handler);
|
||||
|
||||
private void Handler(uint attachedNetId, string name) => SendEvent(CreateMessage(attachedNetId, name));
|
||||
|
||||
private AnimationTriggerMessage CreateMessage(uint attachedNetId, string name) => new AnimationTriggerMessage
|
||||
{
|
||||
AboutId = LocalPlayerId,
|
||||
AttachedNetId = attachedNetId,
|
||||
Name = name
|
||||
};
|
||||
|
||||
public override void OnReceiveRemote(bool server, AnimationTriggerMessage message)
|
||||
{
|
||||
var animationSync = QSBPlayerManager.GetSyncObject<AnimationSync>(message.AttachedNetId);
|
||||
animationSync.VisibleAnimator.SetTrigger(message.Name);
|
||||
}
|
||||
}
|
||||
}
|
25
QSB/Animation/Player/Events/AnimationTriggerMessage.cs
Normal file
25
QSB/Animation/Player/Events/AnimationTriggerMessage.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using QSB.Messaging;
|
||||
using QuantumUNET.Transport;
|
||||
|
||||
namespace QSB.Animation.Player.Events
|
||||
{
|
||||
public class AnimationTriggerMessage : PlayerMessage
|
||||
{
|
||||
public uint AttachedNetId { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
public override void Deserialize(QNetworkReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
AttachedNetId = reader.ReadUInt32();
|
||||
Name = reader.ReadString();
|
||||
}
|
||||
|
||||
public override void Serialize(QNetworkWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(AttachedNetId);
|
||||
writer.Write(Name);
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ using QSB.Instruments;
|
||||
using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
|
||||
namespace QSB.Animation.Events
|
||||
namespace QSB.Animation.Player.Events
|
||||
{
|
||||
public class ChangeAnimTypeEvent : QSBEvent<EnumMessage<AnimationType>>
|
||||
{
|
@ -2,11 +2,11 @@
|
||||
using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
|
||||
namespace QSB.Animation.Events
|
||||
namespace QSB.Animation.Player.Events
|
||||
{
|
||||
public class CrouchEvent : QSBEvent<FloatMessage>
|
||||
{
|
||||
public override EventType Type => EventType.AnimTrigger;
|
||||
public override EventType Type => EventType.Crouch;
|
||||
|
||||
public override void SetupListener() => GlobalMessenger<float>.AddListener(EventNames.QSBCrouch, Handler);
|
||||
public override void CloseListener() => GlobalMessenger<float>.RemoveListener(EventNames.QSBCrouch, Handler);
|
@ -2,7 +2,7 @@
|
||||
using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
|
||||
namespace QSB.Animation.Events
|
||||
namespace QSB.Animation.Player.Events
|
||||
{
|
||||
public class PlayerSuitEvent : QSBEvent<ToggleMessage>
|
||||
{
|
122
QSB/Animation/Player/Patches/PlayerAnimationPatches.cs
Normal file
122
QSB/Animation/Player/Patches/PlayerAnimationPatches.cs
Normal file
@ -0,0 +1,122 @@
|
||||
using QSB.Events;
|
||||
using QSB.Patches;
|
||||
using QSB.Player;
|
||||
using QSB.WorldSync;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Animation.Patches
|
||||
{
|
||||
internal class PlayerAnimationPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
public override void DoPatches() => QSBCore.HarmonyHelper.AddPrefix<PlayerAnimController>("LateUpdate", typeof(PlayerAnimationPatches), nameof(PlayerAnimController_LateUpdate));
|
||||
public override void DoUnpatches() => QSBCore.HarmonyHelper.Unpatch<PlayerAnimController>("LateUpdate");
|
||||
|
||||
public static bool PlayerAnimController_LateUpdate(
|
||||
PlayerAnimController __instance,
|
||||
PlayerCharacterController ____playerController,
|
||||
ThrusterModel ____playerJetpack,
|
||||
ref float ____ungroundedTime,
|
||||
Animator ____animator,
|
||||
ref bool ____justBecameGrounded,
|
||||
ref bool ____justTookFallDamage,
|
||||
ref bool ____leftFootGrounded,
|
||||
ref bool ____rightFootGrounded,
|
||||
ref bool ____rightArmHidden,
|
||||
GameObject[] ____rightArmObjects,
|
||||
int ____defaultLayer,
|
||||
int ____probeOnlyLayer)
|
||||
{
|
||||
var isGrounded = ____playerController.IsGrounded();
|
||||
var isAttached = PlayerState.IsAttached();
|
||||
var isInZeroG = PlayerState.InZeroG();
|
||||
var isFlying = ____playerJetpack.GetLocalAcceleration().y > 0f;
|
||||
var movementVector = Vector3.zero;
|
||||
if (!isAttached)
|
||||
{
|
||||
movementVector = ____playerController.GetRelativeGroundVelocity();
|
||||
}
|
||||
if (Mathf.Abs(movementVector.x) < 0.05f)
|
||||
{
|
||||
movementVector.x = 0f;
|
||||
}
|
||||
if (Mathf.Abs(movementVector.z) < 0.05f)
|
||||
{
|
||||
movementVector.z = 0f;
|
||||
}
|
||||
if (isFlying)
|
||||
{
|
||||
____ungroundedTime = Time.time;
|
||||
}
|
||||
var freefallMagnitude = 0f;
|
||||
var timeInFreefall = 0f;
|
||||
var lastGroundBody = ____playerController.GetLastGroundBody();
|
||||
if (!isGrounded && !isAttached && !isInZeroG && lastGroundBody != null)
|
||||
{
|
||||
freefallMagnitude = (____playerController.GetAttachedOWRigidbody(false).GetVelocity() - lastGroundBody.GetPointVelocity(____playerController.transform.position)).magnitude;
|
||||
timeInFreefall = Time.time - ____ungroundedTime;
|
||||
}
|
||||
____animator.SetFloat("RunSpeedX", movementVector.x / 3f);
|
||||
____animator.SetFloat("RunSpeedY", movementVector.z / 3f);
|
||||
____animator.SetFloat("TurnSpeed", ____playerController.GetTurning());
|
||||
____animator.SetBool("Grounded", isGrounded || isAttached || PlayerState.IsRecentlyDetached());
|
||||
____animator.SetLayerWeight(1, ____playerController.GetJumpChargeFraction());
|
||||
____animator.SetFloat("FreefallSpeed", freefallMagnitude / 15f * (timeInFreefall / 3f));
|
||||
____animator.SetBool("InZeroG", isInZeroG || isFlying);
|
||||
____animator.SetBool("UsingJetpack", isInZeroG && PlayerState.IsWearingSuit());
|
||||
if (____justBecameGrounded)
|
||||
{
|
||||
var playerAnimationSync = QSBPlayerManager.LocalPlayer.AnimationSync;
|
||||
if (____justTookFallDamage)
|
||||
{
|
||||
____animator.SetTrigger("LandHard");
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnimTrigger, playerAnimationSync.AttachedNetId, "LandHard");
|
||||
}
|
||||
else
|
||||
{
|
||||
____animator.SetTrigger("Land");
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnimTrigger, playerAnimationSync.AttachedNetId, "Land");
|
||||
}
|
||||
}
|
||||
if (isGrounded)
|
||||
{
|
||||
var leftFootLift = ____animator.GetFloat("LeftFootLift");
|
||||
if (!____leftFootGrounded && leftFootLift < 0.333f)
|
||||
{
|
||||
____leftFootGrounded = true;
|
||||
QSBWorldSync.RaiseEvent(__instance, "OnLeftFootGrounded");
|
||||
}
|
||||
else if (____leftFootGrounded && leftFootLift > 0.666f)
|
||||
{
|
||||
____leftFootGrounded = false;
|
||||
QSBWorldSync.RaiseEvent(__instance, "OnLeftFootLift");
|
||||
}
|
||||
var rightFootLift = ____animator.GetFloat("RightFootLift");
|
||||
if (!____rightFootGrounded && rightFootLift < 0.333f)
|
||||
{
|
||||
____rightFootGrounded = true;
|
||||
QSBWorldSync.RaiseEvent(__instance, "OnRightFootGrounded");
|
||||
}
|
||||
else if (____rightFootGrounded && rightFootLift > 0.666f)
|
||||
{
|
||||
____rightFootGrounded = false;
|
||||
QSBWorldSync.RaiseEvent(__instance, "OnRightFootLift");
|
||||
}
|
||||
}
|
||||
____justBecameGrounded = false;
|
||||
____justTookFallDamage = false;
|
||||
var usingTool = Locator.GetToolModeSwapper().GetToolMode() != ToolMode.None;
|
||||
if ((usingTool && !____rightArmHidden) || (!usingTool && ____rightArmHidden))
|
||||
{
|
||||
____rightArmHidden = usingTool;
|
||||
for (var i = 0; i < ____rightArmObjects.Length; i++)
|
||||
{
|
||||
____rightArmObjects[i].layer = (!____rightArmHidden) ? ____defaultLayer : ____probeOnlyLayer;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
using QSB.Utility;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Animation
|
||||
namespace QSB.Animation.Player
|
||||
{
|
||||
public class PlayerHeadRotationSync : MonoBehaviour
|
||||
{
|
@ -1,5 +1,6 @@
|
||||
using OWML.Common;
|
||||
using OWML.Utils;
|
||||
using QSB.Animation.Character.WorldObjects;
|
||||
using QSB.Events;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
@ -64,12 +65,8 @@ namespace QSB.ConversationSync.Events
|
||||
CharacterDialogueTree tree)
|
||||
{
|
||||
QSBPlayerManager.GetPlayer(playerId).CurrentDialogueID = characterId;
|
||||
controller.SetValue("_inConversation", true);
|
||||
controller.SetValue("_playerInHeadZone", true);
|
||||
if (controller.GetValue<bool>("_hasTalkAnimation"))
|
||||
{
|
||||
controller.GetValue<Animator>("_animator").SetTrigger("Talking");
|
||||
}
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController, CharacterAnimController>(controller);
|
||||
qsbObj.StartConversation();
|
||||
tree.GetInteractVolume().DisableInteraction();
|
||||
}
|
||||
|
||||
@ -79,12 +76,8 @@ namespace QSB.ConversationSync.Events
|
||||
CharacterDialogueTree tree)
|
||||
{
|
||||
QSBPlayerManager.GetPlayer(playerId).CurrentDialogueID = -1;
|
||||
controller.SetValue("_inConversation", false);
|
||||
controller.SetValue("_playerInHeadZone", false);
|
||||
if (controller.GetValue<bool>("_hasTalkAnimation"))
|
||||
{
|
||||
controller.GetValue<Animator>("_animator").SetTrigger("Idle");
|
||||
}
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController, CharacterAnimController>(controller);
|
||||
qsbObj.EndConversation();
|
||||
tree.GetInteractVolume().EnableInteraction();
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ using QSB.Player;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.ConversationSync.Patches
|
||||
{
|
||||
@ -18,8 +17,6 @@ namespace QSB.ConversationSync.Patches
|
||||
QSBCore.HarmonyHelper.AddPrefix<CharacterDialogueTree>("InputDialogueOption", typeof(ConversationPatches), nameof(Tree_InputDialogueOption));
|
||||
QSBCore.HarmonyHelper.AddPostfix<CharacterDialogueTree>("StartConversation", typeof(ConversationPatches), nameof(Tree_StartConversation));
|
||||
QSBCore.HarmonyHelper.AddPrefix<CharacterDialogueTree>("EndConversation", typeof(ConversationPatches), nameof(Tree_EndConversation));
|
||||
QSBCore.HarmonyHelper.AddPrefix<CharacterAnimController>("OnAnimatorIK", typeof(ConversationPatches), nameof(AnimController_OnAnimatorIK));
|
||||
QSBCore.HarmonyHelper.AddPrefix<CharacterAnimController>("OnZoneExit", typeof(ConversationPatches), nameof(AnimController_OnZoneExit));
|
||||
}
|
||||
|
||||
public override void DoUnpatches()
|
||||
@ -28,8 +25,6 @@ namespace QSB.ConversationSync.Patches
|
||||
QSBCore.HarmonyHelper.Unpatch<CharacterDialogueTree>("InputDialogueOption");
|
||||
QSBCore.HarmonyHelper.Unpatch<CharacterDialogueTree>("StartConversation");
|
||||
QSBCore.HarmonyHelper.Unpatch<CharacterDialogueTree>("EndConversation");
|
||||
QSBCore.HarmonyHelper.Unpatch<CharacterAnimController>("OnAnimatorIK");
|
||||
QSBCore.HarmonyHelper.Unpatch<CharacterAnimController>("OnZoneExit");
|
||||
}
|
||||
|
||||
public static void Tree_StartConversation(CharacterDialogueTree __instance)
|
||||
@ -82,45 +77,5 @@ namespace QSB.ConversationSync.Patches
|
||||
QSBCore.UnityEvents.RunWhen(() => QSBPlayerManager.LocalPlayer.CurrentDialogueID != -1,
|
||||
() => ConversationManager.Instance.SendCharacterDialogue(QSBPlayerManager.LocalPlayer.CurrentDialogueID, key));
|
||||
}
|
||||
|
||||
public static bool AnimController_OnAnimatorIK(float ___headTrackingWeight,
|
||||
bool ___lookOnlyWhenTalking,
|
||||
bool ____playerInHeadZone,
|
||||
bool ____inConversation,
|
||||
ref float ____currentLookWeight,
|
||||
ref Vector3 ____currentLookTarget,
|
||||
DampedSpring3D ___lookSpring,
|
||||
Animator ____animator,
|
||||
CharacterDialogueTree ____dialogueTree)
|
||||
{
|
||||
var playerId = ConversationManager.Instance.GetPlayerTalkingToTree(____dialogueTree);
|
||||
Vector3 position;
|
||||
if (playerId == uint.MaxValue)
|
||||
{
|
||||
position = Locator.GetActiveCamera().transform.position;
|
||||
}
|
||||
else
|
||||
{
|
||||
var player = QSBPlayerManager.GetPlayer(playerId);
|
||||
position = player.CameraBody == null
|
||||
? Locator.GetActiveCamera().transform.position
|
||||
: player.CameraBody.transform.position;
|
||||
}
|
||||
var localPosition = ____animator.transform.InverseTransformPoint(position);
|
||||
var targetWeight = ___headTrackingWeight * Mathf.Min(1, !___lookOnlyWhenTalking
|
||||
? !____playerInHeadZone ? 0 : 1
|
||||
: !____inConversation || !____playerInHeadZone ? 0 : 1);
|
||||
____currentLookWeight = Mathf.Lerp(____currentLookWeight, targetWeight, Time.deltaTime * 2f);
|
||||
____currentLookTarget = ___lookSpring.Update(____currentLookTarget, localPosition, Time.deltaTime);
|
||||
____animator.SetLookAtPosition(____animator.transform.TransformPoint(____currentLookTarget));
|
||||
____animator.SetLookAtWeight(____currentLookWeight);
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool AnimController_OnZoneExit(CharacterDialogueTree ____dialogueTree)
|
||||
{
|
||||
var playerId = ConversationManager.Instance.GetPlayerTalkingToTree(____dialogueTree);
|
||||
return playerId == uint.MaxValue;
|
||||
}
|
||||
}
|
||||
}
|
@ -60,5 +60,8 @@
|
||||
public static string QSBExitPlatform = "QSBExitPlatform";
|
||||
public static string QSBCampfireState = "QSBCampfireState";
|
||||
public static string QSBMarshmallowEvent = "QSBMarshmallowEvent";
|
||||
public static string QSBAnimTrigger = "QSBAnimTrigger";
|
||||
public static string QSBEnterHeadZone = "QSBEnterHeadZone";
|
||||
public static string QSBExitHeadZone = "QSBExitHeadZone";
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
public enum EventType
|
||||
{
|
||||
ServerTime,
|
||||
AnimTrigger,
|
||||
Crouch,
|
||||
PlayerState,
|
||||
PlayerStatesRequest,
|
||||
FlashlightActiveChange,
|
||||
@ -41,6 +41,7 @@
|
||||
PlayerKick,
|
||||
CampfireState,
|
||||
Roasting,
|
||||
MarshmallowEvent
|
||||
MarshmallowEvent,
|
||||
AnimTrigger
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
using OWML.Common;
|
||||
using QSB.Animation.Events;
|
||||
using QSB.Animation.Player.Events;
|
||||
using QSB.CampfireSync.Events;
|
||||
using QSB.ConversationSync.Events;
|
||||
using QSB.DeathSync.Events;
|
||||
@ -51,6 +51,7 @@ namespace QSB.Events
|
||||
new PlayerKickEvent(),
|
||||
new EnterExitRoastingEvent(),
|
||||
new MarshmallowEventEvent(),
|
||||
new AnimationTriggerEvent(),
|
||||
// World Objects
|
||||
new ElevatorEvent(),
|
||||
new GeyserEvent(),
|
||||
|
@ -1,5 +1,5 @@
|
||||
using OWML.Common;
|
||||
using QSB.Animation;
|
||||
using QSB.Animation.Player;
|
||||
using QSB.Events;
|
||||
using QSB.Instruments.QSBCamera;
|
||||
using QSB.Player;
|
||||
|
@ -1,5 +1,6 @@
|
||||
using OWML.Common;
|
||||
using QSB.Events;
|
||||
using QSB.OrbSync.TransformSync;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using QSB.WorldSync.Events;
|
||||
@ -51,9 +52,9 @@ namespace QSB.OrbSync.Events
|
||||
private static void HandleServer(WorldObjectMessage message)
|
||||
{
|
||||
var fromPlayer = QNetworkServer.connections.First(x => x.GetPlayerId() == message.FromId);
|
||||
if (QSBWorldSync.OrbSyncList == null || QSBWorldSync.OrbSyncList.Count == 0)
|
||||
if (NomaiOrbTransformSync.OrbTransformSyncs == null || NomaiOrbTransformSync.OrbTransformSyncs.Count == 0)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - OrbSyncList is empty or null. (ID {message.ObjectId})", MessageType.Error);
|
||||
DebugLog.ToConsole($"Error - OrbTransformSyncs is empty or null. (ID {message.ObjectId})", MessageType.Error);
|
||||
return;
|
||||
}
|
||||
if (QSBWorldSync.OldOrbList == null || QSBWorldSync.OldOrbList.Count == 0)
|
||||
@ -65,8 +66,8 @@ namespace QSB.OrbSync.Events
|
||||
{
|
||||
DebugLog.ToConsole("Error - FromPlayer is null!", MessageType.Error);
|
||||
}
|
||||
var orbSync = QSBWorldSync.OrbSyncList
|
||||
.FirstOrDefault(x => x.AttachedOrb == QSBWorldSync.OldOrbList[message.ObjectId]);
|
||||
var orbSync = NomaiOrbTransformSync.OrbTransformSyncs
|
||||
.FirstOrDefault(x => x.AttachedObject == QSBWorldSync.OldOrbList[message.ObjectId].gameObject);
|
||||
if (orbSync == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - No orb found for user event. (ID {message.ObjectId})", MessageType.Error);
|
||||
@ -78,6 +79,7 @@ namespace QSB.OrbSync.Events
|
||||
DebugLog.ToConsole($"Error - Orb identity is null. (ID {message.ObjectId})", MessageType.Error);
|
||||
return;
|
||||
}
|
||||
DebugLog.DebugWrite($"Orb {message.ObjectId} to owner {message.FromId}");
|
||||
if (orbIdentity.ClientAuthorityOwner != null && orbIdentity.ClientAuthorityOwner != fromPlayer)
|
||||
{
|
||||
orbIdentity.RemoveClientAuthority(orbIdentity.ClientAuthorityOwner);
|
||||
@ -88,9 +90,9 @@ namespace QSB.OrbSync.Events
|
||||
|
||||
private static void HandleClient(WorldObjectMessage message)
|
||||
{
|
||||
if (QSBWorldSync.OrbSyncList == null || QSBWorldSync.OrbSyncList.Count == 0)
|
||||
if (NomaiOrbTransformSync.OrbTransformSyncs == null || NomaiOrbTransformSync.OrbTransformSyncs.Count == 0)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - OrbSyncList is empty or null. (ID {message.ObjectId})", MessageType.Error);
|
||||
DebugLog.ToConsole($"Error - OrbTransformSyncs is empty or null. (ID {message.ObjectId})", MessageType.Error);
|
||||
return;
|
||||
}
|
||||
if (QSBWorldSync.OldOrbList == null || QSBWorldSync.OldOrbList.Count == 0)
|
||||
@ -98,13 +100,14 @@ namespace QSB.OrbSync.Events
|
||||
DebugLog.ToConsole($"Error - OldOrbList is empty or null. (ID {message.ObjectId})", MessageType.Error);
|
||||
return;
|
||||
}
|
||||
if (!QSBWorldSync.OrbSyncList.Any(x => x.AttachedOrb == QSBWorldSync.OldOrbList[message.ObjectId]))
|
||||
if (!NomaiOrbTransformSync.OrbTransformSyncs.Any(x => x.AttachedObject == QSBWorldSync.OldOrbList[message.ObjectId].gameObject))
|
||||
{
|
||||
DebugLog.ToConsole($"Error - No NomaiOrbTransformSync has AttachedOrb with objectId {message.ObjectId}!");
|
||||
return;
|
||||
}
|
||||
var orb = QSBWorldSync.OrbSyncList
|
||||
.First(x => x.AttachedOrb == QSBWorldSync.OldOrbList[message.ObjectId]);
|
||||
DebugLog.DebugWrite($"Orb {message.ObjectId} to owner {message.FromId}");
|
||||
var orb = NomaiOrbTransformSync.OrbTransformSyncs
|
||||
.First(x => x.AttachedObject == QSBWorldSync.OldOrbList[message.ObjectId].gameObject);
|
||||
orb.enabled = true;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using OWML.Common;
|
||||
using QSB.OrbSync.TransformSync;
|
||||
using QSB.OrbSync.WorldObjects;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
@ -23,8 +24,8 @@ namespace QSB.OrbSync
|
||||
QSBWorldSync.OldOrbList = Resources.FindObjectsOfTypeAll<NomaiInterfaceOrb>().ToList();
|
||||
if (QSBCore.IsServer)
|
||||
{
|
||||
QSBWorldSync.OrbSyncList.ForEach(x => QNetworkServer.Destroy(x.gameObject));
|
||||
QSBWorldSync.OrbSyncList.Clear();
|
||||
NomaiOrbTransformSync.OrbTransformSyncs.ForEach(x => QNetworkServer.Destroy(x.gameObject));
|
||||
NomaiOrbTransformSync.OrbTransformSyncs.Clear();
|
||||
QSBWorldSync.OldOrbList.ForEach(x => QNetworkServer.Spawn(Instantiate(QSBNetworkManager.Instance.OrbPrefab)));
|
||||
}
|
||||
DebugLog.DebugWrite($"Finished orb build with {QSBWorldSync.OldOrbList.Count} orbs.", MessageType.Success);
|
||||
|
@ -1,81 +1,51 @@
|
||||
using QSB.Utility;
|
||||
using QSB.TransformSync;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using QuantumUNET;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.OrbSync.TransformSync
|
||||
{
|
||||
public class NomaiOrbTransformSync : QNetworkBehaviour
|
||||
internal class NomaiOrbTransformSync : UnparentedBaseTransformSync
|
||||
{
|
||||
public NomaiInterfaceOrb AttachedOrb { get; private set; }
|
||||
public Transform OrbTransform { get; private set; }
|
||||
public static List<NomaiOrbTransformSync> OrbTransformSyncs = new List<NomaiOrbTransformSync>();
|
||||
|
||||
private int Index => QSBWorldSync.OrbSyncList.IndexOf(this);
|
||||
|
||||
private bool _isInitialized;
|
||||
private int _index => OrbTransformSyncs.IndexOf(this);
|
||||
private bool _isReady;
|
||||
private Transform _orbParent;
|
||||
|
||||
public override void OnStartClient()
|
||||
{
|
||||
DontDestroyOnLoad(this);
|
||||
QSBWorldSync.OrbSyncList.Add(this);
|
||||
OrbTransformSyncs.Add(this);
|
||||
|
||||
QSBCore.UnityEvents.RunWhen(() => QSBCore.HasWokenUp, () => QSBCore.UnityEvents.FireOnNextUpdate(OnReady));
|
||||
}
|
||||
|
||||
private void OnReady()
|
||||
{
|
||||
if (QSBWorldSync.OldOrbList == null || QSBWorldSync.OldOrbList.Count < Index)
|
||||
if (QSBWorldSync.OldOrbList == null || QSBWorldSync.OldOrbList.Count < _index)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - OldOrbList is null or does not contain index {Index}.", OWML.Common.MessageType.Error);
|
||||
DebugLog.ToConsole($"Error - OldOrbList is null or does not contain index {_index}.", OWML.Common.MessageType.Error);
|
||||
return;
|
||||
}
|
||||
AttachedOrb = QSBWorldSync.OldOrbList[Index];
|
||||
_isReady = true;
|
||||
}
|
||||
|
||||
public void OnDestroy() => QSBWorldSync.OrbSyncList.Remove(this);
|
||||
|
||||
protected void Init()
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
OrbTransform = AttachedOrb.transform;
|
||||
_orbParent = AttachedOrb.GetAttachedOWRigidbody().GetOrigParent();
|
||||
_isInitialized = true;
|
||||
OrbTransformSyncs.Remove(this);
|
||||
base.OnDestroy();
|
||||
}
|
||||
|
||||
public void Update()
|
||||
protected override void Init()
|
||||
{
|
||||
if (!_isInitialized && _isReady)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
else if (_isInitialized && !_isReady)
|
||||
{
|
||||
_isInitialized = false;
|
||||
}
|
||||
|
||||
if (OrbTransform == null || !_isInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateTransform();
|
||||
base.Init();
|
||||
SetReferenceTransform(AttachedObject.GetAttachedOWRigidbody().GetOrigParent());
|
||||
}
|
||||
|
||||
private void UpdateTransform()
|
||||
{
|
||||
if (HasAuthority)
|
||||
{
|
||||
transform.position = _orbParent.InverseTransformPoint(OrbTransform.position);
|
||||
transform.rotation = OrbTransform.rotation;
|
||||
return;
|
||||
}
|
||||
if (transform.position != Vector3.zero)
|
||||
{
|
||||
OrbTransform.position = _orbParent.TransformPoint(transform.position);
|
||||
OrbTransform.rotation = transform.rotation;
|
||||
}
|
||||
}
|
||||
protected override GameObject InitLocalTransform() => QSBWorldSync.OldOrbList[_index].gameObject;
|
||||
protected override GameObject InitRemoteTransform() => QSBWorldSync.OldOrbList[_index].gameObject;
|
||||
|
||||
public override bool IsReady => _isReady;
|
||||
public override bool UseInterpolation => false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using OWML.Common;
|
||||
using QSB.Animation.Patches;
|
||||
using QSB.CampfireSync.Patches;
|
||||
using QSB.ConversationSync.Patches;
|
||||
using QSB.DeathSync.Patches;
|
||||
@ -51,7 +52,9 @@ namespace QSB.Patches
|
||||
new PoolPatches(),
|
||||
new CampfirePatches(),
|
||||
new RoastingPatches(),
|
||||
new PlayerPatches()
|
||||
new PlayerPatches(),
|
||||
new PlayerAnimationPatches(),
|
||||
new CharacterAnimationPatches()
|
||||
};
|
||||
|
||||
DebugLog.DebugWrite("Patch Manager ready.", MessageType.Success);
|
||||
|
@ -7,6 +7,8 @@
|
||||
EnterShrine = 2,
|
||||
ExitShrine = 3,
|
||||
EnterPlatform = 4,
|
||||
ExitPlatform = 5
|
||||
ExitPlatform = 5,
|
||||
EnterHeadZone = 6,
|
||||
ExitHeadZone = 7
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
using QSB.Events;
|
||||
using QSB.Animation.Character.WorldObjects;
|
||||
using QSB.Events;
|
||||
using QSB.PoolSync;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using QSB.WorldSync.Events;
|
||||
|
||||
namespace QSB.Player.Events
|
||||
@ -17,6 +19,8 @@ namespace QSB.Player.Events
|
||||
GlobalMessenger.AddListener(EventNames.QSBExitShrine, () => Handler(EnterLeaveType.ExitShrine));
|
||||
GlobalMessenger<int>.AddListener(EventNames.QSBEnterPlatform, (int id) => Handler(EnterLeaveType.EnterPlatform, id));
|
||||
GlobalMessenger<int>.AddListener(EventNames.QSBExitPlatform, (int id) => Handler(EnterLeaveType.ExitPlatform, id));
|
||||
GlobalMessenger<int>.AddListener(EventNames.QSBEnterHeadZone, (int id) => Handler(EnterLeaveType.EnterHeadZone, id));
|
||||
GlobalMessenger<int>.AddListener(EventNames.QSBExitHeadZone, (int id) => Handler(EnterLeaveType.ExitHeadZone, id));
|
||||
}
|
||||
|
||||
public override void CloseListener()
|
||||
@ -64,6 +68,12 @@ namespace QSB.Player.Events
|
||||
CustomNomaiRemoteCameraPlatform.CustomPlatformList[message.ObjectId]
|
||||
.OnRemotePlayerExit(message.AboutId);
|
||||
break;
|
||||
case EnterLeaveType.EnterHeadZone:
|
||||
QSBWorldSync.GetWorldFromId<QSBCharacterAnimController>(message.ObjectId).AddPlayerToHeadZone(player);
|
||||
break;
|
||||
case EnterLeaveType.ExitHeadZone:
|
||||
QSBWorldSync.GetWorldFromId<QSBCharacterAnimController>(message.ObjectId).RemovePlayerFromHeadZone(player);
|
||||
break;
|
||||
default:
|
||||
DebugLog.ToConsole($"Warning - Unknown EnterLeaveType : {message.EnumValue}", OWML.Common.MessageType.Warning);
|
||||
break;
|
||||
|
@ -1,4 +1,4 @@
|
||||
using QSB.Animation;
|
||||
using QSB.Animation.Player;
|
||||
using QSB.CampfireSync.WorldObjects;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.ProbeSync;
|
||||
|
@ -135,5 +135,22 @@ namespace QSB.Player
|
||||
renderer.enabled = visible;
|
||||
}
|
||||
}
|
||||
|
||||
public static PlayerInfo GetClosestPlayerToWorldPoint(Vector3 worldPoint, bool includeLocalPlayer)
|
||||
{
|
||||
return includeLocalPlayer
|
||||
? GetClosestPlayerToWorldPoint(PlayerList, worldPoint)
|
||||
: GetClosestPlayerToWorldPoint(PlayerList.Where(x => x != LocalPlayer).ToList(), worldPoint);
|
||||
}
|
||||
|
||||
public static PlayerInfo GetClosestPlayerToWorldPoint(List<PlayerInfo> playerList, Vector3 worldPoint)
|
||||
{
|
||||
if (playerList.Count == 0)
|
||||
{
|
||||
DebugLog.DebugWrite($"Error - Cannot get closest player from empty player list.", MessageType.Error);
|
||||
return null;
|
||||
}
|
||||
return playerList.Where(x => x.PlayerStates.IsReady).OrderBy(x => Vector3.Distance(x.Body.transform.position, worldPoint)).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@ using UnityEngine;
|
||||
|
||||
namespace QSB.Player.TransformSync
|
||||
{
|
||||
public class PlayerCameraSync : QSBNetworkTransform
|
||||
public class PlayerCameraSync : SectoredTransformSync
|
||||
{
|
||||
protected override GameObject InitLocalTransform()
|
||||
{
|
||||
@ -47,5 +47,7 @@ namespace QSB.Player.TransformSync
|
||||
&& QSBPlayerManager.PlayerExists(Player.PlayerId)
|
||||
&& NetId.Value != uint.MaxValue
|
||||
&& NetId.Value != 0U;
|
||||
|
||||
public override bool UseInterpolation => true;
|
||||
}
|
||||
}
|
@ -1,13 +1,14 @@
|
||||
using QSB.Animation;
|
||||
using QSB.Animation.Player;
|
||||
using QSB.Instruments;
|
||||
using QSB.TransformSync;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Player.TransformSync
|
||||
{
|
||||
public class PlayerTransformSync : QSBNetworkTransform
|
||||
public class PlayerTransformSync : SectoredTransformSync
|
||||
{
|
||||
public static PlayerTransformSync LocalInstance { get; private set; }
|
||||
public override bool UseInterpolation => true;
|
||||
|
||||
static PlayerTransformSync() => AnimControllerPatch.Init();
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
using OWML.Common;
|
||||
using OWML.Utils;
|
||||
using QSB.Animation;
|
||||
using QSB.Animation.Player;
|
||||
using QSB.Events;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
|
@ -7,14 +7,18 @@ using UnityEngine;
|
||||
|
||||
namespace QSB.ProbeSync.TransformSync
|
||||
{
|
||||
public class PlayerProbeSync : QSBNetworkTransform
|
||||
public class PlayerProbeSync : SectoredTransformSync
|
||||
{
|
||||
public static PlayerProbeSync LocalInstance { get; private set; }
|
||||
|
||||
protected override float DistanceLeeway => 10f;
|
||||
public override bool UseInterpolation => true;
|
||||
|
||||
public override void OnStartAuthority()
|
||||
=> LocalInstance = this;
|
||||
{
|
||||
DebugLog.DebugWrite($"OnStartAuthority probe");
|
||||
LocalInstance = this;
|
||||
}
|
||||
|
||||
private Transform GetProbe() =>
|
||||
Locator.GetProbe().transform.Find("CameraPivot").Find("Geometry");
|
||||
|
@ -102,14 +102,20 @@
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Animation\AnimationSync.cs" />
|
||||
<Compile Include="Animation\AnimationType.cs" />
|
||||
<Compile Include="Animation\Events\CrouchEvent.cs" />
|
||||
<Compile Include="Animation\AnimatorMirror.cs" />
|
||||
<Compile Include="Animation\AnimControllerPatch.cs" />
|
||||
<Compile Include="Animation\AnimFloatParam.cs" />
|
||||
<Compile Include="Animation\CrouchSync.cs" />
|
||||
<Compile Include="Animation\PlayerHeadRotationSync.cs" />
|
||||
<Compile Include="Animation\Character\CharacterAnimManager.cs" />
|
||||
<Compile Include="Animation\Character\Patches\CharacterAnimationPatches.cs" />
|
||||
<Compile Include="Animation\Character\WorldObjects\QSBCharacterAnimController.cs" />
|
||||
<Compile Include="Animation\Player\AnimationSync.cs" />
|
||||
<Compile Include="Animation\Player\AnimationType.cs" />
|
||||
<Compile Include="Animation\Player\Events\AnimationTriggerEvent.cs" />
|
||||
<Compile Include="Animation\Player\Events\AnimationTriggerMessage.cs" />
|
||||
<Compile Include="Animation\Player\Events\CrouchEvent.cs" />
|
||||
<Compile Include="Animation\Player\AnimatorMirror.cs" />
|
||||
<Compile Include="Animation\Player\AnimControllerPatch.cs" />
|
||||
<Compile Include="Animation\Player\AnimFloatParam.cs" />
|
||||
<Compile Include="Animation\Player\CrouchSync.cs" />
|
||||
<Compile Include="Animation\Player\Patches\PlayerAnimationPatches.cs" />
|
||||
<Compile Include="Animation\Player\PlayerHeadRotationSync.cs" />
|
||||
<Compile Include="CampfireSync\CampfireManager.cs" />
|
||||
<Compile Include="CampfireSync\Events\CampfireStateEvent.cs" />
|
||||
<Compile Include="CampfireSync\Patches\CampfirePatches.cs" />
|
||||
@ -132,7 +138,7 @@
|
||||
<Compile Include="Events\EventNames.cs" />
|
||||
<Compile Include="DeathSync\Events\PlayerDeathEvent.cs" />
|
||||
<Compile Include="Events\IQSBEvent.cs" />
|
||||
<Compile Include="Animation\Events\ChangeAnimTypeEvent.cs" />
|
||||
<Compile Include="Animation\Player\Events\ChangeAnimTypeEvent.cs" />
|
||||
<Compile Include="FrequencySync\Events\IdentifyFrequencyEvent.cs" />
|
||||
<Compile Include="FrequencySync\Events\IdentifySignalEvent.cs" />
|
||||
<Compile Include="FrequencySync\Patches\FrequencyPatches.cs" />
|
||||
@ -142,6 +148,7 @@
|
||||
<Compile Include="Instruments\QSBCamera\CameraMode.cs" />
|
||||
<Compile Include="Instruments\InstrumentsManager.cs" />
|
||||
<Compile Include="Messaging\BoolMessage.cs" />
|
||||
<Compile Include="OrbSync\TransformSync\NomaiOrbTransformSync.cs" />
|
||||
<Compile Include="Player\Patches\PlayerPatches.cs" />
|
||||
<Compile Include="Player\PlayerState.cs" />
|
||||
<Compile Include="PoolSync\CustomNomaiRemoteCameraPlatform.cs" />
|
||||
@ -231,7 +238,10 @@
|
||||
<Compile Include="StatueSync\Patches\StatuePatches.cs" />
|
||||
<Compile Include="StatueSync\StatueManager.cs" />
|
||||
<Compile Include="RoastingSync\TransformSync\RoastingStickTransformSync.cs" />
|
||||
<Compile Include="TransformSync\QSBNetworkTransform.cs" />
|
||||
<Compile Include="TransformSync\BaseTransformSync.cs" />
|
||||
<Compile Include="TransformSync\IntermediaryTransform.cs" />
|
||||
<Compile Include="TransformSync\SectoredTransformSync.cs" />
|
||||
<Compile Include="TransformSync\UnparentedBaseTransformSync.cs" />
|
||||
<Compile Include="TranslationSync\Events\SetAsTranslatedEvent.cs" />
|
||||
<Compile Include="TranslationSync\Events\SetAsTranslatedMessage.cs" />
|
||||
<Compile Include="TranslationSync\NomaiTextType.cs" />
|
||||
@ -247,9 +257,8 @@
|
||||
<Compile Include="Player\Events\PlayerJoinEvent.cs" />
|
||||
<Compile Include="ProbeSync\Events\PlayerProbeEvent.cs" />
|
||||
<Compile Include="Player\Events\PlayerReadyEvent.cs" />
|
||||
<Compile Include="OrbSync\TransformSync\NomaiOrbTransformSync.cs" />
|
||||
<Compile Include="Player\Events\PlayerStatesRequestEvent.cs" />
|
||||
<Compile Include="Animation\Events\PlayerSuitEvent.cs" />
|
||||
<Compile Include="Animation\Player\Events\PlayerSuitEvent.cs" />
|
||||
<Compile Include="TimeSync\Events\ServerTimeEvent.cs" />
|
||||
<Compile Include="GeyserSync\Events\GeyserEvent.cs" />
|
||||
<Compile Include="GeyserSync\GeyserManager.cs" />
|
||||
|
@ -1,6 +1,7 @@
|
||||
using OWML.Common;
|
||||
using OWML.ModHelper;
|
||||
using OWML.Utils;
|
||||
using QSB.Animation.Character;
|
||||
using QSB.CampfireSync;
|
||||
using QSB.ConversationSync;
|
||||
using QSB.ElevatorSync;
|
||||
@ -111,6 +112,7 @@ namespace QSB
|
||||
gameObject.AddComponent<StatueManager>();
|
||||
gameObject.AddComponent<PoolManager>();
|
||||
gameObject.AddComponent<CampfireManager>();
|
||||
gameObject.AddComponent<CharacterAnimManager>();
|
||||
|
||||
DebugBoxManager.Init();
|
||||
|
||||
@ -147,9 +149,13 @@ namespace QSB
|
||||
}
|
||||
|
||||
var offset3 = 10f;
|
||||
GUI.Label(new Rect(420, offset3, 400f, 20f), $"Current sector : {PlayerTransformSync.LocalInstance.ReferenceSector.Name}");
|
||||
var playerSector = PlayerTransformSync.LocalInstance.ReferenceSector;
|
||||
var playerText = playerSector == null ? "NULL" : playerSector.Name;
|
||||
GUI.Label(new Rect(420, offset3, 400f, 20f), $"Current sector : {playerText}");
|
||||
offset3 += _debugLineSpacing;
|
||||
GUI.Label(new Rect(420, offset3, 400f, 20f), $"Probe sector : {PlayerProbeSync.LocalInstance.ReferenceSector.Name}");
|
||||
var probeSector = PlayerProbeSync.LocalInstance.ReferenceSector;
|
||||
var probeText = probeSector == null ? "NULL" : probeSector.Name;
|
||||
GUI.Label(new Rect(420, offset3, 400f, 20f), $"Probe sector : {probeText}");
|
||||
offset3 += _debugLineSpacing;
|
||||
|
||||
var offset2 = 10f;
|
||||
|
@ -1,6 +1,6 @@
|
||||
using OWML.Common;
|
||||
using OWML.Utils;
|
||||
using QSB.Animation;
|
||||
using QSB.Animation.Player;
|
||||
using QSB.DeathSync;
|
||||
using QSB.Events;
|
||||
using QSB.Instruments;
|
||||
@ -215,7 +215,7 @@ namespace QSB
|
||||
QSBPlayerManager.PlayerList.ForEach(player => player.HudMarker?.Remove());
|
||||
|
||||
RemoveWorldObjects();
|
||||
QSBWorldSync.OrbSyncList.Clear();
|
||||
NomaiOrbTransformSync.OrbTransformSyncs.Clear();
|
||||
QSBWorldSync.OldDialogueTrees.Clear();
|
||||
|
||||
if (_everConnected)
|
||||
@ -237,7 +237,7 @@ namespace QSB
|
||||
base.OnServerDisconnect(connection);
|
||||
DebugLog.DebugWrite("OnServerDisconnect", MessageType.Info);
|
||||
|
||||
foreach (var item in QSBWorldSync.OrbSyncList)
|
||||
foreach (var item in NomaiOrbTransformSync.OrbTransformSyncs)
|
||||
{
|
||||
var identity = item.GetComponent<QNetworkIdentity>();
|
||||
if (identity.ClientAuthorityOwner == connection)
|
||||
|
@ -103,7 +103,7 @@ namespace QSB.QuantumSync.WorldObjects
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (GetAttachedShapes().Any(x => x.gameObject.activeInHierarchy))
|
||||
if (GetAttachedShapes().Any(x => x.isActiveAndEnabled))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -7,8 +7,10 @@ using UnityEngine;
|
||||
|
||||
namespace QSB.RoastingSync.TransformSync
|
||||
{
|
||||
internal class RoastingStickTransformSync : QSBNetworkTransform
|
||||
internal class RoastingStickTransformSync : SectoredTransformSync
|
||||
{
|
||||
public override bool UseInterpolation => true;
|
||||
|
||||
private Transform _stickTip;
|
||||
private Transform _networkStickTip => gameObject.transform.GetChild(0);
|
||||
private const float SmoothTime = 0.1f;
|
||||
|
@ -20,7 +20,7 @@ namespace QSB.SectorSync
|
||||
|
||||
public void Invoke()
|
||||
{
|
||||
foreach (var sync in QSBNetworkTransform.NetworkTransformList)
|
||||
foreach (var sync in SectoredTransformSync.SectoredNetworkTransformList)
|
||||
{
|
||||
if (sync.AttachedObject == null)
|
||||
{
|
||||
@ -64,7 +64,7 @@ namespace QSB.SectorSync
|
||||
IsReady = QSBWorldSync.GetWorldObjects<QSBSector>().Any();
|
||||
}
|
||||
|
||||
private void CheckTransformSyncSector(QSBNetworkTransform transformSync)
|
||||
private void CheckTransformSyncSector(SectoredTransformSync transformSync)
|
||||
{
|
||||
var attachedObject = transformSync.AttachedObject;
|
||||
var closestSector = transformSync.SectorSync.GetClosestSector(attachedObject.transform);
|
||||
|
@ -4,9 +4,10 @@ using UnityEngine;
|
||||
|
||||
namespace QSB.ShipSync.TransformSync
|
||||
{
|
||||
public class ShipTransformSync : QSBNetworkTransform
|
||||
public class ShipTransformSync : SectoredTransformSync
|
||||
{
|
||||
protected override float DistanceLeeway => 20f;
|
||||
public override bool UseInterpolation => true;
|
||||
|
||||
private Transform GetShipModel() => Locator.GetShipTransform();
|
||||
|
||||
|
@ -1,30 +1,30 @@
|
||||
using OWML.Common;
|
||||
using QSB.Player;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.SectorSync.WorldObjects;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using QuantumUNET.Components;
|
||||
using QuantumUNET.Transport;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.TransformSync
|
||||
{
|
||||
public abstract class QSBNetworkTransform : QNetworkTransform
|
||||
/*
|
||||
* Rewrite number : 4
|
||||
* God has cursed me for my hubris, and my work is never finished.
|
||||
*/
|
||||
|
||||
public abstract class BaseTransformSync : QNetworkTransform
|
||||
{
|
||||
public uint AttachedNetId => NetIdentity?.NetId.Value ?? uint.MaxValue;
|
||||
public uint PlayerId => NetIdentity.RootIdentity?.NetId.Value ?? NetIdentity.NetId.Value;
|
||||
public PlayerInfo Player => QSBPlayerManager.GetPlayer(PlayerId);
|
||||
|
||||
public static List<QSBNetworkTransform> NetworkTransformList = new List<QSBNetworkTransform>();
|
||||
|
||||
public QSBSector ReferenceSector { get; set; }
|
||||
public Transform ReferenceTransform { get; set; }
|
||||
public GameObject AttachedObject { get; set; }
|
||||
public SectorSync.SectorSync SectorSync { get; private set; }
|
||||
|
||||
public abstract bool IsReady { get; }
|
||||
public abstract bool UseInterpolation { get; }
|
||||
|
||||
protected abstract GameObject InitLocalTransform();
|
||||
protected abstract GameObject InitRemoteTransform();
|
||||
@ -35,6 +35,7 @@ namespace QSB.TransformSync
|
||||
private float _previousDistance;
|
||||
private Vector3 _positionSmoothVelocity;
|
||||
private Quaternion _rotationSmoothVelocity;
|
||||
protected IntermediaryTransform _intermediaryTransform;
|
||||
|
||||
public virtual void Start()
|
||||
{
|
||||
@ -42,10 +43,8 @@ namespace QSB.TransformSync
|
||||
.Where(x => x.NetId.Value <= NetId.Value).OrderBy(x => x.NetId.Value).Last();
|
||||
NetIdentity.SetRootIdentity(lowestBound.NetIdentity);
|
||||
|
||||
SectorSync = gameObject.AddComponent<SectorSync.SectorSync>();
|
||||
|
||||
NetworkTransformList.Add(this);
|
||||
DontDestroyOnLoad(gameObject);
|
||||
_intermediaryTransform = new IntermediaryTransform(transform);
|
||||
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
|
||||
}
|
||||
|
||||
@ -55,75 +54,61 @@ namespace QSB.TransformSync
|
||||
{
|
||||
Destroy(AttachedObject);
|
||||
}
|
||||
NetworkTransformList.Remove(this);
|
||||
QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
|
||||
if (SectorSync != null)
|
||||
{
|
||||
Destroy(SectorSync);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSceneLoaded(OWScene scene, bool isInUniverse) =>
|
||||
_isInitialized = false;
|
||||
|
||||
protected void Init()
|
||||
protected virtual void Init()
|
||||
{
|
||||
AttachedObject = HasAuthority ? InitLocalTransform() : InitRemoteTransform();
|
||||
SetReferenceSector(SectorSync.GetClosestSector(AttachedObject.transform));
|
||||
_isInitialized = true;
|
||||
}
|
||||
|
||||
public override void SerializeTransform(QNetworkWriter writer)
|
||||
{
|
||||
if (ReferenceSector != null)
|
||||
if (_intermediaryTransform == null)
|
||||
{
|
||||
writer.Write(ReferenceSector.ObjectId);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write(-1);
|
||||
_intermediaryTransform = new IntermediaryTransform(transform);
|
||||
}
|
||||
|
||||
writer.Write(transform.localPosition);
|
||||
SerializeRotation(writer, transform.localRotation);
|
||||
_prevPosition = transform.localPosition;
|
||||
_prevRotation = transform.localRotation;
|
||||
var worldPos = _intermediaryTransform.GetPosition();
|
||||
var worldRot = _intermediaryTransform.GetRotation();
|
||||
writer.Write(worldPos);
|
||||
SerializeRotation(writer, worldRot);
|
||||
_prevPosition = worldPos;
|
||||
_prevRotation = worldRot;
|
||||
}
|
||||
|
||||
public override void DeserializeTransform(QNetworkReader reader)
|
||||
{
|
||||
if (!QSBCore.HasWokenUp)
|
||||
{
|
||||
reader.ReadInt32();
|
||||
reader.ReadVector3();
|
||||
DeserializeRotation(reader);
|
||||
return;
|
||||
}
|
||||
|
||||
var sectorId = reader.ReadInt32();
|
||||
var sector = sectorId == -1
|
||||
? null
|
||||
: QSBWorldSync.GetWorldFromId<QSBSector>(sectorId);
|
||||
|
||||
if (sector != ReferenceSector)
|
||||
{
|
||||
SetReferenceSector(sector);
|
||||
}
|
||||
|
||||
var localPosition = reader.ReadVector3();
|
||||
var localRotation = DeserializeRotation(reader);
|
||||
var pos = reader.ReadVector3();
|
||||
var rot = DeserializeRotation(reader);
|
||||
|
||||
if (HasAuthority)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
transform.localPosition = localPosition;
|
||||
transform.localRotation = localRotation;
|
||||
|
||||
if (transform.position == Vector3.zero)
|
||||
if (_intermediaryTransform == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - {PlayerId}.{GetType().Name} at (0,0,0)! - Given localPosition was {localPosition} at sector {sector?.Name}", MessageType.Warning);
|
||||
_intermediaryTransform = new IntermediaryTransform(transform);
|
||||
}
|
||||
|
||||
_intermediaryTransform.SetPosition(pos);
|
||||
_intermediaryTransform.SetRotation(rot);
|
||||
|
||||
if (_intermediaryTransform.GetPosition() == Vector3.zero)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - {PlayerId}.{GetType().Name} at (0,0,0)! - Given position was {pos}", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,47 +144,62 @@ namespace QSB.TransformSync
|
||||
{
|
||||
if (HasAuthority)
|
||||
{
|
||||
transform.position = AttachedObject.transform.position;
|
||||
transform.rotation = AttachedObject.transform.rotation;
|
||||
_intermediaryTransform.EncodePosition(AttachedObject.transform.position);
|
||||
_intermediaryTransform.EncodeRotation(AttachedObject.transform.rotation);
|
||||
return;
|
||||
}
|
||||
else
|
||||
var targetPos = _intermediaryTransform.GetTargetPosition_ParentedToReference();
|
||||
var targetRot = _intermediaryTransform.GetTargetRotation_ParentedToReference();
|
||||
if (targetPos != Vector3.zero && _intermediaryTransform.GetTargetPosition_Unparented() != Vector3.zero)
|
||||
{
|
||||
AttachedObject.transform.localPosition = SmartSmoothDamp(AttachedObject.transform.localPosition, transform.localPosition);
|
||||
AttachedObject.transform.localRotation = QuaternionHelper.SmoothDamp(AttachedObject.transform.localRotation, transform.localRotation, ref _rotationSmoothVelocity, SmoothTime);
|
||||
if (UseInterpolation)
|
||||
{
|
||||
AttachedObject.transform.localPosition = SmartSmoothDamp(AttachedObject.transform.localPosition, targetPos);
|
||||
AttachedObject.transform.localRotation = QuaternionHelper.SmoothDamp(AttachedObject.transform.localRotation, targetRot, ref _rotationSmoothVelocity, SmoothTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
AttachedObject.transform.localPosition = targetPos;
|
||||
AttachedObject.transform.localRotation = targetRot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool HasMoved()
|
||||
{
|
||||
var displacementMagnitude = (transform.localPosition - _prevPosition).magnitude;
|
||||
var displacementMagnitude = (_intermediaryTransform.GetPosition() - _prevPosition).magnitude;
|
||||
return displacementMagnitude > 1E-03f
|
||||
|| Quaternion.Angle(transform.localRotation, _prevRotation) > 1E-03f;
|
||||
|| Quaternion.Angle(_intermediaryTransform.GetRotation(), _prevRotation) > 1E-03f;
|
||||
}
|
||||
|
||||
public void SetReferenceSector(QSBSector sector)
|
||||
public void SetReferenceTransform(Transform transform)
|
||||
{
|
||||
if (ReferenceSector == sector)
|
||||
if (ReferenceTransform == transform)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ReferenceSector = sector;
|
||||
transform.SetParent(sector.Transform, true);
|
||||
ReferenceTransform = transform;
|
||||
_intermediaryTransform.SetReferenceTransform(transform);
|
||||
if (AttachedObject == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - AttachedObject was null for {PlayerId}.{GetType().Name} when trying to set reference sector to {sector.Name}. Waiting until not null...", MessageType.Warning);
|
||||
DebugLog.ToConsole($"Warning - AttachedObject was null for {PlayerId}.{GetType().Name} when trying to set reference transform to {transform.name}. Waiting until not null...", MessageType.Warning);
|
||||
QSBCore.UnityEvents.RunWhen(
|
||||
() => AttachedObject != null,
|
||||
() => ReparentAttachedObject(sector.Transform));
|
||||
() => ReparentAttachedObject(transform));
|
||||
return;
|
||||
}
|
||||
if (!HasAuthority)
|
||||
{
|
||||
ReparentAttachedObject(sector.Transform);
|
||||
ReparentAttachedObject(transform);
|
||||
}
|
||||
}
|
||||
|
||||
private void ReparentAttachedObject(Transform sectorTransform)
|
||||
{
|
||||
if (AttachedObject.transform.parent != null && AttachedObject.transform.parent.GetComponent<Sector>() == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Trying to reparent AttachedObject {AttachedObject.name} which wasnt attached to sector!", MessageType.Warning);
|
||||
}
|
||||
AttachedObject.transform.SetParent(sectorTransform, true);
|
||||
AttachedObject.transform.localScale = GetType() == typeof(PlayerTransformSync)
|
||||
? Vector3.one / 10
|
||||
@ -211,7 +211,6 @@ namespace QSB.TransformSync
|
||||
var distance = Vector3.Distance(currentPosition, targetPosition);
|
||||
if (distance > _previousDistance + DistanceLeeway)
|
||||
{
|
||||
DebugLog.DebugWrite($"Warning - {PlayerId}.{GetType().Name} moved too fast!", MessageType.Warning);
|
||||
_previousDistance = distance;
|
||||
return targetPosition;
|
||||
}
|
||||
@ -226,10 +225,10 @@ namespace QSB.TransformSync
|
||||
return;
|
||||
}
|
||||
|
||||
Popcron.Gizmos.Cube(transform.position, transform.rotation, Vector3.one / 2, Color.red);
|
||||
Popcron.Gizmos.Cube(_intermediaryTransform.GetTargetPosition_Unparented(), _intermediaryTransform.GetTargetRotation_Unparented(), Vector3.one / 2, Color.red);
|
||||
var color = HasMoved() ? Color.green : Color.yellow;
|
||||
Popcron.Gizmos.Cube(AttachedObject.transform.position, AttachedObject.transform.rotation, Vector3.one / 2, color);
|
||||
Popcron.Gizmos.Line(AttachedObject.transform.position, ReferenceSector.Transform.position, Color.cyan);
|
||||
Popcron.Gizmos.Line(AttachedObject.transform.position, ReferenceTransform.position, Color.cyan);
|
||||
}
|
||||
}
|
||||
}
|
83
QSB/TransformSync/IntermediaryTransform.cs
Normal file
83
QSB/TransformSync/IntermediaryTransform.cs
Normal file
@ -0,0 +1,83 @@
|
||||
using QSB.Utility;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.TransformSync
|
||||
{
|
||||
public class IntermediaryTransform
|
||||
{
|
||||
private Transform _attachedTransform;
|
||||
private Transform _referenceTransform;
|
||||
|
||||
public IntermediaryTransform(Transform transform)
|
||||
=> _attachedTransform = transform;
|
||||
|
||||
/// <summary>
|
||||
/// Get the world position of this INVISIBLE transform.
|
||||
/// </summary>
|
||||
public Vector3 GetPosition()
|
||||
=> _attachedTransform.position;
|
||||
|
||||
/// <summary>
|
||||
/// Set the world position of this INVISIBLE transform.
|
||||
/// </summary>
|
||||
public void SetPosition(Vector3 worldPos)
|
||||
=> _attachedTransform.position = worldPos;
|
||||
|
||||
/// <summary>
|
||||
/// Get the world rotation of this INVISIBLE transform.
|
||||
/// </summary>
|
||||
public Quaternion GetRotation()
|
||||
=> _attachedTransform.rotation;
|
||||
|
||||
/// <summary>
|
||||
/// Set the world rotation of this INVISIBLE transform.
|
||||
/// </summary>
|
||||
public void SetRotation(Quaternion worldRot)
|
||||
=> _attachedTransform.rotation = worldRot;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the reference transform - what transform this transform is syncing to.
|
||||
/// </summary>
|
||||
/// <param name="sector">The new reference sector.</param>
|
||||
public void SetReferenceTransform(Transform transform)
|
||||
=> _referenceTransform = transform;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the position of the INVISIBLE transform to be correct, according to the reference sector and the position of the VISIBLE transform.
|
||||
/// </summary>
|
||||
/// <param name="worldPosition">The world position of the VISIBLE transform.</param>
|
||||
public void EncodePosition(Vector3 worldPosition)
|
||||
=> SetPosition(_referenceTransform.InverseTransformPoint(worldPosition));
|
||||
|
||||
/// <summary>
|
||||
/// Sets the rotation of the INVISIBLE transform to be correct, according to the reference sector and the rotation of the VISIBLE transform.
|
||||
/// </summary>
|
||||
/// <param name="worldPosition">The world rotation of the VISIBLE transform.</param>
|
||||
public void EncodeRotation(Quaternion worldRotation)
|
||||
=> SetRotation(_referenceTransform.InverseTransformRotation(worldRotation));
|
||||
|
||||
/// <summary>
|
||||
/// Returns the local position the VISIBLE transform should be set to, from the INVISIBLE transform.
|
||||
/// </summary>
|
||||
public Vector3 GetTargetPosition_ParentedToReference()
|
||||
=> GetPosition();
|
||||
|
||||
/// <summary>
|
||||
/// Returns the local rotation the VISIBLE transform should be set to, from the INVISIBLE transform.
|
||||
/// </summary>
|
||||
public Quaternion GetTargetRotation_ParentedToReference()
|
||||
=> GetRotation();
|
||||
|
||||
/// <summary>
|
||||
/// Returns the world position the VISIBLE transform should be set to, from the INVISIBLE transform.
|
||||
/// </summary>
|
||||
public Vector3 GetTargetPosition_Unparented()
|
||||
=> _referenceTransform.TransformPoint(GetPosition());
|
||||
|
||||
/// <summary>
|
||||
/// Returns the world rotation the VISIBLE transform should be set to, from the INVISIBLE transform.
|
||||
/// </summary>
|
||||
public Quaternion GetTargetRotation_Unparented()
|
||||
=> _referenceTransform.TransformRotation(GetRotation());
|
||||
}
|
||||
}
|
83
QSB/TransformSync/SectoredTransformSync.cs
Normal file
83
QSB/TransformSync/SectoredTransformSync.cs
Normal file
@ -0,0 +1,83 @@
|
||||
using QSB.SectorSync.WorldObjects;
|
||||
using QSB.WorldSync;
|
||||
using QuantumUNET.Transport;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QSB.TransformSync
|
||||
{
|
||||
public abstract class SectoredTransformSync : BaseTransformSync
|
||||
{
|
||||
public QSBSector ReferenceSector { get; set; }
|
||||
public SectorSync.SectorSync SectorSync { get; private set; }
|
||||
public static List<SectoredTransformSync> SectoredNetworkTransformList = new List<SectoredTransformSync>();
|
||||
|
||||
public override void Start()
|
||||
{
|
||||
SectorSync = gameObject.AddComponent<SectorSync.SectorSync>();
|
||||
SectoredNetworkTransformList.Add(this);
|
||||
base.Start();
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
SectoredNetworkTransformList.Remove(this);
|
||||
if (SectorSync != null)
|
||||
{
|
||||
Destroy(SectorSync);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Init()
|
||||
{
|
||||
base.Init();
|
||||
SetReferenceTransform(SectorSync.GetClosestSector(AttachedObject.transform).Transform);
|
||||
}
|
||||
|
||||
public override void SerializeTransform(QNetworkWriter writer)
|
||||
{
|
||||
if (_intermediaryTransform == null)
|
||||
{
|
||||
_intermediaryTransform = new IntermediaryTransform(transform);
|
||||
}
|
||||
if (ReferenceSector != null)
|
||||
{
|
||||
writer.Write(ReferenceSector.ObjectId);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write(-1);
|
||||
}
|
||||
base.SerializeTransform(writer);
|
||||
}
|
||||
|
||||
public override void DeserializeTransform(QNetworkReader reader)
|
||||
{
|
||||
if (!QSBCore.HasWokenUp)
|
||||
{
|
||||
reader.ReadInt32();
|
||||
reader.ReadVector3();
|
||||
DeserializeRotation(reader);
|
||||
return;
|
||||
}
|
||||
|
||||
var sectorId = reader.ReadInt32();
|
||||
var sector = sectorId == -1
|
||||
? null
|
||||
: QSBWorldSync.GetWorldFromId<QSBSector>(sectorId);
|
||||
|
||||
if (sector != ReferenceSector)
|
||||
{
|
||||
SetReferenceSector(sector);
|
||||
}
|
||||
|
||||
base.DeserializeTransform(reader);
|
||||
}
|
||||
|
||||
public void SetReferenceSector(QSBSector sector)
|
||||
{
|
||||
ReferenceSector = sector;
|
||||
SetReferenceTransform(sector.Transform);
|
||||
}
|
||||
}
|
||||
}
|
205
QSB/TransformSync/UnparentedBaseTransformSync.cs
Normal file
205
QSB/TransformSync/UnparentedBaseTransformSync.cs
Normal file
@ -0,0 +1,205 @@
|
||||
using OWML.Common;
|
||||
using QSB.Player;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.Utility;
|
||||
using QuantumUNET.Components;
|
||||
using QuantumUNET.Transport;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.TransformSync
|
||||
{
|
||||
public abstract class UnparentedBaseTransformSync : QNetworkTransform
|
||||
{
|
||||
public uint AttachedNetId => NetIdentity?.NetId.Value ?? uint.MaxValue;
|
||||
public uint PlayerId => NetIdentity.RootIdentity?.NetId.Value ?? NetIdentity.NetId.Value;
|
||||
public PlayerInfo Player => QSBPlayerManager.GetPlayer(PlayerId);
|
||||
|
||||
public Transform ReferenceTransform { get; set; }
|
||||
public GameObject AttachedObject { get; set; }
|
||||
|
||||
public abstract bool IsReady { get; }
|
||||
public abstract bool UseInterpolation { get; }
|
||||
|
||||
protected abstract GameObject InitLocalTransform();
|
||||
protected abstract GameObject InitRemoteTransform();
|
||||
|
||||
private bool _isInitialized;
|
||||
private const float SmoothTime = 0.1f;
|
||||
protected virtual float DistanceLeeway { get; } = 5f;
|
||||
private float _previousDistance;
|
||||
private Vector3 _positionSmoothVelocity;
|
||||
private Quaternion _rotationSmoothVelocity;
|
||||
protected IntermediaryTransform _intermediaryTransform;
|
||||
|
||||
public virtual void Start()
|
||||
{
|
||||
var lowestBound = Resources.FindObjectsOfTypeAll<PlayerTransformSync>()
|
||||
.Where(x => x.NetId.Value <= NetId.Value).OrderBy(x => x.NetId.Value).Last();
|
||||
NetIdentity.SetRootIdentity(lowestBound.NetIdentity);
|
||||
|
||||
DontDestroyOnLoad(gameObject);
|
||||
_intermediaryTransform = new IntermediaryTransform(transform);
|
||||
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
|
||||
}
|
||||
|
||||
protected virtual void OnDestroy()
|
||||
{
|
||||
if (!HasAuthority && AttachedObject != null)
|
||||
{
|
||||
Destroy(AttachedObject);
|
||||
}
|
||||
QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
|
||||
}
|
||||
|
||||
private void OnSceneLoaded(OWScene scene, bool isInUniverse) =>
|
||||
_isInitialized = false;
|
||||
|
||||
protected virtual void Init()
|
||||
{
|
||||
AttachedObject = HasAuthority ? InitLocalTransform() : InitRemoteTransform();
|
||||
_isInitialized = true;
|
||||
}
|
||||
|
||||
public override void SerializeTransform(QNetworkWriter writer)
|
||||
{
|
||||
if (_intermediaryTransform == null)
|
||||
{
|
||||
_intermediaryTransform = new IntermediaryTransform(transform);
|
||||
}
|
||||
|
||||
var worldPos = _intermediaryTransform.GetPosition();
|
||||
var worldRot = _intermediaryTransform.GetRotation();
|
||||
writer.Write(worldPos);
|
||||
SerializeRotation(writer, worldRot);
|
||||
_prevPosition = worldPos;
|
||||
_prevRotation = worldRot;
|
||||
}
|
||||
|
||||
public override void DeserializeTransform(QNetworkReader reader)
|
||||
{
|
||||
if (!QSBCore.HasWokenUp)
|
||||
{
|
||||
reader.ReadVector3();
|
||||
DeserializeRotation(reader);
|
||||
return;
|
||||
}
|
||||
|
||||
var pos = reader.ReadVector3();
|
||||
var rot = DeserializeRotation(reader);
|
||||
|
||||
if (HasAuthority)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_intermediaryTransform == null)
|
||||
{
|
||||
_intermediaryTransform = new IntermediaryTransform(transform);
|
||||
}
|
||||
|
||||
_intermediaryTransform.SetPosition(pos);
|
||||
_intermediaryTransform.SetRotation(rot);
|
||||
|
||||
if (_intermediaryTransform.GetPosition() == Vector3.zero)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - {PlayerId}.{GetType().Name} at (0,0,0)! - Given position was {pos}", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (!_isInitialized && IsReady)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
else if (_isInitialized && !IsReady)
|
||||
{
|
||||
_isInitialized = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_isInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (AttachedObject == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - AttachedObject {Player.PlayerId}.{GetType().Name} is null.", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateTransform();
|
||||
|
||||
base.Update();
|
||||
}
|
||||
|
||||
protected virtual void UpdateTransform()
|
||||
{
|
||||
if (HasAuthority)
|
||||
{
|
||||
_intermediaryTransform.EncodePosition(AttachedObject.transform.position);
|
||||
_intermediaryTransform.EncodeRotation(AttachedObject.transform.rotation);
|
||||
return;
|
||||
}
|
||||
var targetPos = _intermediaryTransform.GetTargetPosition_Unparented();
|
||||
var targetRot = _intermediaryTransform.GetTargetRotation_Unparented();
|
||||
if (targetPos != Vector3.zero && _intermediaryTransform.GetTargetPosition_ParentedToReference() != Vector3.zero)
|
||||
{
|
||||
if (UseInterpolation)
|
||||
{
|
||||
AttachedObject.transform.position = SmartSmoothDamp(AttachedObject.transform.position, targetPos);
|
||||
AttachedObject.transform.rotation = QuaternionHelper.SmoothDamp(AttachedObject.transform.rotation, targetRot, ref _rotationSmoothVelocity, SmoothTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
AttachedObject.transform.position = targetPos;
|
||||
AttachedObject.transform.rotation = targetRot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool HasMoved()
|
||||
{
|
||||
var displacementMagnitude = (_intermediaryTransform.GetPosition() - _prevPosition).magnitude;
|
||||
return displacementMagnitude > 1E-03f
|
||||
|| Quaternion.Angle(_intermediaryTransform.GetRotation(), _prevRotation) > 1E-03f;
|
||||
}
|
||||
|
||||
public void SetReferenceTransform(Transform transform)
|
||||
{
|
||||
if (ReferenceTransform == transform)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ReferenceTransform = transform;
|
||||
_intermediaryTransform.SetReferenceTransform(transform);
|
||||
}
|
||||
|
||||
private Vector3 SmartSmoothDamp(Vector3 currentPosition, Vector3 targetPosition)
|
||||
{
|
||||
var distance = Vector3.Distance(currentPosition, targetPosition);
|
||||
if (distance > _previousDistance + DistanceLeeway)
|
||||
{
|
||||
_previousDistance = distance;
|
||||
return targetPosition;
|
||||
}
|
||||
_previousDistance = distance;
|
||||
return Vector3.SmoothDamp(currentPosition, targetPosition, ref _positionSmoothVelocity, SmoothTime);
|
||||
}
|
||||
|
||||
private void OnRenderObject()
|
||||
{
|
||||
if (!QSBCore.HasWokenUp || !QSBCore.DebugMode || !QSBCore.ShowLinesInDebug || !IsReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Popcron.Gizmos.Cube(_intermediaryTransform.GetTargetPosition_ParentedToReference(), _intermediaryTransform.GetTargetRotation_ParentedToReference(), Vector3.one / 2, Color.red);
|
||||
var color = HasMoved() ? Color.green : Color.yellow;
|
||||
Popcron.Gizmos.Cube(AttachedObject.transform.position, AttachedObject.transform.rotation, Vector3.one / 2, color);
|
||||
Popcron.Gizmos.Line(AttachedObject.transform.position, ReferenceTransform.position, Color.cyan);
|
||||
}
|
||||
}
|
||||
}
|
@ -12,7 +12,6 @@ namespace QSB.WorldSync
|
||||
{
|
||||
public static class QSBWorldSync
|
||||
{
|
||||
public static List<NomaiOrbTransformSync> OrbSyncList { get; } = new List<NomaiOrbTransformSync>();
|
||||
public static List<NomaiInterfaceOrb> OldOrbList { get; set; } = new List<NomaiInterfaceOrb>();
|
||||
public static List<CharacterDialogueTree> OldDialogueTrees { get; set; } = new List<CharacterDialogueTree>();
|
||||
public static Dictionary<string, bool> DialogueConditions { get; } = new Dictionary<string, bool>();
|
||||
@ -119,7 +118,7 @@ namespace QSB.WorldSync
|
||||
return worldObject;
|
||||
}
|
||||
|
||||
public static void RaiseEvent<T>(T instance, string eventName, params object[] args)
|
||||
public static void RaiseEvent<T>(T instance, string eventName, params object[] args) // TODO : move this to qsb.utility
|
||||
{
|
||||
if (!(typeof(T)
|
||||
.GetField(eventName, Flags)?
|
||||
@ -147,7 +146,7 @@ namespace QSB.WorldSync
|
||||
DebugLog.ToConsole($"Error - No QSBOrbSlot found for {slot.name}!", MessageType.Error);
|
||||
return;
|
||||
}
|
||||
var orbSync = OrbSyncList.FirstOrDefault(x => x.AttachedOrb == affectingOrb);
|
||||
var orbSync = NomaiOrbTransformSync.OrbTransformSyncs.FirstOrDefault(x => x.AttachedObject == affectingOrb.gameObject);
|
||||
if (orbSync == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - No NomaiOrbTransformSync found for {affectingOrb.name} (For slot {slot.name})!", MessageType.Error);
|
||||
|
@ -3,7 +3,7 @@
|
||||
"settings": {
|
||||
"defaultServerIP": "localhost",
|
||||
"port": 7777,
|
||||
"debugMode": false,
|
||||
"debugMode": true,
|
||||
"showLinesInDebug": false,
|
||||
"socketedObjToDebug": -1
|
||||
}
|
||||
|
@ -289,14 +289,7 @@ namespace QuantumUNET.Components
|
||||
QLog.Error("Must set the Network Address field in the manager");
|
||||
return null;
|
||||
}
|
||||
if (useSimulator)
|
||||
{
|
||||
client.ConnectWithSimulator(networkAddress, networkPort, simulatedLatency, packetLossPercentage);
|
||||
}
|
||||
else
|
||||
{
|
||||
client.Connect(networkAddress, networkPort);
|
||||
}
|
||||
client.Connect(networkAddress, networkPort);
|
||||
OnStartClient(client);
|
||||
s_Address = networkAddress;
|
||||
return client;
|
||||
|
@ -268,29 +268,29 @@ namespace QuantumUNET
|
||||
{
|
||||
if (localClient)
|
||||
{
|
||||
client.RegisterHandlerSafe(1, OnLocalClientObjectDestroy);
|
||||
client.RegisterHandlerSafe(13, OnLocalClientObjectHide);
|
||||
client.RegisterHandlerSafe(3, OnLocalClientObjectSpawn);
|
||||
client.RegisterHandlerSafe(10, OnLocalClientObjectSpawnScene);
|
||||
client.RegisterHandlerSafe(15, OnClientAuthority);
|
||||
client.RegisterHandlerSafe(QMsgType.ObjectDestroy, OnLocalClientObjectDestroy);
|
||||
client.RegisterHandlerSafe(QMsgType.ObjectSpawn, OnLocalClientObjectSpawn);
|
||||
client.RegisterHandlerSafe(QMsgType.ObjectSpawnScene, OnLocalClientObjectSpawnScene);
|
||||
client.RegisterHandlerSafe(QMsgType.ObjectHide, OnLocalClientObjectHide);
|
||||
client.RegisterHandlerSafe(QMsgType.LocalClientAuthority, OnClientAuthority);
|
||||
}
|
||||
else
|
||||
{
|
||||
client.RegisterHandlerSafe(3, OnObjectSpawn);
|
||||
client.RegisterHandlerSafe(10, OnObjectSpawnScene);
|
||||
client.RegisterHandlerSafe(12, OnObjectSpawnFinished);
|
||||
client.RegisterHandlerSafe(1, OnObjectDestroy);
|
||||
client.RegisterHandlerSafe(13, OnObjectDestroy);
|
||||
client.RegisterHandlerSafe(8, OnUpdateVarsMessage);
|
||||
client.RegisterHandlerSafe(4, OnOwnerMessage);
|
||||
client.RegisterHandlerSafe(9, OnSyncListMessage);
|
||||
client.RegisterHandlerSafe(40, QNetworkAnimator.OnAnimationClientMessage);
|
||||
client.RegisterHandlerSafe(41, QNetworkAnimator.OnAnimationParametersClientMessage);
|
||||
client.RegisterHandlerSafe(15, OnClientAuthority);
|
||||
client.RegisterHandlerSafe(QMsgType.ObjectDestroy, OnObjectDestroy);
|
||||
client.RegisterHandlerSafe(QMsgType.ObjectSpawn, OnObjectSpawn);
|
||||
client.RegisterHandlerSafe(QMsgType.Owner, OnOwnerMessage);
|
||||
client.RegisterHandlerSafe(QMsgType.UpdateVars, OnUpdateVarsMessage);
|
||||
client.RegisterHandlerSafe(QMsgType.SyncList, OnSyncListMessage);
|
||||
client.RegisterHandlerSafe(QMsgType.ObjectSpawnScene, OnObjectSpawnScene);
|
||||
client.RegisterHandlerSafe(QMsgType.SpawnFinished, OnObjectSpawnFinished);
|
||||
client.RegisterHandlerSafe(QMsgType.ObjectHide, OnObjectDestroy);
|
||||
client.RegisterHandlerSafe(QMsgType.LocalClientAuthority, OnClientAuthority);
|
||||
client.RegisterHandlerSafe(QMsgType.Animation, QNetworkAnimator.OnAnimationClientMessage);
|
||||
client.RegisterHandlerSafe(QMsgType.AnimationParameters, QNetworkAnimator.OnAnimationParametersClientMessage);
|
||||
}
|
||||
client.RegisterHandlerSafe(2, OnRPCMessage);
|
||||
client.RegisterHandlerSafe(7, OnSyncEventMessage);
|
||||
client.RegisterHandlerSafe(42, QNetworkAnimator.OnAnimationTriggerClientMessage);
|
||||
client.RegisterHandlerSafe(QMsgType.Rpc, OnRPCMessage);
|
||||
client.RegisterHandlerSafe(QMsgType.SyncEvent, OnSyncEventMessage);
|
||||
client.RegisterHandlerSafe(QMsgType.AnimationTrigger, QNetworkAnimator.OnAnimationTriggerClientMessage);
|
||||
}
|
||||
|
||||
internal static string GetStringForAssetId(NetworkHash128 assetId)
|
||||
|
@ -52,6 +52,18 @@ namespace QuantumUNET
|
||||
|
||||
public HostTopology hostTopology { get; private set; }
|
||||
|
||||
private const int k_MaxEventsPerFrame = 500;
|
||||
private int m_HostPort;
|
||||
private int m_ClientConnectionId = -1;
|
||||
private int m_StatResetTime;
|
||||
private static readonly QCRCMessage s_CRCMessage = new QCRCMessage();
|
||||
private readonly QNetworkMessageHandlers m_MessageHandlers = new QNetworkMessageHandlers();
|
||||
protected QNetworkConnection m_Connection;
|
||||
private readonly byte[] m_MsgBuffer;
|
||||
private readonly NetworkReader m_MsgReader;
|
||||
protected ConnectState m_AsyncConnect = ConnectState.None;
|
||||
private string m_RequestedServerHost = "";
|
||||
|
||||
public int hostPort
|
||||
{
|
||||
get => m_HostPort;
|
||||
@ -87,139 +99,6 @@ namespace QuantumUNET
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool ReconnectToNewHost(string serverIp, int serverPort)
|
||||
{
|
||||
bool result;
|
||||
if (!active)
|
||||
{
|
||||
QLog.Error("Reconnect - NetworkClient must be active");
|
||||
result = false;
|
||||
}
|
||||
else if (m_Connection == null)
|
||||
{
|
||||
QLog.Error("Reconnect - no old connection exists");
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
QLog.Log($"NetworkClient Reconnect {serverIp}:{serverPort}");
|
||||
QClientScene.HandleClientDisconnect(m_Connection);
|
||||
QClientScene.ClearLocalPlayers();
|
||||
m_Connection.Disconnect();
|
||||
m_Connection = null;
|
||||
hostId = NetworkTransport.AddHost(hostTopology, m_HostPort);
|
||||
this.serverPort = serverPort;
|
||||
if (Application.platform == RuntimePlatform.WebGLPlayer)
|
||||
{
|
||||
this.serverIp = serverIp;
|
||||
m_AsyncConnect = ConnectState.Resolved;
|
||||
}
|
||||
else if (serverIp.Equals("127.0.0.1") || serverIp.Equals("localhost"))
|
||||
{
|
||||
this.serverIp = "127.0.0.1";
|
||||
m_AsyncConnect = ConnectState.Resolved;
|
||||
}
|
||||
else
|
||||
{
|
||||
QLog.Log($"Async DNS START:{serverIp}");
|
||||
m_AsyncConnect = ConnectState.Resolving;
|
||||
Dns.BeginGetHostAddresses(serverIp, GetHostAddressesCallback, this);
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool ReconnectToNewHost(EndPoint secureTunnelEndPoint)
|
||||
{
|
||||
bool result;
|
||||
if (!active)
|
||||
{
|
||||
QLog.Error("Reconnect - NetworkClient must be active");
|
||||
result = false;
|
||||
}
|
||||
else if (m_Connection == null)
|
||||
{
|
||||
QLog.Error("Reconnect - no old connection exists");
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
QLog.Log("NetworkClient Reconnect to remoteSockAddr");
|
||||
QClientScene.HandleClientDisconnect(m_Connection);
|
||||
QClientScene.ClearLocalPlayers();
|
||||
m_Connection.Disconnect();
|
||||
m_Connection = null;
|
||||
hostId = NetworkTransport.AddHost(hostTopology, m_HostPort);
|
||||
if (secureTunnelEndPoint == null)
|
||||
{
|
||||
QLog.Error("Reconnect failed: null endpoint passed in");
|
||||
m_AsyncConnect = ConnectState.Failed;
|
||||
result = false;
|
||||
}
|
||||
else if (secureTunnelEndPoint.AddressFamily != AddressFamily.InterNetwork && secureTunnelEndPoint.AddressFamily != AddressFamily.InterNetworkV6)
|
||||
{
|
||||
QLog.Error("Reconnect failed: Endpoint AddressFamily must be either InterNetwork or InterNetworkV6");
|
||||
m_AsyncConnect = ConnectState.Failed;
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
var fullName = secureTunnelEndPoint.GetType().FullName;
|
||||
if (fullName == "System.Net.IPEndPoint")
|
||||
{
|
||||
var ipendPoint = (IPEndPoint)secureTunnelEndPoint;
|
||||
Connect(ipendPoint.Address.ToString(), ipendPoint.Port);
|
||||
result = m_AsyncConnect != ConnectState.Failed;
|
||||
}
|
||||
else if (fullName != "UnityEngine.XboxOne.XboxOneEndPoint" && fullName != "UnityEngine.PS4.SceEndPoint")
|
||||
{
|
||||
QLog.Error("Reconnect failed: invalid Endpoint (not IPEndPoint or XboxOneEndPoint or SceEndPoint)");
|
||||
m_AsyncConnect = ConnectState.Failed;
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RemoteEndPoint = secureTunnelEndPoint;
|
||||
m_AsyncConnect = ConnectState.Connecting;
|
||||
byte b;
|
||||
try
|
||||
{
|
||||
m_ClientConnectionId = NetworkTransport.ConnectEndPoint(hostId, m_RemoteEndPoint, 0, out b);
|
||||
}
|
||||
catch (Exception arg)
|
||||
{
|
||||
QLog.Error($"Reconnect failed: Exception when trying to connect to EndPoint: {arg}");
|
||||
m_AsyncConnect = ConnectState.Failed;
|
||||
return false;
|
||||
}
|
||||
if (m_ClientConnectionId == 0)
|
||||
{
|
||||
QLog.Error($"Reconnect failed: Unable to connect to EndPoint ({b})");
|
||||
m_AsyncConnect = ConnectState.Failed;
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Connection = (QNetworkConnection)Activator.CreateInstance(networkConnectionClass);
|
||||
m_Connection.SetHandlers(m_MessageHandlers);
|
||||
m_Connection.Initialize(serverIp, hostId, m_ClientConnectionId, hostTopology);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void ConnectWithSimulator(string serverIp, int serverPort, int latency, float packetLoss)
|
||||
{
|
||||
m_UseSimulator = true;
|
||||
m_SimulatedLatency = latency;
|
||||
m_PacketLoss = packetLoss;
|
||||
Connect(serverIp, serverPort);
|
||||
}
|
||||
|
||||
private static bool IsValidIpV6(string address) =>
|
||||
address.All(c => c == ':' || (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
|
||||
|
||||
@ -251,63 +130,6 @@ namespace QuantumUNET
|
||||
}
|
||||
}
|
||||
|
||||
public void Connect(EndPoint secureTunnelEndPoint)
|
||||
{
|
||||
PrepareForConnect();
|
||||
QLog.Log("Client Connect to remoteSockAddr");
|
||||
if (secureTunnelEndPoint == null)
|
||||
{
|
||||
QLog.Error("Connect failed: null endpoint passed in");
|
||||
m_AsyncConnect = ConnectState.Failed;
|
||||
}
|
||||
else if (secureTunnelEndPoint.AddressFamily != AddressFamily.InterNetwork && secureTunnelEndPoint.AddressFamily != AddressFamily.InterNetworkV6)
|
||||
{
|
||||
QLog.Error("Connect failed: Endpoint AddressFamily must be either InterNetwork or InterNetworkV6");
|
||||
m_AsyncConnect = ConnectState.Failed;
|
||||
}
|
||||
else
|
||||
{
|
||||
var fullName = secureTunnelEndPoint.GetType().FullName;
|
||||
if (fullName == "System.Net.IPEndPoint")
|
||||
{
|
||||
var ipendPoint = (IPEndPoint)secureTunnelEndPoint;
|
||||
Connect(ipendPoint.Address.ToString(), ipendPoint.Port);
|
||||
}
|
||||
else if (fullName != "UnityEngine.XboxOne.XboxOneEndPoint" && fullName != "UnityEngine.PS4.SceEndPoint" && fullName != "UnityEngine.PSVita.SceEndPoint")
|
||||
{
|
||||
QLog.Error("Connect failed: invalid Endpoint (not IPEndPoint or XboxOneEndPoint or SceEndPoint)");
|
||||
m_AsyncConnect = ConnectState.Failed;
|
||||
}
|
||||
else
|
||||
{
|
||||
byte b = 0;
|
||||
m_RemoteEndPoint = secureTunnelEndPoint;
|
||||
m_AsyncConnect = ConnectState.Connecting;
|
||||
try
|
||||
{
|
||||
m_ClientConnectionId = NetworkTransport.ConnectEndPoint(hostId, m_RemoteEndPoint, 0, out b);
|
||||
}
|
||||
catch (Exception arg)
|
||||
{
|
||||
QLog.Error($"Connect failed: Exception when trying to connect to EndPoint: {arg}");
|
||||
m_AsyncConnect = ConnectState.Failed;
|
||||
return;
|
||||
}
|
||||
if (m_ClientConnectionId == 0)
|
||||
{
|
||||
QLog.Error($"Connect failed: Unable to connect to EndPoint ({b})");
|
||||
m_AsyncConnect = ConnectState.Failed;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Connection = (QNetworkConnection)Activator.CreateInstance(networkConnectionClass);
|
||||
m_Connection.SetHandlers(m_MessageHandlers);
|
||||
m_Connection.Initialize(serverIp, hostId, m_ClientConnectionId, hostTopology);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void PrepareForConnect()
|
||||
{
|
||||
SetActive(true);
|
||||
@ -320,21 +142,7 @@ namespace QuantumUNET
|
||||
connectionConfig.UsePlatformSpecificProtocols = false;
|
||||
hostTopology = new HostTopology(connectionConfig, 8);
|
||||
}
|
||||
if (m_UseSimulator)
|
||||
{
|
||||
var num = m_SimulatedLatency / 3 - 1;
|
||||
if (num < 1)
|
||||
{
|
||||
num = 1;
|
||||
}
|
||||
var num2 = m_SimulatedLatency * 3;
|
||||
QLog.Log($"AddHost Using Simulator {num}/{num2}");
|
||||
hostId = NetworkTransport.AddHostWithSimulator(hostTopology, num, num2, m_HostPort);
|
||||
}
|
||||
else
|
||||
{
|
||||
hostId = NetworkTransport.AddHost(hostTopology, m_HostPort);
|
||||
}
|
||||
hostId = NetworkTransport.AddHost(hostTopology, m_HostPort);
|
||||
}
|
||||
|
||||
internal static void GetHostAddressesCallback(IAsyncResult ar)
|
||||
@ -367,22 +175,7 @@ namespace QuantumUNET
|
||||
|
||||
internal void ContinueConnect()
|
||||
{
|
||||
if (m_UseSimulator)
|
||||
{
|
||||
var num = m_SimulatedLatency / 3;
|
||||
if (num < 1)
|
||||
{
|
||||
num = 1;
|
||||
}
|
||||
QLog.Log(
|
||||
$"Connect Using Simulator {m_SimulatedLatency / 3}/{m_SimulatedLatency}");
|
||||
var conf = new ConnectionSimulatorConfig(num, m_SimulatedLatency, num, m_SimulatedLatency, m_PacketLoss);
|
||||
m_ClientConnectionId = NetworkTransport.ConnectWithSimulator(hostId, serverIp, serverPort, 0, out var b, conf);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ClientConnectionId = NetworkTransport.Connect(hostId, serverIp, serverPort, 0, out var b);
|
||||
}
|
||||
m_ClientConnectionId = NetworkTransport.Connect(hostId, serverIp, serverPort, 0, out var b);
|
||||
m_Connection = (QNetworkConnection)Activator.CreateInstance(networkConnectionClass);
|
||||
m_Connection.SetHandlers(m_MessageHandlers);
|
||||
m_Connection.Initialize(serverIp, hostId, m_ClientConnectionId, hostTopology);
|
||||
@ -808,34 +601,6 @@ namespace QuantumUNET
|
||||
active = state;
|
||||
}
|
||||
|
||||
private const int k_MaxEventsPerFrame = 500;
|
||||
private int m_HostPort;
|
||||
|
||||
private bool m_UseSimulator;
|
||||
|
||||
private int m_SimulatedLatency;
|
||||
|
||||
private float m_PacketLoss;
|
||||
private int m_ClientConnectionId = -1;
|
||||
|
||||
private int m_StatResetTime;
|
||||
|
||||
private EndPoint m_RemoteEndPoint;
|
||||
|
||||
private static readonly QCRCMessage s_CRCMessage = new QCRCMessage();
|
||||
|
||||
private readonly QNetworkMessageHandlers m_MessageHandlers = new QNetworkMessageHandlers();
|
||||
|
||||
protected QNetworkConnection m_Connection;
|
||||
|
||||
private readonly byte[] m_MsgBuffer;
|
||||
|
||||
private readonly NetworkReader m_MsgReader;
|
||||
|
||||
protected ConnectState m_AsyncConnect = ConnectState.None;
|
||||
|
||||
private string m_RequestedServerHost = "";
|
||||
|
||||
protected enum ConnectState
|
||||
{
|
||||
None,
|
||||
|
Loading…
x
Reference in New Issue
Block a user