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 ///