Merge pull request #204 from misternebula/orb-tracking

Orb tracking
This commit is contained in:
Mister_Nebula 2020-10-22 21:26:56 +01:00 committed by GitHub
commit ff85a56a91
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 751 additions and 147 deletions

Binary file not shown.

View File

@ -1,9 +1,9 @@
ManifestFileVersion: 0
CRC: 3045401868
CRC: 3416116897
Hashes:
AssetFileHash:
serializedVersion: 2
Hash: fbaaf26c59dbb62b2ffc0c3939c0880a
Hash: f304be71f6b3202b0c75695ffc81dd4e
TypeTreeHash:
serializedVersion: 2
Hash: 47ee499ae8022a6b96ca6a5fd541f154
@ -27,6 +27,7 @@ Assets:
- Assets/NetworkPlayer.prefab
- Assets/NetworkCameraRoot.prefab
- Assets/NetworkProbe.prefab
- Assets/NetworkOrb.prefab
- Assets/NetworkManager.prefab
- Assets/NetworkShip.prefab
Dependencies: []

View File

@ -7,15 +7,9 @@ namespace QSB.Animation
{
public override EventType Type => EventType.AnimTrigger;
public override void SetupListener()
{
GlobalMessenger<short, float>.AddListener(EventNames.QSBAnimTrigger, Handler);
}
public override void SetupListener() => GlobalMessenger<short, float>.AddListener(EventNames.QSBAnimTrigger, Handler);
public override void CloseListener()
{
GlobalMessenger<short, float>.RemoveListener(EventNames.QSBAnimTrigger, Handler);
}
public override void CloseListener() => GlobalMessenger<short, float>.RemoveListener(EventNames.QSBAnimTrigger, Handler);
private void Handler(short triggerId, float value) => SendEvent(CreateMessage(triggerId, value));

View File

@ -8,15 +8,9 @@ namespace QSB.DeathSync
{
public override EventType Type => EventType.PlayerDeath;
public override void SetupListener()
{
GlobalMessenger<DeathType>.AddListener(EventNames.QSBPlayerDeath, Handler);
}
public override void SetupListener() => GlobalMessenger<DeathType>.AddListener(EventNames.QSBPlayerDeath, Handler);
public override void CloseListener()
{
GlobalMessenger<DeathType>.RemoveListener(EventNames.QSBPlayerDeath, Handler);
}
public override void CloseListener() => GlobalMessenger<DeathType>.RemoveListener(EventNames.QSBPlayerDeath, Handler);
private void Handler(DeathType type) => SendEvent(CreateMessage(type));

View File

@ -8,15 +8,9 @@ namespace QSB.ElevatorSync
{
public override EventType Type => EventType.Elevator;
public override void SetupListener()
{
GlobalMessenger<int, ElevatorDirection>.AddListener(EventNames.QSBStartLift, Handler);
}
public override void SetupListener() => GlobalMessenger<int, ElevatorDirection>.AddListener(EventNames.QSBStartLift, Handler);
public override void CloseListener()
{
GlobalMessenger<int, ElevatorDirection>.RemoveListener(EventNames.QSBStartLift, Handler);
}
public override void CloseListener() => GlobalMessenger<int, ElevatorDirection>.RemoveListener(EventNames.QSBStartLift, Handler);
private void Handler(int id, ElevatorDirection direction) => SendEvent(CreateMessage(id, direction));

View File

@ -2,6 +2,7 @@
using QSB.DeathSync;
using QSB.ElevatorSync;
using QSB.GeyserSync;
using QSB.OrbSync;
using QSB.TimeSync;
using QSB.Tools;
using QSB.TransformSync;
@ -37,7 +38,9 @@ namespace QSB.Events
new ElevatorEvent(),
new GeyserEvent(),
new ServerTimeEvent(),
new AnimTriggerEvent()
new AnimTriggerEvent(),
new OrbSlotEvent(),
new OrbUserEvent()
};
_eventList.ForEach(ev => ev.SetupListener());

View File

@ -16,6 +16,7 @@
public static string UnequipTranslator = "UnequipTranslator";
public static string ExitShip = "ExitShip";
public static string RestartTimeLoop = "RestartTimeLoop";
public static string WakeUp = "WakeUp";
public static string QSBPlayerDeath = "QSBPlayerDeath";
public static string QSBPlayerJoin = "QSBPlayerJoin";
@ -29,5 +30,7 @@
public static string QSBStartLift = "QSBStartLift";
public static string QSBGeyserState = "QSBGeyserState";
public static string QSBAnimTrigger = "QSBAnimTrigger";
public static string QSBOrbSlot = "QSBOrbSlot";
public static string QSBOrbUser = "QSBOrbUser";
}
}

View File

@ -8,15 +8,9 @@ namespace QSB.Events
{
public override EventType Type => EventType.PlayerJoin;
public override void SetupListener()
{
GlobalMessenger<string>.AddListener(EventNames.QSBPlayerJoin, Handler);
}
public override void SetupListener() => GlobalMessenger<string>.AddListener(EventNames.QSBPlayerJoin, Handler);
public override void CloseListener()
{
GlobalMessenger<string>.RemoveListener(EventNames.QSBPlayerJoin, Handler);
}
public override void CloseListener() => GlobalMessenger<string>.RemoveListener(EventNames.QSBPlayerJoin, Handler);
private void Handler(string name) => SendEvent(CreateMessage(name));

View File

@ -9,15 +9,9 @@ namespace QSB.Events
{
public override EventType Type => EventType.PlayerLeave;
public override void SetupListener()
{
GlobalMessenger<uint, uint[]>.AddListener(EventNames.QSBPlayerLeave, Handler);
}
public override void SetupListener() => GlobalMessenger<uint, uint[]>.AddListener(EventNames.QSBPlayerLeave, Handler);
public override void CloseListener()
{
GlobalMessenger<uint, uint[]>.RemoveListener(EventNames.QSBPlayerLeave, Handler);
}
public override void CloseListener() => GlobalMessenger<uint, uint[]>.RemoveListener(EventNames.QSBPlayerLeave, Handler);
private void Handler(uint playerId, uint[] netIds) => SendEvent(CreateMessage(playerId, netIds));

View File

@ -10,15 +10,9 @@ namespace QSB.Events
{
public override EventType Type => EventType.PlayerReady;
public override void SetupListener()
{
GlobalMessenger<bool>.AddListener(EventNames.QSBPlayerReady, Handler);
}
public override void SetupListener() => GlobalMessenger<bool>.AddListener(EventNames.QSBPlayerReady, Handler);
public override void CloseListener()
{
GlobalMessenger<bool>.RemoveListener(EventNames.QSBPlayerReady, Handler);
}
public override void CloseListener() => GlobalMessenger<bool>.RemoveListener(EventNames.QSBPlayerReady, Handler);
private void Handler(bool ready) => SendEvent(CreateMessage(ready));

View File

@ -9,15 +9,9 @@ namespace QSB.Events
{
public override EventType Type => EventType.FullStateRequest;
public override void SetupListener()
{
GlobalMessenger.AddListener(EventNames.QSBPlayerStatesRequest, Handler);
}
public override void SetupListener() => GlobalMessenger.AddListener(EventNames.QSBPlayerStatesRequest, Handler);
public override void CloseListener()
{
GlobalMessenger.RemoveListener(EventNames.QSBPlayerStatesRequest, Handler);
}
public override void CloseListener() => GlobalMessenger.RemoveListener(EventNames.QSBPlayerStatesRequest, Handler);
private void Handler() => SendEvent(CreateMessage());

View File

@ -19,6 +19,8 @@
PlayerReady,
ProbeActiveChange,
Elevator,
Geyser
Geyser,
OrbSlot,
OrbUser
}
}

52
QSB/OrbSync/OrbManager.cs Normal file
View File

@ -0,0 +1,52 @@
using QSB.Utility;
using QSB.WorldSync;
using System.Linq;
using UnityEngine;
using UnityEngine.Networking;
namespace QSB.OrbSync
{
public class OrbManager : MonoBehaviour
{
public static OrbManager Instance { get; private set; }
private void Awake()
{
Instance = this;
}
private void BuildOrbSlots()
{
DebugLog.DebugWrite("Building QSBOrbSlots...");
var orbSlots = Resources.FindObjectsOfTypeAll<NomaiInterfaceSlot>();
for (var id = 0; id < orbSlots.Length; id++)
{
var qsbOrbSlot = WorldRegistry.GetObject<QSBOrbSlot>(id) ?? new QSBOrbSlot();
qsbOrbSlot.Init(orbSlots[id], id);
}
DebugLog.DebugWrite($"Finished orb build with {WorldRegistry.OldOrbList.Count} interface orbs and {WorldRegistry.OrbSyncList.Count} orb syncs.");
}
public void BuildOrbs()
{
DebugLog.DebugWrite("Building orb syncs...");
WorldRegistry.OldOrbList.Clear();
WorldRegistry.OldOrbList = Resources.FindObjectsOfTypeAll<NomaiInterfaceOrb>().ToList();
if (NetworkServer.active)
{
DebugLog.DebugWrite("IS SERVER - INSTANTIATING!");
WorldRegistry.OrbSyncList.Clear();
WorldRegistry.OldOrbList.ForEach(x => NetworkServer.Spawn(Instantiate(QSBNetworkManager.Instance.OrbPrefab)));
}
}
public void QueueBuildSlots()
{
DebugLog.DebugWrite("Queueing build of QSBOrbSlots...");
QSB.Helper.Events.Unity.RunWhen(() => QSB.HasWokenUp, BuildOrbSlots);
}
}
}

61
QSB/OrbSync/OrbPatches.cs Normal file
View File

@ -0,0 +1,61 @@
using QSB.Events;
using QSB.WorldSync;
using UnityEngine;
namespace QSB.OrbSync
{
public static class OrbPatches
{
public static void StartDragCallEvent(bool __result, NomaiInterfaceOrb __instance)
{
if (__result)
{
GlobalMessenger<int>.FireEvent(EventNames.QSBOrbUser, WorldRegistry.OldOrbList.FindIndex(x => x == __instance));
}
}
public static bool CheckOrbCollision(ref bool __result, NomaiInterfaceSlot __instance, NomaiInterfaceOrb orb,
bool ____ignoreDraggedOrbs, float ____radius, float ____exitRadius, ref NomaiInterfaceOrb ____occupyingOrb)
{
if (____ignoreDraggedOrbs && orb.IsBeingDragged())
{
__result = false;
return false;
}
var orbDistance = Vector3.Distance(orb.transform.position, __instance.transform.position);
var triggerRadius = orb.IsBeingDragged() ? ____exitRadius : ____radius;
if (____occupyingOrb == null && orbDistance < ____radius)
{
____occupyingOrb = orb;
if (Time.timeSinceLevelLoad > 1f)
{
WorldRegistry.HandleSlotStateChange(__instance, orb, true);
WorldRegistry.RaiseEvent(__instance, "OnSlotActivated");
}
__result = true;
return false;
}
if (____occupyingOrb == null || ____occupyingOrb != orb)
{
__result = false;
return false;
}
if (orbDistance > triggerRadius)
{
WorldRegistry.HandleSlotStateChange(__instance, orb, false);
____occupyingOrb = null;
WorldRegistry.RaiseEvent(__instance, "OnSlotDeactivated");
__result = false;
return false;
}
__result = true;
return false;
}
public static void AddPatches()
{
QSB.Helper.HarmonyHelper.AddPostfix<NomaiInterfaceOrb>("StartDragFromPosition", typeof(OrbPatches), nameof(StartDragCallEvent));
QSB.Helper.HarmonyHelper.AddPrefix<NomaiInterfaceSlot>("CheckOrbCollision", typeof(OrbPatches), nameof(CheckOrbCollision));
}
}
}

View File

@ -0,0 +1,30 @@
using QSB.Events;
using QSB.Messaging;
using QSB.WorldSync;
namespace QSB.OrbSync
{
public class OrbSlotEvent : QSBEvent<BoolWorldObjectMessage>
{
public override EventType Type => EventType.OrbSlot;
public override void SetupListener() => GlobalMessenger<int, bool>.AddListener(EventNames.QSBOrbSlot, Handler);
public override void CloseListener() => GlobalMessenger<int, bool>.RemoveListener(EventNames.QSBOrbSlot, Handler);
private void Handler(int id, bool state) => SendEvent(CreateMessage(id, state));
private BoolWorldObjectMessage CreateMessage(int id, bool state) => new BoolWorldObjectMessage
{
AboutId = LocalPlayerId,
ObjectId = id,
State = state
};
public override void OnReceiveRemote(BoolWorldObjectMessage message)
{
var orbSlot = WorldRegistry.GetObject<QSBOrbSlot>(message.ObjectId);
orbSlot?.SetState(message.State);
}
}
}

View File

@ -0,0 +1,73 @@
using OWML.Common;
using QSB.Events;
using QSB.Messaging;
using QSB.TransformSync;
using QSB.Utility;
using QSB.WorldSync;
using System.Linq;
using UnityEngine.Networking;
namespace QSB.OrbSync
{
public class OrbUserEvent : QSBEvent<WorldObjectMessage>
{
public override EventType Type => EventType.OrbUser;
public override void SetupListener() => GlobalMessenger<int>.AddListener(EventNames.QSBOrbUser, Handler);
public override void CloseListener() => GlobalMessenger<int>.RemoveListener(EventNames.QSBOrbUser, Handler);
private void Handler(int id) => SendEvent(CreateMessage(id));
private WorldObjectMessage CreateMessage(int id) => new WorldObjectMessage
{
AboutId = LocalPlayerId,
ObjectId = id
};
public override void OnServerReceive(WorldObjectMessage message)
{
var fromPlayer = NetworkServer.connections
.First(x => x.playerControllers[0].gameObject.GetComponent<PlayerTransformSync>().netId.Value == message.FromId);
if (WorldRegistry.OrbSyncList.Count == 0)
{
DebugLog.ToConsole($"Error - OrbSyncList is empty. (ID {message.ObjectId})", MessageType.Error);
return;
}
var orb = WorldRegistry.OrbSyncList
.First(x => x.AttachedOrb == WorldRegistry.OldOrbList[message.ObjectId]);
if (orb == null)
{
DebugLog.ToConsole($"Error - No orb found for user event. (ID {message.ObjectId})", MessageType.Error);
return;
}
var orbIdentity = orb.GetComponent<NetworkIdentity>();
if (orbIdentity == null)
{
DebugLog.ToConsole($"Error - Orb identity is null. (ID {message.ObjectId})", MessageType.Error);
return;
}
if (orbIdentity.clientAuthorityOwner != null)
{
orbIdentity.RemoveClientAuthority(orbIdentity.clientAuthorityOwner);
}
orbIdentity.AssignClientAuthority(fromPlayer);
orb.enabled = true;
}
public override void OnReceiveRemote(WorldObjectMessage message)
{
var orb = WorldRegistry.OrbSyncList
.First(x => x.AttachedOrb == WorldRegistry.OldOrbList[message.ObjectId]);
orb.enabled = true;
}
public override void OnReceiveLocal(WorldObjectMessage message)
{
if (NetworkServer.active)
{
OnServerReceive(message);
}
}
}
}

38
QSB/OrbSync/QSBOrbSlot.cs Normal file
View File

@ -0,0 +1,38 @@
using QSB.Events;
using QSB.WorldSync;
namespace QSB.OrbSync
{
public class QSBOrbSlot : WorldObject
{
public NomaiInterfaceSlot InterfaceSlot { get; private set; }
private bool _initialized;
public void Init(NomaiInterfaceSlot slot, int id)
{
ObjectId = id;
InterfaceSlot = slot;
_initialized = true;
WorldRegistry.AddObject(this);
}
public void HandleEvent(bool state)
{
if (QSB.HasWokenUp)
{
GlobalMessenger<int, bool>.FireEvent(EventNames.QSBOrbSlot, ObjectId, state);
}
}
public void SetState(bool state)
{
if (!_initialized)
{
return;
}
var ev = state ? "OnSlotActivated" : "OnSlotDeactivated";
WorldRegistry.RaiseEvent(InterfaceSlot, ev);
}
}
}

View File

@ -24,6 +24,7 @@ namespace QSB
public PlayerInfo(uint id)
{
DebugLog.DebugWrite($"Creating PlayerInfo with id {id}");
PlayerId = id;
}
@ -39,8 +40,6 @@ namespace QSB
FlagsHelper.Unset(ref states, state);
}
State = states;
//DebugLog.DebugWrite($"State of player {NetId} is now : {Environment.NewLine}" +
// $"{DebugLog.GenerateTable(Enum.GetNames(typeof(State)).ToList(), FlagsHelper.FlagsToListSet(State))}");
}
public void UpdateStateObjects()

View File

@ -3,6 +3,7 @@ using QSB.Messaging;
using QSB.TransformSync;
using QSB.Utility;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using UnityEngine.Networking;
@ -20,6 +21,8 @@ namespace QSB
{
if (id == uint.MaxValue || id == 0U)
{
var stacktrace = new StackTrace();
DebugLog.ToConsole($"GetPlayer() got uint.MaxValue or 0 - returning default. Ran from {stacktrace.GetFrame(1).GetMethod().DeclaringType.Name}.{stacktrace.GetFrame(1).GetMethod().Name}.", MessageType.Warning);
return default;
}
var player = PlayerList.FirstOrDefault(x => x.PlayerId == id);
@ -39,6 +42,12 @@ namespace QSB
PlayerList.Remove(GetPlayer(id));
}
public static void RemoveAllPlayers()
{
DebugLog.DebugWrite($"Removing all players.", MessageType.Info);
PlayerList.Clear();
}
public static bool PlayerExists(uint id)
{
return id != uint.MaxValue && PlayerList.Any(x => x.PlayerId == id);
@ -50,8 +59,6 @@ namespace QSB
player.Name = message.PlayerName;
player.IsReady = message.PlayerReady;
player.State = message.PlayerState;
//DebugLog.DebugWrite($"Updating state of player {player.NetId} to : {Environment.NewLine}" +
// $"{DebugLog.GenerateTable(Enum.GetNames(typeof(State)).ToList(), FlagsHelper.FlagsToListSet(player.State))}");
if (LocalPlayer.IsReady)
{
player.UpdateStateObjects();
@ -76,28 +83,69 @@ namespace QSB
public static uint GetPlayerOfObject(this PlayerSyncObject syncObject)
{
if (PlayerList.Count == 0)
{
DebugLog.ToConsole($"Error - No players exist to find owner of object. (Attached NetID : {syncObject.AttachedNetId})", MessageType.Error);
syncObject.PreviousPlayerId = uint.MaxValue;
return uint.MaxValue;
}
// Get all Player IDs
var playerIds = PlayerList.Select(x => x.PlayerId).ToList();
// Get highest ID below the given syncobject's netid. A netid cannot belong to a netid above it, only below or equal to it.
var lowerBound = playerIds.Where(x => x <= syncObject.AttachedNetId).ToList().Max();
if (playerIds.Min() > syncObject.AttachedNetId)
{
DebugLog.ToConsole($"Warning - Minimum playerid is greater than syncobject's netid. (Attached NetID : {syncObject.AttachedNetId})", MessageType.Warning);
syncObject.PreviousPlayerId = uint.MaxValue;
return uint.MaxValue;
}
// If the player list count is not the same as the count of the same type syncobject (eg. 3 players and 4 PlayerTransformSyncs)
// and the highest ID below the syncobject's id is the same as the highest player id.
if (PlayerList.Count != PlayerSyncObjects.Count(x => x.GetType() == syncObject.GetType()) && lowerBound == playerIds.Max())
{
// If the previous player id was not the error value, return it. To smooth over discrepancies between player list and object list.
if (syncObject.PreviousPlayerId != uint.MaxValue)
{
return syncObject.PreviousPlayerId;
}
// If the syncobject is a PlayerTransformSync, make a player.
if (syncObject.GetType() == typeof(PlayerTransformSync) && syncObject.AttachedNetId != 0U)
{
return GetPlayer(syncObject.AttachedNetId).PlayerId;
}
DebugLog.ToConsole($"Warning - Unequal player:syncobject count. ({PlayerList.Count}:{PlayerSyncObjects.Count(x => x.GetType() == syncObject.GetType())}) (Attached NetID : {syncObject.AttachedNetId})", MessageType.Warning);
syncObject.PreviousPlayerId = uint.MaxValue;
return uint.MaxValue;
}
if (syncObject.PreviousPlayerId == uint.MaxValue)
{
DebugLog.ToConsole($"Warning - Syncobject previously had uint.MaxValue as it's playerid. (Attached NetID : {syncObject.AttachedNetId})", MessageType.Warning);
}
syncObject.PreviousPlayerId = lowerBound;
return lowerBound;
}
public static List<uint> GetPlayerNetIds(PlayerInfo player)
{
var count = PlayerSyncObjects.DistinctBy(x => x.AttachedNetId).Count(x => x.Player.PlayerId == player.PlayerId);
if (PlayerSyncObjects.Count == 0)
{
return default;
}
int count = 0;
int totalCount = PlayerSyncObjects.Count;
PlayerSyncObjects.RemoveAll(x => x == null);
PlayerSyncObjects.RemoveAll(x => x.GetComponent<NetworkIdentity>() == null);
if (PlayerSyncObjects.Count != totalCount)
{
DebugLog.ToConsole($"Warning - Removed {totalCount - PlayerSyncObjects.Count} items from PlayerSyncObjects.", MessageType.Warning);
}
foreach (var item in PlayerSyncObjects.DistinctBy(x => x.AttachedNetId))
{
if (item.PlayerId == player.PlayerId)
{
count++;
}
}
return Enumerable.Range((int)player.PlayerId, count).Select(x => (uint)x).ToList();
}
}

View File

@ -3,6 +3,7 @@ using OWML.ModHelper;
using QSB.DeathSync;
using QSB.ElevatorSync;
using QSB.GeyserSync;
using QSB.OrbSync;
using QSB.Tools;
using QSB.TransformSync;
using QSB.Utility;
@ -18,6 +19,7 @@ namespace QSB
public static int Port { get; private set; }
public static bool DebugMode { get; private set; }
public static AssetBundle NetworkAssetBundle { get; private set; }
public static bool HasWokenUp { get; set; }
private void Awake()
{
@ -43,6 +45,7 @@ namespace QSB
gameObject.AddComponent<DebugActions>();
gameObject.AddComponent<ElevatorManager>();
gameObject.AddComponent<GeyserManager>();
gameObject.AddComponent<OrbManager>();
gameObject.AddComponent<QSBSectorManager>();
}

View File

@ -136,6 +136,11 @@
<Compile Include="Events\EventNames.cs" />
<Compile Include="DeathSync\PlayerDeathEvent.cs" />
<Compile Include="Events\IQSBEvent.cs" />
<Compile Include="OrbSync\OrbManager.cs" />
<Compile Include="OrbSync\OrbSlotEvent.cs" />
<Compile Include="OrbSync\OrbPatches.cs" />
<Compile Include="OrbSync\OrbUserEvent.cs" />
<Compile Include="OrbSync\QSBOrbSlot.cs" />
<Compile Include="PlayerSyncObject.cs" />
<Compile Include="QSBNetworkLobby.cs" />
<Compile Include="QSBSceneManager.cs" />
@ -145,6 +150,7 @@
<Compile Include="Events\PlayerLeaveEvent.cs" />
<Compile Include="Tools\PlayerProbeEvent.cs" />
<Compile Include="Events\PlayerReadyEvent.cs" />
<Compile Include="TransformSync\NomaiOrbTransformSync.cs" />
<Compile Include="TransformSync\PlayerSectorEvent.cs" />
<Compile Include="Events\PlayerStatesRequestEvent.cs" />
<Compile Include="Animation\PlayerSuitEvent.cs" />

View File

@ -1,11 +1,15 @@
using OWML.Common;
using OWML.ModHelper.Events;
using QSB.Animation;
using QSB.DeathSync;
using QSB.ElevatorSync;
using QSB.Events;
using QSB.GeyserSync;
using QSB.OrbSync;
using QSB.TimeSync;
using QSB.TransformSync;
using QSB.Utility;
using QSB.WorldSync;
using System;
using System.Linq;
using UnityEngine;
@ -16,6 +20,7 @@ namespace QSB
public class QSBNetworkManager : NetworkManager
{
private const int MaxConnections = 128;
private const int MaxBufferedPackets = 64;
public static QSBNetworkManager Instance { get; private set; }
@ -27,6 +32,7 @@ namespace QSB
private GameObject _shipPrefab;
private GameObject _cameraPrefab;
private GameObject _probePrefab;
public GameObject OrbPrefab;
private void Awake()
{
@ -56,7 +62,21 @@ namespace QSB
spawnPrefabs.Add(_probePrefab);
DebugLog.LogState("ProbePrefab", _probePrefab);
OrbPrefab = _assetBundle.LoadAsset<GameObject>("assets/networkorb.prefab");
OrbPrefab.AddComponent<NomaiOrbTransformSync>();
spawnPrefabs.Add(OrbPrefab);
DebugLog.LogState("OrbPrefab", OrbPrefab);
ConfigureNetworkManager();
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
}
private void OnSceneLoaded(OWScene scene, bool inUniverse)
{
if (inUniverse)
{
OrbManager.Instance.BuildOrbs();
}
}
private void ConfigureNetworkManager()
@ -67,8 +87,20 @@ namespace QSB
customConfig = true;
connectionConfig.AddChannel(QosType.Reliable);
connectionConfig.AddChannel(QosType.Unreliable);
this.SetValue("m_MaxBufferedPackets", MaxBufferedPackets);
channels.Add(QosType.Reliable);
channels.Add(QosType.Unreliable);
gameObject.AddComponent<Events.PlayerState>();
}
public override void OnStartServer()
{
DebugLog.DebugWrite("~~ ON START SERVER ~~", MessageType.Info);
if (WorldRegistry.OrbSyncList.Count == 0 && QSBSceneManager.IsInUniverse)
{
QSB.Helper.Events.Unity.RunWhen(() => NetworkServer.active, OrbManager.Instance.BuildOrbs);
}
}
public override void OnServerAddPlayer(NetworkConnection connection, short playerControllerId) // Called on the server when a client joins
@ -80,8 +112,6 @@ namespace QSB
NetworkServer.SpawnWithClientAuthority(Instantiate(_shipPrefab), connection);
NetworkServer.SpawnWithClientAuthority(Instantiate(_cameraPrefab), connection);
NetworkServer.SpawnWithClientAuthority(Instantiate(_probePrefab), connection);
gameObject.AddComponent<Events.PlayerState>();
}
public override void OnClientConnect(NetworkConnection connection) // Called on the client when connecting to a server
@ -92,13 +122,17 @@ namespace QSB
gameObject.AddComponent<RespawnOnDeath>();
gameObject.AddComponent<PreventShipDestruction>();
QSBSectorManager.Instance.RebuildSectors();
OrbManager.Instance.QueueBuildSlots();
if (NetworkClient.active && !NetworkServer.active)
{
gameObject.AddComponent<Events.PlayerState>();
GeyserManager.Instance.EmptyUpdate();
WakeUpPatches.AddPatches();
}
OrbPatches.AddPatches();
_lobby.CanEditName = false;
OnNetworkManagerReady?.Invoke();
@ -111,7 +145,6 @@ namespace QSB
QSB.Helper.Events.Unity.RunWhen(() => EventList.Ready,
() => GlobalMessenger.FireEvent(EventNames.QSBPlayerStatesRequest));
}
public override void OnStopClient() // Called on the client when closing connection
@ -127,7 +160,14 @@ namespace QSB
{
PlayerRegistry.GetPlayerNetIds(player).ForEach(CleanupNetworkBehaviour);
}
PlayerRegistry.PlayerList.ForEach(x => PlayerRegistry.PlayerList.Remove(x));
PlayerRegistry.RemoveAllPlayers();
WorldRegistry.RemoveObjects<QSBOrbSlot>();
WorldRegistry.RemoveObjects<QSBElevator>();
WorldRegistry.RemoveObjects<QSBGeyser>();
WorldRegistry.RemoveObjects<QSBSector>();
DebugLog.DebugWrite("Clearing OrbSyncList...", MessageType.Info);
WorldRegistry.OrbSyncList.Clear();
_lobby.CanEditName = true;
}
@ -137,6 +177,16 @@ namespace QSB
var playerId = connection.playerControllers[0].gameObject.GetComponent<PlayerTransformSync>().netId.Value;
var netIds = connection.clientOwnedObjects.Select(x => x.Value).ToArray();
GlobalMessenger<uint, uint[]>.FireEvent(EventNames.QSBPlayerLeave, playerId, netIds);
foreach (var item in WorldRegistry.OrbSyncList)
{
var identity = item.GetComponent<NetworkIdentity>();
if (identity.clientAuthorityOwner == connection)
{
identity.RemoveClientAuthority(connection);
}
}
PlayerRegistry.GetPlayer(playerId).HudMarker?.Remove();
CleanupConnection(connection);
}
@ -150,6 +200,12 @@ namespace QSB
DebugLog.ToConsole("[S] Server stopped!", MessageType.Info);
PlayerRegistry.PlayerList.ForEach(player => player.HudMarker?.Remove());
NetworkServer.connections.ToList().ForEach(CleanupConnection);
WorldRegistry.RemoveObjects<QSBOrbSlot>();
WorldRegistry.RemoveObjects<QSBElevator>();
WorldRegistry.RemoveObjects<QSBGeyser>();
WorldRegistry.RemoveObjects<QSBSector>();
base.OnStopServer();
}
@ -173,11 +229,8 @@ namespace QSB
DebugLog.ToConsole($"{playerName} disconnected.", MessageType.Info);
PlayerRegistry.RemovePlayer(playerId);
if (playerId != PlayerRegistry.LocalPlayerId) // We don't want to delete the local player!
{
var netIds = connection.clientOwnedObjects?.Select(x => x.Value).ToList();
netIds.ForEach(CleanupNetworkBehaviour);
}
var netIds = connection.clientOwnedObjects?.Select(x => x.Value).ToList();
netIds.ForEach(CleanupNetworkBehaviour);
}
public void CleanupNetworkBehaviour(uint netId)
@ -192,15 +245,26 @@ namespace QSB
if (transformSync != null)
{
DebugLog.DebugWrite($" * Removing TransformSync from syncobjects");
PlayerRegistry.PlayerSyncObjects.Remove(transformSync);
if (transformSync.SyncedTransform != null && netId != PlayerRegistry.LocalPlayerId && !networkBehaviour.hasAuthority)
{
DebugLog.DebugWrite($" * Destroying {transformSync.SyncedTransform.gameObject.name}");
Destroy(transformSync.SyncedTransform.gameObject);
}
}
var animationSync = networkBehaviour.GetComponent<AnimationSync>();
if (animationSync != null)
{
DebugLog.DebugWrite($" * Removing AnimationSync from syncobjects");
PlayerRegistry.PlayerSyncObjects.Remove(animationSync);
}
if (!networkBehaviour.hasAuthority)
{
DebugLog.DebugWrite($" * Destroying {networkBehaviour.gameObject.name}");
Destroy(networkBehaviour.gameObject);
}
}

View File

@ -49,6 +49,15 @@ namespace QSB.TimeSync
}
GlobalMessenger.AddListener(EventNames.RestartTimeLoop, OnLoopStart);
GlobalMessenger.AddListener(EventNames.WakeUp, OnWakeUp);
}
private void OnWakeUp()
{
if (NetworkServer.active)
{
QSB.HasWokenUp = true;
}
}
private void OnDestroy()
@ -59,6 +68,7 @@ namespace QSB.TimeSync
private void OnSceneLoaded(OWScene scene, bool isInUniverse)
{
QSB.HasWokenUp = false;
if (isInUniverse)
{
Init();
@ -165,6 +175,7 @@ namespace QSB.TimeSync
EnableInput();
}
_isFirstFastForward = false;
QSB.HasWokenUp = true;
Physics.SyncTransforms();
SpinnerUI.Hide();
DebugLog.DebugWrite("ResetTimeScale - Request state!");

View File

@ -7,7 +7,6 @@ namespace QSB.Tools
{
public class PlayerToolsManager
{
private static Transform _cameraBody;
private static Transform _toolStowTransform;
private static Transform _toolHoldTransform;
private static Material _playerToolsMaterial;
@ -20,16 +19,15 @@ namespace QSB.Tools
public static void Init(Transform camera)
{
_cameraBody = camera;
CreateStowTransforms();
CreateStowTransforms(camera);
_playerToolsMaterial = GameObject.Find("PlayerSuit_Jetpack").GetComponent<MeshRenderer>().materials[0];
_lightbulbMaterial = GameObject.Find("Props_HEA_Lantern (10)/Lantern_Lamp").GetComponent<MeshRenderer>().materials[0];
CreateFlashlight();
CreateSignalscope();
CreateProbeLauncher();
CreateTranslator();
CreateFlashlight(camera);
CreateSignalscope(camera);
CreateProbeLauncher(camera);
CreateTranslator(camera);
}
public static void CreateProbe(Transform body, PlayerInfo player)
@ -38,22 +36,22 @@ namespace QSB.Tools
player.Probe = newProbe;
}
private static void CreateStowTransforms()
private static void CreateStowTransforms(Transform cameraBody)
{
var stow = new GameObject("ToolStowTransform");
_toolStowTransform = stow.transform;
stow.transform.parent = _cameraBody;
stow.transform.parent = cameraBody;
stow.transform.localPosition = Vector3.zero;
stow.transform.localRotation = Quaternion.Euler(45f, 0f, 0f);
var hold = new GameObject("ToolHoldTransform");
_toolHoldTransform = hold.transform;
hold.transform.parent = _cameraBody;
hold.transform.parent = cameraBody;
hold.transform.localPosition = Vector3.zero;
hold.transform.localRotation = Quaternion.Euler(0f, 0f, 0f);
}
private static void CreateFlashlight()
private static GameObject CreateFlashlight(Transform cameraBody)
{
var flashlightRoot = Object.Instantiate(GameObject.Find("FlashlightRoot"));
flashlightRoot.SetActive(false);
@ -63,12 +61,14 @@ namespace QSB.Tools
component.Init(oldComponent);
oldComponent.enabled = false;
flashlightRoot.transform.parent = _cameraBody;
flashlightRoot.transform.parent = cameraBody;
flashlightRoot.transform.localPosition = FlashlightOffset;
flashlightRoot.SetActive(true);
return flashlightRoot;
}
private static void CreateSignalscope()
private static GameObject CreateSignalscope(Transform cameraBody)
{
var signalscopeRoot = Object.Instantiate(GameObject.Find("Signalscope"));
signalscopeRoot.SetActive(false);
@ -89,13 +89,15 @@ namespace QSB.Tools
GetRenderer(signalscopeRoot, "Props_HEA_Signalscope").material = _playerToolsMaterial;
signalscopeRoot.transform.parent = _cameraBody;
signalscopeRoot.transform.parent = cameraBody;
signalscopeRoot.transform.localPosition = Vector3.zero;
signalscopeRoot.transform.localScale = SignalscopeScale;
signalscopeRoot.SetActive(true);
return signalscopeRoot;
}
private static void CreateTranslator()
private static GameObject CreateTranslator(Transform cameraBody)
{
var original = GameObject.Find("NomaiTranslatorProp");
@ -128,13 +130,15 @@ namespace QSB.Tools
GetRenderer(translatorRoot, "Props_HEA_Translator_Button_L").material = _lightbulbMaterial;
GetRenderer(translatorRoot, "Props_HEA_Translator_Button_R").material = _lightbulbMaterial;
translatorRoot.transform.parent = _cameraBody;
translatorRoot.transform.parent = cameraBody;
translatorRoot.transform.localPosition = Vector3.zero;
translatorRoot.transform.localScale = TranslatorScale;
QSB.Helper.Events.Unity.FireOnNextUpdate(() => translatorRoot.SetActive(true));
return translatorRoot;
}
private static void CreateProbeLauncher()
private static GameObject CreateProbeLauncher(Transform cameraBody)
{
var launcherRoot = new GameObject("ProbeLauncher");
var modelOrig = GameObject.Find("PlayerCamera/ProbeLauncher/Props_HEA_ProbeLauncher");
@ -167,9 +171,11 @@ namespace QSB.Tools
GetRenderer(launcherRoot, "PressureGauge_Arrow").material = _playerToolsMaterial;
GetRenderer(launcherRoot, "ProbeLauncherChassis").material = _playerToolsMaterial;
launcherRoot.transform.parent = _cameraBody;
launcherRoot.transform.parent = cameraBody;
launcherRoot.transform.localPosition = ProbeLauncherOffset;
launcherRoot.SetActive(true);
return launcherRoot;
}
private static MeshRenderer GetRenderer(GameObject root, string gameObjectName)

View File

@ -0,0 +1,96 @@
using QSB.WorldSync;
using UnityEngine;
using UnityEngine.Networking;
namespace QSB.TransformSync
{
public class NomaiOrbTransformSync : NetworkBehaviour
{
public NomaiInterfaceOrb AttachedOrb { get; private set; }
public Transform OrbTransform { get; private set; }
private int Index => WorldRegistry.OrbSyncList.IndexOf(this);
private const int MaxUpdatesBeforeDisable = 5;
private bool _isInitialized;
private bool _isReady;
private Transform _orbParent;
private int _updateCount;
public override void OnStartClient()
{
WorldRegistry.OrbSyncList.Add(this);
QSB.Helper.Events.Unity.RunWhen(() => QSB.HasWokenUp, () => QSB.Helper.Events.Unity.FireOnNextUpdate(OnReady));
}
private void OnReady()
{
AttachedOrb = WorldRegistry.OldOrbList[Index];
_isReady = true;
}
private void Awake()
{
DontDestroyOnLoad(this);
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
}
private void OnDestroy()
{
WorldRegistry.OrbSyncList.Remove(this);
QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
}
private void OnSceneLoaded(OWScene scene, bool isInUniverse) => _isInitialized = false;
protected void Init()
{
OrbTransform = AttachedOrb.transform;
_orbParent = AttachedOrb.GetAttachedOWRigidbody().GetOrigParent();
_isInitialized = true;
}
private void Update()
{
if (!_isInitialized && _isReady)
{
Init();
}
else if (_isInitialized && !_isReady)
{
_isInitialized = false;
}
if (OrbTransform == null || !_isInitialized)
{
return;
}
UpdateTransform();
}
protected virtual void UpdateTransform()
{
if (hasAuthority)
{
transform.position = _orbParent.InverseTransformPoint(OrbTransform.position);
transform.rotation = _orbParent.InverseTransformRotation(OrbTransform.rotation);
return;
}
OrbTransform.position = _orbParent.TransformPoint(transform.position);
OrbTransform.rotation = _orbParent.InverseTransformRotation(OrbTransform.rotation);
if (transform.localPosition == Vector3.zero)
{
_updateCount++;
}
if (_updateCount >= MaxUpdatesBeforeDisable)
{
enabled = false;
_updateCount = 0;
}
}
}
}

View File

@ -25,7 +25,7 @@ namespace QSB.TransformSync
{
var body = GetProbe();
_disabledSocket = Player.Camera.transform;
SetSocket(Player.Camera.transform);
Player.ProbeBody = body.gameObject;
return body;
@ -48,16 +48,37 @@ namespace QSB.TransformSync
PlayerToolsManager.CreateProbe(body, Player);
_disabledSocket = Player.ProbeLauncher.ToolGameObject.transform;
QSB.Helper.Events.Unity.RunWhen(() => (Player.ProbeLauncher != null), () => SetSocket(Player.ProbeLauncher.ToolGameObject.transform));
Player.ProbeBody = body.gameObject;
return body;
}
private void SetSocket(Transform socket)
{
DebugLog.DebugWrite($"Setting DisabledSocket for {AttachedNetId} to {socket.name}");
_disabledSocket = socket;
}
protected override void UpdateTransform()
{
base.UpdateTransform();
if (Player.GetState(State.ProbeActive) || ReferenceSector.Sector == null)
if (Player == null)
{
DebugLog.ToConsole($"Player is null for {AttachedNetId}!", MessageType.Error);
return;
}
if (ReferenceSector == null)
{
DebugLog.ToConsole($"ReferenceSector is null for {AttachedNetId}!", MessageType.Error);
return;
}
if (_disabledSocket == null)
{
DebugLog.ToConsole($"DisabledSocket is null for {AttachedNetId}! (ProbeLauncher null? : {Player.ProbeLauncher == null})", MessageType.Error);
return;
}
if (Player.GetState(State.ProbeActive) || ReferenceSector?.Sector == null)
{
return;
}

View File

@ -44,8 +44,8 @@ namespace QSB.TransformSync
var transformSync = PlayerRegistry.GetSyncObject<TransformSync>(message.AboutId);
QSB.Helper.Events.Unity.RunWhen(() => transformSync.SyncedTransform != null,
() => transformSync.SetReferenceSector(sector));
QSB.Helper.Events.Unity.RunWhen(() => transformSync?.SyncedTransform != null,
() => transformSync?.SetReferenceSector(sector));
}
}

View File

@ -18,11 +18,12 @@ namespace QSB.TransformSync
private void Awake()
{
Instance = this;
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
QSBSceneManager.OnSceneLoaded += (OWScene scene, bool universe) => RebuildSectors();
}
private void OnSceneLoaded(OWScene scene, bool isInUniverse)
public void RebuildSectors()
{
WorldRegistry.RemoveObjects<QSBSector>();
var sectors = Resources.FindObjectsOfTypeAll<Sector>().ToList();
for (var id = 0; id < sectors.Count; id++)
{

View File

@ -64,7 +64,7 @@ namespace QSB.TransformSync
if (SyncedTransform == null)
{
DebugLog.ToConsole($"SyncedTransform {AttachedNetId} ({Player.PlayerId}.{GetType().Name}) is null!");
DebugLog.ToConsole($"Warning - SyncedTransform {AttachedNetId} ({Player.PlayerId}.{GetType().Name}) is null.", MessageType.Warning);
return;
}
@ -82,7 +82,7 @@ namespace QSB.TransformSync
{
if (ReferenceSector.Sector == null)
{
DebugLog.ToConsole($"Sector is null for referencesector for {AttachedNetId} ({Player.PlayerId}.{GetType().Name})!", MessageType.Error);
DebugLog.ToConsole($"Error - Sector is null for referencesector for {AttachedNetId}. ({Player.PlayerId}.{GetType().Name})", MessageType.Error);
}
transform.position = ReferenceSector.Transform.InverseTransformPoint(SyncedTransform.position);
transform.rotation = ReferenceSector.Transform.InverseTransformRotation(SyncedTransform.rotation);

View File

@ -1,6 +1,6 @@
using OWML.Common;
using System;
using System.Collections.Generic;
using OWML.Logging;
using System.Diagnostics;
using System.Linq;
namespace QSB.Utility
@ -9,7 +9,12 @@ namespace QSB.Utility
{
public static void ToConsole(string message, MessageType type = MessageType.Message)
{
QSB.Helper.Console.WriteLine(message, type);
var console = (ModSocketOutput)QSB.Helper.Console;
var method = console.GetType()
.GetMethods(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
.Last(x => x.Name == "WriteLine");
var callingType = GetCallingType(new StackTrace());
method.Invoke(console, new object[] { type, message, callingType });
}
public static void ToHud(string message)
@ -36,30 +41,20 @@ namespace QSB.Utility
}
}
public static string GenerateTable(List<string> columnsData, List<string> rowData)
{
var longestKey = columnsData.OrderByDescending(s => s.Length).First();
var longestValue = rowData.OrderByDescending(s => s.Length).First();
var longestObject = (longestKey.Length > longestValue.Length) ? longestKey : longestValue;
var columns = "|";
var data = "|";
foreach (var item in columnsData)
{
columns += $" {item.PadRight(longestObject.Length)} |";
}
foreach (var item in rowData)
{
data += $" {item.PadRight(longestObject.Length)} |";
}
return columns + Environment.NewLine + data;
}
public static void LogState(string name, bool state)
{
var status = state ? "OK" : "FAIL";
var messageType = state ? MessageType.Success : MessageType.Error;
DebugWrite($"* {name} {status}", messageType);
if (!state) // to stop "OK" spam
{
DebugWrite($"* {name} {status}", messageType);
}
}
private static string GetCallingType(StackTrace frame)
{
var stackFrame = frame.GetFrames().First(x => x.GetMethod().DeclaringType.Name != "DebugLog");
return stackFrame.GetMethod().DeclaringType.Name;
}
}
}

View File

@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
namespace QSB.Utility
namespace QSB.Utility
{
// Stolen from here : https://stackoverflow.com/questions/3261451/using-a-bitmask-in-c-sharp
@ -28,15 +25,7 @@ namespace QSB.Utility
var flagsValue = (int)(object)flags;
var flagValue = (int)(object)flag;
flags = (T)(object)(flagsValue & (~flagValue));
}
public static List<string> FlagsToListSet<T>(T flags) where T : struct
{
var temp = new List<string>();
var array = (T[])Enum.GetValues(flags.GetType());
Array.ForEach(array, x => temp.Add(Convert.ToString(IsSet(flags, x) ? 1 : 0)));
return temp;
flags = (T)(object)(flagsValue & ~flagValue);
}
}
}

View File

@ -1,29 +1,70 @@
using System.Collections.Generic;
using OWML.Common;
using QSB.OrbSync;
using QSB.TransformSync;
using QSB.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace QSB.WorldSync
{
public static class WorldRegistry
{
private static readonly List<WorldObject> _worldObjects = new List<WorldObject>();
private static readonly List<WorldObject> WorldObjects = new List<WorldObject>();
public static List<NomaiOrbTransformSync> OrbSyncList = new List<NomaiOrbTransformSync>();
public static List<NomaiInterfaceOrb> OldOrbList = new List<NomaiInterfaceOrb>();
public static void AddObject(WorldObject worldObject)
{
if (_worldObjects.Contains(worldObject))
if (WorldObjects.Contains(worldObject))
{
return;
}
_worldObjects.Add(worldObject);
WorldObjects.Add(worldObject);
}
public static IEnumerable<T> GetObjects<T>()
{
return _worldObjects.OfType<T>();
return WorldObjects.OfType<T>();
}
public static T GetObject<T>(int id) where T : WorldObject
{
return GetObjects<T>().FirstOrDefault(x => x.ObjectId == id);
}
public static void RemoveObjects<T>() where T : WorldObject
{
WorldObjects.RemoveAll(x => x.GetType() == typeof(T));
}
public static void HandleSlotStateChange(NomaiInterfaceSlot slot, NomaiInterfaceOrb affectingOrb, bool state)
{
var slotList = GetObjects<QSBOrbSlot>();
if (slotList.Count() == 0)
{
DebugLog.ToConsole($"Error - No QSBOrbSlots found when handling slot state change.", MessageType.Error);
return;
}
var qsbSlot = slotList.First(x => x.InterfaceSlot == slot);
var orbSync = OrbSyncList.First(x => x.AttachedOrb == affectingOrb);
if (orbSync.hasAuthority)
{
qsbSlot.HandleEvent(state);
}
}
public static void RaiseEvent(object instance, string eventName)
{
if (!(instance.GetType()
.GetField(eventName, BindingFlags.Instance | BindingFlags.NonPublic)?
.GetValue(instance) is MulticastDelegate multiDelegate))
{
return;
}
var delegateList = multiDelegate.GetInvocationList().ToList();
delegateList.ForEach(x => x.DynamicInvoke(instance));
}
}
}

View File

@ -3,6 +3,6 @@
"settings": {
"defaultServerIP": "localhost",
"port": 7777,
"debugMode": true
"debugMode": false
}
}

View File

@ -1,6 +1,6 @@
{
"filename": "QSB.dll",
"author": "Raicuparta, AmazingAlek & misternebula",
"author": "Nebula, Alek & Rai",
"name": "Quantum Space Buddies",
"description": "Adds online multiplayer to the game.",
"uniqueName": "Raicuparta.QuantumSpaceBuddies",

View File

@ -61,8 +61,7 @@ MonoBehaviour:
m_ScriptCRCCheck: 1
m_MaxDelay: 0.01
m_LogLevel: 2
m_PlayerPrefab: {fileID: 1211347487444314, guid: 163f71f5a4ce8e543bbf5632a3585dc7,
type: 2}
m_PlayerPrefab: {fileID: 0}
m_AutoCreatePlayer: 1
m_PlayerSpawnMethod: 0
m_OfflineScene:

View File

@ -0,0 +1,96 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications: []
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 1252242529042024}
m_IsPrefabParent: 1
--- !u!1 &1252242529042024
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 4745039063230268}
- component: {fileID: 114872848302743272}
- component: {fileID: 114240702864939342}
m_Layer: 0
m_Name: NetworkOrb
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &4745039063230268
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1252242529042024}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &114240702864939342
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1252242529042024}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -1768714887, guid: dc443db3e92b4983b9738c1131f555cb, type: 3}
m_Name:
m_EditorClassIdentifier:
m_TransformSyncMode: 1
m_SendInterval: 0.09090909
m_SyncRotationAxis: 0
m_RotationSyncCompression: 0
m_SyncSpin: 0
m_MovementTheshold: 0.001
m_VelocityThreshold: 0.0001
m_SnapThreshold: 5
m_InterpolateRotation: 1
m_InterpolateMovement: 1
--- !u!114 &114872848302743272
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1252242529042024}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 372142912, guid: dc443db3e92b4983b9738c1131f555cb, type: 3}
m_Name:
m_EditorClassIdentifier:
m_SceneId:
m_Value: 0
m_AssetId:
i0: 16
i1: 54
i2: 85
i3: 231
i4: 191
i5: 68
i6: 98
i7: 228
i8: 25
i9: 191
i10: 115
i11: 12
i12: 196
i13: 32
i14: 194
i15: 197
m_ServerOnly: 0
m_LocalPlayerAuthority: 1

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 103655e7bf4462e419bf730cc420c2c5
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 100100000
userData:
assetBundleName: network
assetBundleVariant:

View File

@ -53,7 +53,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
m_TransformSyncMode: 1
m_SendInterval: 0.09090909
m_SendInterval: 0.083333336
m_SyncRotationAxis: 7
m_RotationSyncCompression: 0
m_SyncSpin: 0