diff --git a/Assets/Mirror/Components/NetworkTransform2k/NetworkTransformBase.cs b/Assets/Mirror/Components/NetworkTransform2k/NetworkTransformBase.cs
index 15dea23d4..7f2171846 100644
--- a/Assets/Mirror/Components/NetworkTransform2k/NetworkTransformBase.cs
+++ b/Assets/Mirror/Components/NetworkTransform2k/NetworkTransformBase.cs
@@ -412,6 +412,23 @@ protected virtual void OnTeleport(Vector3 destination)
// -> maybe add destionation as first entry?
}
+ // common Teleport code for client->server and server->client
+ protected virtual void OnTeleport(Vector3 destination, Quaternion rotation)
+ {
+ // reset any in-progress interpolation & buffers
+ Reset();
+
+ // set the new position.
+ // interpolation will automatically continue.
+ targetComponent.position = destination;
+ targetComponent.rotation = rotation;
+
+ // TODO
+ // what if we still receive a snapshot from before the interpolation?
+ // it could easily happen over unreliable.
+ // -> maybe add destionation as first entry?
+ }
+
// server->client 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.
@@ -428,6 +445,22 @@ public void RpcTeleport(Vector3 destination)
OnTeleport(destination);
}
+ // server->client teleport to force position and rotation without interpolation.
+ // otherwise it would interpolate to a (far away) new position.
+ // => manually calling Teleport is the only 100% reliable solution.
+ [ClientRpc]
+ public void RpcTeleportAndRotate(Vector3 destination, Quaternion rotation)
+ {
+ // NOTE: even in client authority mode, the server is always allowed
+ // to teleport the player. for example:
+ // * CmdEnterPortal() might teleport the player
+ // * Some people use client authority with server sided checks
+ // so the server should be able to reset position if needed.
+
+ // TODO what about host mode?
+ 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.
@@ -450,6 +483,28 @@ public void CmdTeleport(Vector3 destination)
RpcTeleport(destination);
}
+ // client->server teleport to force position and rotation without interpolation.
+ // otherwise it would interpolate to a (far away) new position.
+ // => manually calling Teleport is the only 100% reliable solution.
+ [Command]
+ public void CmdTeleportAndRotate(Vector3 destination, Quaternion rotation)
+ {
+ // client can only teleport objects that it has authority over.
+ if (!clientAuthority) return;
+
+ // TODO what about host mode?
+ OnTeleport(destination, rotation);
+
+ // if a client teleports, we need to broadcast to everyone else too
+ // TODO the teleported client should ignore the rpc though.
+ // otherwise if it already moved again after teleporting,
+ // the rpc would come a little bit later and reset it once.
+ // TODO or not? if client ONLY calls Teleport(pos), the position
+ // would only be set after the rpc. unless the client calls
+ // BOTH Teleport(pos) and targetComponent.position=pos
+ RpcTeleportAndRotate(destination, rotation);
+ }
+
protected virtual void Reset()
{
// disabled objects aren't updated anymore.
diff --git a/Assets/ScriptTemplates/57-Mirror__Network Transform-NewNetworkTransform.cs.txt b/Assets/ScriptTemplates/57-Mirror__Network Transform-NewNetworkTransform.cs.txt
index 1939d2cfd..15fda53b2 100644
--- a/Assets/ScriptTemplates/57-Mirror__Network Transform-NewNetworkTransform.cs.txt
+++ b/Assets/ScriptTemplates/57-Mirror__Network Transform-NewNetworkTransform.cs.txt
@@ -94,6 +94,16 @@ public class #SCRIPTNAME# : NetworkTransformBase
base.OnTeleport(destination);
}
+ ///
+ /// Called by both CmdTeleportAndRotate and RpcTeleportAndRotate on server and clients, respectively.
+ /// Here you can disable a Character Controller before calling the base method,
+ /// and re-enabling it after the base method call to avoid conflicting with it.
+ ///
+ protected override void OnTeleport(Vector3 destination, Quaternion rotation)
+ {
+ base.OnTeleport(destination, rotation);
+ }
+
///
/// NTSnapshot struct is created here
///