mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 02:50:32 +00:00
breaking: Removed Obsoletes (#3142)
* Removed Experimental NetworkTransform * NetworkRoomManager: Removed Obsoletes * NetworkTransformBase: Removed Obsoletes * NetworkBehaviour: Removed Obsoletes * NetworkManager: Removed Obsoletes * NetworkServer: Removed Obsoletes * SyncObject: Removed Obsoletes * fixed comment * fixed XML comment
This commit is contained in:
parent
8d07be97ed
commit
0e9d86f563
@ -1,14 +0,0 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Mirror.Experimental
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
// Deprecated 2022-01-18
|
||||
[Obsolete("Use the default NetworkTransform instead, it has proper snapshot interpolation.")]
|
||||
[AddComponentMenu("")]
|
||||
public class NetworkTransform : NetworkTransformBase
|
||||
{
|
||||
protected override Transform targetTransform => transform;
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 741bbe11f5357b44593b15c0d11b16bd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -1,531 +0,0 @@
|
||||
// vis2k:
|
||||
// base class for NetworkTransform and NetworkTransformChild.
|
||||
// New method is simple and stupid. No more 1500 lines of code.
|
||||
//
|
||||
// Server sends current data.
|
||||
// Client saves it and interpolates last and latest data points.
|
||||
// Update handles transform movement / rotation
|
||||
// FixedUpdate handles rigidbody movement / rotation
|
||||
//
|
||||
// Notes:
|
||||
// * Built-in Teleport detection in case of lags / teleport / obstacles
|
||||
// * Quaternion > EulerAngles because gimbal lock and Quaternion.Slerp
|
||||
// * Syncs XYZ. Works 3D and 2D. Saving 4 bytes isn't worth 1000 lines of code.
|
||||
// * Initial delay might happen if server sends packet immediately after moving
|
||||
// just 1cm, hence we move 1cm and then wait 100ms for next packet
|
||||
// * Only way for smooth movement is to use a fixed movement speed during
|
||||
// interpolation. interpolation over time is never that good.
|
||||
//
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Mirror.Experimental
|
||||
{
|
||||
// Deprecated 2022-01-18
|
||||
[Obsolete("Use the default NetworkTransform instead, it has proper snapshot interpolation.")]
|
||||
public abstract class NetworkTransformBase : NetworkBehaviour
|
||||
{
|
||||
// target transform to sync. can be on a child.
|
||||
protected abstract Transform targetTransform { get; }
|
||||
|
||||
[Header("Authority")]
|
||||
|
||||
[Tooltip("Set to true if moves come from owner client, set to false if moves always come from server")]
|
||||
[SyncVar]
|
||||
public bool clientAuthority;
|
||||
|
||||
[Tooltip("Set to true if updates from server should be ignored by owner")]
|
||||
[SyncVar]
|
||||
public bool excludeOwnerUpdate = true;
|
||||
|
||||
[Header("Synchronization")]
|
||||
|
||||
[Tooltip("Set to true if position should be synchronized")]
|
||||
[SyncVar]
|
||||
public bool syncPosition = true;
|
||||
|
||||
[Tooltip("Set to true if rotation should be synchronized")]
|
||||
[SyncVar]
|
||||
public bool syncRotation = true;
|
||||
|
||||
[Tooltip("Set to true if scale should be synchronized")]
|
||||
[SyncVar]
|
||||
public bool syncScale = true;
|
||||
|
||||
[Header("Interpolation")]
|
||||
|
||||
[Tooltip("Set to true if position should be interpolated")]
|
||||
[SyncVar]
|
||||
public bool interpolatePosition = true;
|
||||
|
||||
[Tooltip("Set to true if rotation should be interpolated")]
|
||||
[SyncVar]
|
||||
public bool interpolateRotation = true;
|
||||
|
||||
[Tooltip("Set to true if scale should be interpolated")]
|
||||
[SyncVar]
|
||||
public bool interpolateScale = true;
|
||||
|
||||
// Sensitivity is added for VR where human players tend to have micro movements so this can quiet down
|
||||
// the network traffic. Additionally, rigidbody drift should send less traffic, e.g very slow sliding / rolling.
|
||||
[Header("Sensitivity")]
|
||||
|
||||
[Tooltip("Changes to the transform must exceed these values to be transmitted on the network.")]
|
||||
[SyncVar]
|
||||
public float localPositionSensitivity = .01f;
|
||||
|
||||
[Tooltip("If rotation exceeds this angle, it will be transmitted on the network")]
|
||||
[SyncVar]
|
||||
public float localRotationSensitivity = .01f;
|
||||
|
||||
[Tooltip("Changes to the transform must exceed these values to be transmitted on the network.")]
|
||||
[SyncVar]
|
||||
public float localScaleSensitivity = .01f;
|
||||
|
||||
[Header("Diagnostics")]
|
||||
|
||||
// server
|
||||
public Vector3 lastPosition;
|
||||
public Quaternion lastRotation;
|
||||
public Vector3 lastScale;
|
||||
|
||||
// client
|
||||
// use local position/rotation for VR support
|
||||
[Serializable]
|
||||
public struct DataPoint
|
||||
{
|
||||
public float timeStamp;
|
||||
public Vector3 localPosition;
|
||||
public Quaternion localRotation;
|
||||
public Vector3 localScale;
|
||||
public float movementSpeed;
|
||||
|
||||
public bool isValid => timeStamp != 0;
|
||||
}
|
||||
|
||||
// Is this a client with authority over this transform?
|
||||
// This component could be on the player object or any object that has been assigned authority to this client.
|
||||
bool IsOwnerWithClientAuthority => hasAuthority && clientAuthority;
|
||||
|
||||
// interpolation start and goal
|
||||
public DataPoint start = new DataPoint();
|
||||
public DataPoint goal = new DataPoint();
|
||||
|
||||
// We need to store this locally on the server so clients can't request Authority when ever they like
|
||||
bool clientAuthorityBeforeTeleport;
|
||||
|
||||
void FixedUpdate()
|
||||
{
|
||||
// if server then always sync to others.
|
||||
// let the clients know that this has moved
|
||||
if (isServer && HasEitherMovedRotatedScaled())
|
||||
{
|
||||
ServerUpdate();
|
||||
}
|
||||
|
||||
if (isClient)
|
||||
{
|
||||
// send to server if we have local authority (and aren't the server)
|
||||
// -> only if connectionToServer has been initialized yet too
|
||||
if (IsOwnerWithClientAuthority)
|
||||
{
|
||||
ClientAuthorityUpdate();
|
||||
}
|
||||
else if (goal.isValid)
|
||||
{
|
||||
ClientRemoteUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ServerUpdate()
|
||||
{
|
||||
RpcMove(targetTransform.localPosition, Compression.CompressQuaternion(targetTransform.localRotation), targetTransform.localScale);
|
||||
}
|
||||
|
||||
void ClientAuthorityUpdate()
|
||||
{
|
||||
if (!isServer && HasEitherMovedRotatedScaled())
|
||||
{
|
||||
// serialize
|
||||
// local position/rotation for VR support
|
||||
// send to server
|
||||
CmdClientToServerSync(targetTransform.localPosition, Compression.CompressQuaternion(targetTransform.localRotation), targetTransform.localScale);
|
||||
}
|
||||
}
|
||||
|
||||
void ClientRemoteUpdate()
|
||||
{
|
||||
// teleport or interpolate
|
||||
if (NeedsTeleport())
|
||||
{
|
||||
// local position/rotation for VR support
|
||||
ApplyPositionRotationScale(goal.localPosition, goal.localRotation, goal.localScale);
|
||||
|
||||
// reset data points so we don't keep interpolating
|
||||
start = new DataPoint();
|
||||
goal = new DataPoint();
|
||||
}
|
||||
else
|
||||
{
|
||||
// local position/rotation for VR support
|
||||
ApplyPositionRotationScale(InterpolatePosition(start, goal, targetTransform.localPosition),
|
||||
InterpolateRotation(start, goal, targetTransform.localRotation),
|
||||
InterpolateScale(start, goal, targetTransform.localScale));
|
||||
}
|
||||
}
|
||||
|
||||
// moved or rotated or scaled since last time we checked it?
|
||||
bool HasEitherMovedRotatedScaled()
|
||||
{
|
||||
// Save last for next frame to compare only if change was detected, otherwise
|
||||
// slow moving objects might never sync because of C#'s float comparison tolerance.
|
||||
// See also: https://github.com/vis2k/Mirror/pull/428)
|
||||
bool changed = HasMoved || HasRotated || HasScaled;
|
||||
if (changed)
|
||||
{
|
||||
// local position/rotation for VR support
|
||||
if (syncPosition) lastPosition = targetTransform.localPosition;
|
||||
if (syncRotation) lastRotation = targetTransform.localRotation;
|
||||
if (syncScale) lastScale = targetTransform.localScale;
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
// local position/rotation for VR support
|
||||
// SqrMagnitude is faster than Distance per Unity docs
|
||||
// https://docs.unity3d.com/ScriptReference/Vector3-sqrMagnitude.html
|
||||
|
||||
bool HasMoved => syncPosition && Vector3.SqrMagnitude(lastPosition - targetTransform.localPosition) > localPositionSensitivity * localPositionSensitivity;
|
||||
bool HasRotated => syncRotation && Quaternion.Angle(lastRotation, targetTransform.localRotation) > localRotationSensitivity;
|
||||
bool HasScaled => syncScale && Vector3.SqrMagnitude(lastScale - targetTransform.localScale) > localScaleSensitivity * localScaleSensitivity;
|
||||
|
||||
// teleport / lag / stuck detection
|
||||
// - checking distance is not enough since there could be just a tiny fence between us and the goal
|
||||
// - checking time always works, this way we just teleport if we still didn't reach the goal after too much time has elapsed
|
||||
bool NeedsTeleport()
|
||||
{
|
||||
// calculate time between the two data points
|
||||
float startTime = start.isValid ? start.timeStamp : Time.time - Time.fixedDeltaTime;
|
||||
float goalTime = goal.isValid ? goal.timeStamp : Time.time;
|
||||
float difference = goalTime - startTime;
|
||||
float timeSinceGoalReceived = Time.time - goalTime;
|
||||
return timeSinceGoalReceived > difference * 5;
|
||||
}
|
||||
|
||||
// local authority client sends sync message to server for broadcasting
|
||||
[Command(channel = Channels.Unreliable)]
|
||||
void CmdClientToServerSync(Vector3 position, uint packedRotation, Vector3 scale)
|
||||
{
|
||||
// Ignore messages from client if not in client authority mode
|
||||
if (!clientAuthority)
|
||||
return;
|
||||
|
||||
// deserialize payload
|
||||
SetGoal(position, Compression.DecompressQuaternion(packedRotation), scale);
|
||||
|
||||
// server-only mode does no interpolation to save computations, but let's set the position directly
|
||||
if (isServer && !isClient)
|
||||
ApplyPositionRotationScale(goal.localPosition, goal.localRotation, goal.localScale);
|
||||
|
||||
RpcMove(position, packedRotation, scale);
|
||||
}
|
||||
|
||||
[ClientRpc(channel = Channels.Unreliable)]
|
||||
void RpcMove(Vector3 position, uint packedRotation, Vector3 scale)
|
||||
{
|
||||
if (hasAuthority && excludeOwnerUpdate) return;
|
||||
|
||||
if (!isServer)
|
||||
SetGoal(position, Compression.DecompressQuaternion(packedRotation), scale);
|
||||
}
|
||||
|
||||
// serialization is needed by OnSerialize and by manual sending from authority
|
||||
void SetGoal(Vector3 position, Quaternion rotation, Vector3 scale)
|
||||
{
|
||||
// put it into a data point immediately
|
||||
DataPoint temp = new DataPoint
|
||||
{
|
||||
// deserialize position
|
||||
localPosition = position,
|
||||
localRotation = rotation,
|
||||
localScale = scale,
|
||||
timeStamp = Time.time
|
||||
};
|
||||
|
||||
// movement speed: based on how far it moved since last time has to be calculated before 'start' is overwritten
|
||||
temp.movementSpeed = EstimateMovementSpeed(goal, temp, targetTransform, Time.fixedDeltaTime);
|
||||
|
||||
// reassign start wisely
|
||||
// first ever data point? then make something up for previous one so that we can start interpolation without waiting for next.
|
||||
if (start.timeStamp == 0)
|
||||
{
|
||||
start = new DataPoint
|
||||
{
|
||||
timeStamp = Time.time - Time.fixedDeltaTime,
|
||||
// local position/rotation for VR support
|
||||
localPosition = targetTransform.localPosition,
|
||||
localRotation = targetTransform.localRotation,
|
||||
localScale = targetTransform.localScale,
|
||||
movementSpeed = temp.movementSpeed
|
||||
};
|
||||
}
|
||||
// second or nth data point? then update previous
|
||||
// but: we start at where ever we are right now, so that it's perfectly smooth and we don't jump anywhere
|
||||
//
|
||||
// example if we are at 'x':
|
||||
//
|
||||
// A--x->B
|
||||
//
|
||||
// and then receive a new point C:
|
||||
//
|
||||
// A--x--B
|
||||
// |
|
||||
// |
|
||||
// C
|
||||
//
|
||||
// then we don't want to just jump to B and start interpolation:
|
||||
//
|
||||
// x
|
||||
// |
|
||||
// |
|
||||
// C
|
||||
//
|
||||
// we stay at 'x' and interpolate from there to C:
|
||||
//
|
||||
// x..B
|
||||
// \ .
|
||||
// \.
|
||||
// C
|
||||
//
|
||||
else
|
||||
{
|
||||
float oldDistance = Vector3.Distance(start.localPosition, goal.localPosition);
|
||||
float newDistance = Vector3.Distance(goal.localPosition, temp.localPosition);
|
||||
|
||||
start = goal;
|
||||
|
||||
// local position/rotation for VR support
|
||||
// teleport / lag / obstacle detection: only continue at current position if we aren't too far away
|
||||
// XC < AB + BC (see comments above)
|
||||
if (Vector3.Distance(targetTransform.localPosition, start.localPosition) < oldDistance + newDistance)
|
||||
{
|
||||
start.localPosition = targetTransform.localPosition;
|
||||
start.localRotation = targetTransform.localRotation;
|
||||
start.localScale = targetTransform.localScale;
|
||||
}
|
||||
}
|
||||
|
||||
// set new destination in any case. new data is best data.
|
||||
goal = temp;
|
||||
}
|
||||
|
||||
// try to estimate movement speed for a data point based on how far it moved since the previous one
|
||||
// - if this is the first time ever then we use our best guess:
|
||||
// - delta based on transform.localPosition
|
||||
// - elapsed based on send interval hoping that it roughly matches
|
||||
static float EstimateMovementSpeed(DataPoint from, DataPoint to, Transform transform, float sendInterval)
|
||||
{
|
||||
Vector3 delta = to.localPosition - (from.localPosition != transform.localPosition ? from.localPosition : transform.localPosition);
|
||||
float elapsed = from.isValid ? to.timeStamp - from.timeStamp : sendInterval;
|
||||
|
||||
// avoid NaN
|
||||
return elapsed > 0 ? delta.magnitude / elapsed : 0;
|
||||
}
|
||||
|
||||
// set position carefully depending on the target component
|
||||
void ApplyPositionRotationScale(Vector3 position, Quaternion rotation, Vector3 scale)
|
||||
{
|
||||
// local position/rotation for VR support
|
||||
if (syncPosition) targetTransform.localPosition = position;
|
||||
if (syncRotation) targetTransform.localRotation = rotation;
|
||||
if (syncScale) targetTransform.localScale = scale;
|
||||
}
|
||||
|
||||
// where are we in the timeline between start and goal? [0,1]
|
||||
Vector3 InterpolatePosition(DataPoint start, DataPoint goal, Vector3 currentPosition)
|
||||
{
|
||||
if (!interpolatePosition)
|
||||
return currentPosition;
|
||||
|
||||
if (start.movementSpeed != 0)
|
||||
{
|
||||
// Option 1: simply interpolate based on time, but stutter will happen, it's not that smooth.
|
||||
// This is especially noticeable if the camera automatically follows the player
|
||||
// - Tell SonarCloud this isn't really commented code but actual comments and to stfu about it
|
||||
// - float t = CurrentInterpolationFactor();
|
||||
// - return Vector3.Lerp(start.position, goal.position, t);
|
||||
|
||||
// Option 2: always += speed
|
||||
// speed is 0 if we just started after idle, so always use max for best results
|
||||
float speed = Mathf.Max(start.movementSpeed, goal.movementSpeed);
|
||||
return Vector3.MoveTowards(currentPosition, goal.localPosition, speed * Time.deltaTime);
|
||||
}
|
||||
|
||||
return currentPosition;
|
||||
}
|
||||
|
||||
Quaternion InterpolateRotation(DataPoint start, DataPoint goal, Quaternion defaultRotation)
|
||||
{
|
||||
if (!interpolateRotation)
|
||||
return defaultRotation;
|
||||
|
||||
if (start.localRotation != goal.localRotation)
|
||||
{
|
||||
float t = CurrentInterpolationFactor(start, goal);
|
||||
return Quaternion.Slerp(start.localRotation, goal.localRotation, t);
|
||||
}
|
||||
|
||||
return defaultRotation;
|
||||
}
|
||||
|
||||
Vector3 InterpolateScale(DataPoint start, DataPoint goal, Vector3 currentScale)
|
||||
{
|
||||
if (!interpolateScale)
|
||||
return currentScale;
|
||||
|
||||
if (start.localScale != goal.localScale)
|
||||
{
|
||||
float t = CurrentInterpolationFactor(start, goal);
|
||||
return Vector3.Lerp(start.localScale, goal.localScale, t);
|
||||
}
|
||||
|
||||
return currentScale;
|
||||
}
|
||||
|
||||
static float CurrentInterpolationFactor(DataPoint start, DataPoint goal)
|
||||
{
|
||||
if (start.isValid)
|
||||
{
|
||||
float difference = goal.timeStamp - start.timeStamp;
|
||||
|
||||
// the moment we get 'goal', 'start' is supposed to start, so elapsed time is based on:
|
||||
float elapsed = Time.time - goal.timeStamp;
|
||||
|
||||
// avoid NaN
|
||||
return difference > 0 ? elapsed / difference : 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#region Server Teleport (force move player)
|
||||
|
||||
/// <summary>
|
||||
/// This method will override this GameObject's current Transform.localPosition to the specified Vector3 and update all clients.
|
||||
/// <para>NOTE: position must be in LOCAL space if the transform has a parent</para>
|
||||
/// </summary>
|
||||
/// <param name="localPosition">Where to teleport this GameObject</param>
|
||||
[Server]
|
||||
public void ServerTeleport(Vector3 localPosition)
|
||||
{
|
||||
Quaternion localRotation = targetTransform.localRotation;
|
||||
ServerTeleport(localPosition, localRotation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method will override this GameObject's current Transform.localPosition and Transform.localRotation
|
||||
/// to the specified Vector3 and Quaternion and update all clients.
|
||||
/// <para>NOTE: localPosition must be in LOCAL space if the transform has a parent</para>
|
||||
/// <para>NOTE: localRotation must be in LOCAL space if the transform has a parent</para>
|
||||
/// </summary>
|
||||
/// <param name="localPosition">Where to teleport this GameObject</param>
|
||||
/// <param name="localRotation">Which rotation to set this GameObject</param>
|
||||
[Server]
|
||||
public void ServerTeleport(Vector3 localPosition, Quaternion localRotation)
|
||||
{
|
||||
// To prevent applying the position updates received from client (if they have ClientAuth) while being teleported.
|
||||
// clientAuthorityBeforeTeleport defaults to false when not teleporting, if it is true then it means that teleport
|
||||
// was previously called but not finished therefore we should keep it as true so that 2nd teleport call doesn't clear authority
|
||||
clientAuthorityBeforeTeleport = clientAuthority || clientAuthorityBeforeTeleport;
|
||||
clientAuthority = false;
|
||||
|
||||
DoTeleport(localPosition, localRotation);
|
||||
|
||||
// tell all clients about new values
|
||||
RpcTeleport(localPosition, Compression.CompressQuaternion(localRotation), clientAuthorityBeforeTeleport);
|
||||
}
|
||||
|
||||
void DoTeleport(Vector3 newLocalPosition, Quaternion newLocalRotation)
|
||||
{
|
||||
targetTransform.localPosition = newLocalPosition;
|
||||
targetTransform.localRotation = newLocalRotation;
|
||||
|
||||
// Since we are overriding the position we don't need a goal and start.
|
||||
// Reset them to null for fresh start
|
||||
goal = new DataPoint();
|
||||
start = new DataPoint();
|
||||
lastPosition = newLocalPosition;
|
||||
lastRotation = newLocalRotation;
|
||||
}
|
||||
|
||||
[ClientRpc(channel = Channels.Unreliable)]
|
||||
void RpcTeleport(Vector3 newPosition, uint newPackedRotation, bool isClientAuthority)
|
||||
{
|
||||
DoTeleport(newPosition, Compression.DecompressQuaternion(newPackedRotation));
|
||||
|
||||
// only send finished if is owner and is ClientAuthority on server
|
||||
if (hasAuthority && isClientAuthority)
|
||||
CmdTeleportFinished();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This RPC will be invoked on server after client finishes overriding the position.
|
||||
/// </summary>
|
||||
/// <param name="initialAuthority"></param>
|
||||
[Command(channel = Channels.Unreliable)]
|
||||
void CmdTeleportFinished()
|
||||
{
|
||||
if (clientAuthorityBeforeTeleport)
|
||||
{
|
||||
clientAuthority = true;
|
||||
|
||||
// reset value so doesn't effect future calls, see note in ServerTeleport
|
||||
clientAuthorityBeforeTeleport = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("Client called TeleportFinished when clientAuthority was false on server", this);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Debug Gizmos
|
||||
|
||||
// draw the data points for easier debugging
|
||||
void OnDrawGizmos()
|
||||
{
|
||||
// draw start and goal points and a line between them
|
||||
if (start.localPosition != goal.localPosition)
|
||||
{
|
||||
DrawDataPointGizmo(start, Color.yellow);
|
||||
DrawDataPointGizmo(goal, Color.green);
|
||||
DrawLineBetweenDataPoints(start, goal, Color.cyan);
|
||||
}
|
||||
}
|
||||
|
||||
static void DrawDataPointGizmo(DataPoint data, Color color)
|
||||
{
|
||||
// use a little offset because transform.localPosition might be in the ground in many cases
|
||||
Vector3 offset = Vector3.up * 0.01f;
|
||||
|
||||
// draw position
|
||||
Gizmos.color = color;
|
||||
Gizmos.DrawSphere(data.localPosition + offset, 0.5f);
|
||||
|
||||
// draw forward and up like unity move tool
|
||||
Gizmos.color = Color.blue;
|
||||
Gizmos.DrawRay(data.localPosition + offset, data.localRotation * Vector3.forward);
|
||||
Gizmos.color = Color.green;
|
||||
Gizmos.DrawRay(data.localPosition + offset, data.localRotation * Vector3.up);
|
||||
}
|
||||
|
||||
static void DrawLineBetweenDataPoints(DataPoint data1, DataPoint data2, Color color)
|
||||
{
|
||||
Gizmos.color = color;
|
||||
Gizmos.DrawLine(data1.localPosition, data2.localPosition);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ea7c690c4fbf8c4439726f4c62eda6d3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -1,20 +0,0 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Mirror.Experimental
|
||||
{
|
||||
/// <summary>
|
||||
/// A component to synchronize the position of child transforms of networked objects.
|
||||
/// <para>There must be a NetworkTransform on the root object of the hierarchy. There can be multiple NetworkTransformChild components on an object. This does not use physics for synchronization, it simply synchronizes the localPosition and localRotation of the child transform and lerps towards the received values.</para>
|
||||
/// </summary>
|
||||
// Deprecated 2022-01-18
|
||||
[Obsolete("Use the default NetworkTransform instead, it has proper snapshot interpolation.")]
|
||||
[AddComponentMenu("")]
|
||||
public class NetworkTransformChild : NetworkTransformBase
|
||||
{
|
||||
[Header("Target")]
|
||||
public Transform target;
|
||||
|
||||
protected override Transform targetTransform => target;
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f65214da13a861f4a8ae309d3daea1c6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -472,10 +472,7 @@ public override void OnStartClient()
|
||||
/// </summary>
|
||||
public override void OnClientConnect()
|
||||
{
|
||||
#pragma warning disable 618
|
||||
// obsolete method calls new method
|
||||
OnRoomClientConnect(NetworkClient.connection);
|
||||
#pragma warning restore 618
|
||||
OnRoomClientConnect();
|
||||
base.OnClientConnect();
|
||||
}
|
||||
|
||||
@ -485,9 +482,7 @@ public override void OnClientConnect()
|
||||
/// </summary>
|
||||
public override void OnClientDisconnect()
|
||||
{
|
||||
#pragma warning disable 618
|
||||
OnRoomClientDisconnect(NetworkClient.connection);
|
||||
#pragma warning restore 618
|
||||
OnRoomClientDisconnect();
|
||||
base.OnClientDisconnect();
|
||||
}
|
||||
|
||||
@ -516,10 +511,7 @@ public override void OnClientSceneChanged()
|
||||
CallOnClientExitRoom();
|
||||
|
||||
base.OnClientSceneChanged();
|
||||
#pragma warning disable 618
|
||||
// obsolete method calls new method
|
||||
OnRoomClientSceneChanged(NetworkClient.connection);
|
||||
#pragma warning restore 618
|
||||
OnRoomClientSceneChanged();
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -647,19 +639,11 @@ public virtual void OnRoomClientExit() {}
|
||||
/// </summary>
|
||||
public virtual void OnRoomClientConnect() {}
|
||||
|
||||
// Deprecated 2021-10-30
|
||||
[Obsolete("Remove NetworkConnection from your override and use NetworkClient.connection instead.")]
|
||||
public virtual void OnRoomClientConnect(NetworkConnection conn) => OnRoomClientConnect();
|
||||
|
||||
/// <summary>
|
||||
/// This is called on the client when disconnected from a server.
|
||||
/// </summary>
|
||||
public virtual void OnRoomClientDisconnect() {}
|
||||
|
||||
// Deprecated 2021-10-30
|
||||
[Obsolete("Remove NetworkConnection from your override and use NetworkClient.connection instead.")]
|
||||
public virtual void OnRoomClientDisconnect(NetworkConnection conn) => OnRoomClientDisconnect();
|
||||
|
||||
/// <summary>
|
||||
/// This is called on the client when a client is started.
|
||||
/// </summary>
|
||||
@ -675,10 +659,6 @@ public virtual void OnRoomStopClient() {}
|
||||
/// </summary>
|
||||
public virtual void OnRoomClientSceneChanged() {}
|
||||
|
||||
// Deprecated 2021-10-30
|
||||
[Obsolete("Remove NetworkConnection from your override and use NetworkClient.connection instead.")]
|
||||
public virtual void OnRoomClientSceneChanged(NetworkConnection conn) => OnRoomClientSceneChanged();
|
||||
|
||||
/// <summary>
|
||||
/// Called on the client when adding a player to the room fails.
|
||||
/// <para>This could be because the room is full, or the connection is not allowed to have more players.</para>
|
||||
|
@ -570,14 +570,6 @@ public void RpcTeleport(Vector3 destination, Quaternion rotation)
|
||||
OnTeleport(destination, rotation);
|
||||
}
|
||||
|
||||
// Deprecated 2022-01-19
|
||||
[Obsolete("Use RpcTeleport(Vector3, Quaternion) instead.")]
|
||||
[ClientRpc]
|
||||
public void RpcTeleportAndRotate(Vector3 destination, Quaternion rotation)
|
||||
{
|
||||
OnTeleport(destination, rotation);
|
||||
}
|
||||
|
||||
// client->server teleport to force position without interpolation.
|
||||
// otherwise it would interpolate to a (far away) new position.
|
||||
// => manually calling Teleport is the only 100% reliable solution.
|
||||
@ -622,16 +614,6 @@ public void CmdTeleport(Vector3 destination, Quaternion rotation)
|
||||
RpcTeleport(destination, rotation);
|
||||
}
|
||||
|
||||
// Deprecated 2022-01-19
|
||||
[Obsolete("Use CmdTeleport(Vector3, Quaternion) instead.")]
|
||||
[Command]
|
||||
public void CmdTeleportAndRotate(Vector3 destination, Quaternion rotation)
|
||||
{
|
||||
if (!clientAuthority) return;
|
||||
OnTeleport(destination, rotation);
|
||||
RpcTeleport(destination, rotation);
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
// disabled objects aren't updated anymore.
|
||||
|
@ -102,10 +102,6 @@ public abstract class NetworkBehaviour : MonoBehaviour
|
||||
protected bool GetSyncVarHookGuard(ulong dirtyBit) =>
|
||||
(syncVarHookGuard & dirtyBit) != 0UL;
|
||||
|
||||
// Deprecated 2021-09-16 (old weavers used it)
|
||||
[Obsolete("Renamed to GetSyncVarHookGuard (uppercase)")]
|
||||
protected bool getSyncVarHookGuard(ulong dirtyBit) => GetSyncVarHookGuard(dirtyBit);
|
||||
|
||||
// USED BY WEAVER to set syncvars in host mode without deadlocking
|
||||
protected void SetSyncVarHookGuard(ulong dirtyBit, bool value)
|
||||
{
|
||||
@ -117,10 +113,6 @@ protected void SetSyncVarHookGuard(ulong dirtyBit, bool value)
|
||||
syncVarHookGuard &= ~dirtyBit;
|
||||
}
|
||||
|
||||
// Deprecated 2021-09-16 (old weavers used it)
|
||||
[Obsolete("Renamed to SetSyncVarHookGuard (uppercase)")]
|
||||
protected void setSyncVarHookGuard(ulong dirtyBit, bool value) => SetSyncVarHookGuard(dirtyBit, value);
|
||||
|
||||
/// <summary>Set as dirty so that it's synced to clients again.</summary>
|
||||
// these are masks, not bit numbers, ie. 110011b not '2' for 2nd bit.
|
||||
public void SetSyncVarDirtyBit(ulong dirtyBit)
|
||||
@ -128,10 +120,6 @@ public void SetSyncVarDirtyBit(ulong dirtyBit)
|
||||
syncVarDirtyBits |= dirtyBit;
|
||||
}
|
||||
|
||||
// Deprecated 2021-09-19
|
||||
[Obsolete("SetDirtyBit was renamed to SetSyncVarDirtyBit because that's what it does")]
|
||||
public void SetDirtyBit(ulong dirtyBit) => SetSyncVarDirtyBit(dirtyBit);
|
||||
|
||||
// true if syncInterval elapsed and any SyncVar or SyncObject is dirty
|
||||
public bool IsDirty()
|
||||
{
|
||||
|
@ -955,10 +955,7 @@ void FinishLoadSceneHost()
|
||||
|
||||
if (clientReadyConnection != null)
|
||||
{
|
||||
#pragma warning disable 618
|
||||
// obsolete method calls new method because it's not empty
|
||||
OnClientConnect(clientReadyConnection);
|
||||
#pragma warning restore 618
|
||||
OnClientConnect();
|
||||
clientLoadedScene = true;
|
||||
clientReadyConnection = null;
|
||||
}
|
||||
@ -992,13 +989,7 @@ void FinishLoadSceneHost()
|
||||
OnServerSceneChanged(networkSceneName);
|
||||
|
||||
if (NetworkClient.isConnected)
|
||||
{
|
||||
// let client know that we changed scene
|
||||
#pragma warning disable 618
|
||||
// obsolete method calls new method because it's not empty
|
||||
OnClientSceneChanged(NetworkClient.connection);
|
||||
#pragma warning restore 618
|
||||
}
|
||||
OnClientSceneChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1024,21 +1015,13 @@ void FinishLoadSceneClientOnly()
|
||||
|
||||
if (clientReadyConnection != null)
|
||||
{
|
||||
#pragma warning disable 618
|
||||
// obsolete method calls new method because it's not empty
|
||||
OnClientConnect(clientReadyConnection);
|
||||
#pragma warning restore 618
|
||||
OnClientConnect();
|
||||
clientLoadedScene = true;
|
||||
clientReadyConnection = null;
|
||||
}
|
||||
|
||||
if (NetworkClient.isConnected)
|
||||
{
|
||||
#pragma warning disable 618
|
||||
// obsolete method calls new method because it's not empty
|
||||
OnClientSceneChanged(NetworkClient.connection);
|
||||
#pragma warning restore 618
|
||||
}
|
||||
OnClientSceneChanged();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1184,10 +1167,7 @@ void OnClientAuthenticated()
|
||||
if (string.IsNullOrWhiteSpace(onlineScene) || onlineScene == offlineScene || IsSceneActive(onlineScene))
|
||||
{
|
||||
clientLoadedScene = false;
|
||||
#pragma warning disable 618
|
||||
// obsolete method calls new method because it's not empty
|
||||
OnClientConnect(NetworkClient.connection);
|
||||
#pragma warning restore 618
|
||||
OnClientConnect();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1200,19 +1180,13 @@ void OnClientAuthenticated()
|
||||
void OnClientDisconnectInternal()
|
||||
{
|
||||
//Debug.Log("NetworkManager.OnClientDisconnectInternal");
|
||||
#pragma warning disable 618
|
||||
// obsolete method calls new method because it's not empty
|
||||
OnClientDisconnect(NetworkClient.connection);
|
||||
#pragma warning restore 618
|
||||
OnClientDisconnect();
|
||||
}
|
||||
|
||||
void OnClientNotReadyMessageInternal(NotReadyMessage msg)
|
||||
{
|
||||
//Debug.Log("NetworkManager.OnClientNotReadyMessageInternal");
|
||||
NetworkClient.ready = false;
|
||||
#pragma warning disable 618
|
||||
OnClientNotReady(NetworkClient.connection);
|
||||
#pragma warning restore 618
|
||||
OnClientNotReady();
|
||||
|
||||
// NOTE: clientReadyConnection is not set here! don't want OnClientConnect to be invoked again after scene changes.
|
||||
@ -1296,10 +1270,6 @@ public virtual void OnClientConnect()
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated 2021-12-11
|
||||
[Obsolete("Remove the NetworkConnection parameter in your override and use NetworkClient.connection instead.")]
|
||||
public virtual void OnClientConnect(NetworkConnection conn) => OnClientConnect();
|
||||
|
||||
/// <summary>Called on clients when disconnected from a server.</summary>
|
||||
public virtual void OnClientDisconnect()
|
||||
{
|
||||
@ -1309,20 +1279,12 @@ public virtual void OnClientDisconnect()
|
||||
StopClient();
|
||||
}
|
||||
|
||||
// Deprecated 2021-12-11
|
||||
[Obsolete("Remove the NetworkConnection parameter in your override and use NetworkClient.connection instead.")]
|
||||
public virtual void OnClientDisconnect(NetworkConnection conn) => OnClientDisconnect();
|
||||
|
||||
/// <summary>Called on client when transport raises an exception.</summary>
|
||||
public virtual void OnClientError(Exception exception) {}
|
||||
|
||||
/// <summary>Called on clients when a servers tells the client it is no longer ready, e.g. when switching scenes.</summary>
|
||||
public virtual void OnClientNotReady() {}
|
||||
|
||||
// Deprecated 2021-12-11
|
||||
[Obsolete("Remove the NetworkConnection parameter in your override and use NetworkClient.connection instead.")]
|
||||
public virtual void OnClientNotReady(NetworkConnection conn) {}
|
||||
|
||||
/// <summary>Called from ClientChangeScene immediately before SceneManager.LoadSceneAsync is executed</summary>
|
||||
// customHandling: indicates if scene loading will be handled through overrides
|
||||
public virtual void OnClientChangeScene(string newSceneName, SceneOperation sceneOperation, bool customHandling) {}
|
||||
@ -1344,10 +1306,6 @@ public virtual void OnClientSceneChanged()
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated 2021-12-11
|
||||
[Obsolete("Remove the NetworkConnection parameter in your override and use NetworkClient.connection instead.")]
|
||||
public virtual void OnClientSceneChanged(NetworkConnection conn) => OnClientSceneChanged();
|
||||
|
||||
// Since there are multiple versions of StartServer, StartClient and
|
||||
// StartHost, to reliably customize their functionality, users would
|
||||
// need override all the versions. Instead these callbacks are invoked
|
||||
|
@ -264,11 +264,6 @@ internal static void RemoveLocalConnection()
|
||||
RemoveConnection(0);
|
||||
}
|
||||
|
||||
/// <summary>True if we have no external connections (host is allowed)</summary>
|
||||
// DEPRECATED 2022-02-05
|
||||
[Obsolete("Use !HasExternalConnections() instead of NoExternalConnections() to avoid double negatives.")]
|
||||
public static bool NoExternalConnections() => !HasExternalConnections();
|
||||
|
||||
/// <summary>True if we have external connections (that are not host)</summary>
|
||||
public static bool HasExternalConnections()
|
||||
{
|
||||
@ -388,12 +383,6 @@ public static void SendToReadyObservers<T>(NetworkIdentity identity, T message,
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated 2021-09-19
|
||||
[Obsolete("SendToReady(identity, message, ...) was renamed to SendToReadyObservers because that's what it does.")]
|
||||
public static void SendToReady<T>(NetworkIdentity identity, T message, bool includeOwner = true, int channelId = Channels.Reliable)
|
||||
where T : struct, NetworkMessage =>
|
||||
SendToReadyObservers(identity, message, includeOwner, channelId);
|
||||
|
||||
/// <summary>Send a message to only clients which are ready including the owner of the NetworkIdentity</summary>
|
||||
// TODO put rpcs into NetworkServer.Update WorldState packet, then finally remove SendToReady!
|
||||
public static void SendToReadyObservers<T>(NetworkIdentity identity, T message, int channelId)
|
||||
@ -402,12 +391,6 @@ public static void SendToReadyObservers<T>(NetworkIdentity identity, T message,
|
||||
SendToReadyObservers(identity, message, true, channelId);
|
||||
}
|
||||
|
||||
// Deprecated 2021-09-19
|
||||
[Obsolete("SendToReady(identity, message, ...) was renamed to SendToReadyObservers because that's what it does.")]
|
||||
public static void SendToReady<T>(NetworkIdentity identity, T message, int channelId)
|
||||
where T : struct, NetworkMessage =>
|
||||
SendToReadyObservers(identity, message, channelId);
|
||||
|
||||
// transport events ////////////////////////////////////////////////////
|
||||
// called by transport
|
||||
static void OnTransportConnected(int connectionId)
|
||||
|
@ -29,10 +29,6 @@ public abstract class SyncObject
|
||||
// Consider the object fully synchronized with clients
|
||||
public abstract void ClearChanges();
|
||||
|
||||
// Deprecated 2021-09-17
|
||||
[Obsolete("Deprecated: Use ClearChanges instead.")]
|
||||
public void Flush() => ClearChanges();
|
||||
|
||||
/// <summary>Write a full copy of the object</summary>
|
||||
public abstract void OnSerializeAll(NetworkWriter writer);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user