aha
This commit is contained in:
104
Assets/Mirror/Examples/AdditiveLevels/Scripts/Portal.cs
Normal file
104
Assets/Mirror/Examples/AdditiveLevels/Scripts/Portal.cs
Normal file
@ -0,0 +1,104 @@
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace Mirror.Examples.AdditiveLevels
|
||||
{
|
||||
public class Portal : NetworkBehaviour
|
||||
{
|
||||
[Scene, Tooltip("Which scene to send player from here")]
|
||||
public string destinationScene;
|
||||
|
||||
[Tooltip("Where to spawn player in Destination Scene")]
|
||||
public Vector3 startPosition;
|
||||
|
||||
[Tooltip("Reference to child TextMesh label")]
|
||||
public TextMesh label; // don't depend on TMPro. 2019 errors.
|
||||
|
||||
[SyncVar(hook = nameof(OnLabelTextChanged))]
|
||||
public string labelText;
|
||||
|
||||
public void OnLabelTextChanged(string _, string newValue)
|
||||
{
|
||||
label.text = labelText;
|
||||
}
|
||||
|
||||
public override void OnStartServer()
|
||||
{
|
||||
labelText = Path.GetFileNameWithoutExtension(destinationScene).Replace("MirrorAdditiveLevels", "");
|
||||
|
||||
// Simple Regex to insert spaces before capitals, numbers
|
||||
labelText = Regex.Replace(labelText, @"\B[A-Z0-9]+", " $0");
|
||||
}
|
||||
|
||||
public override void OnStartClient()
|
||||
{
|
||||
if (label.TryGetComponent(out LookAtMainCamera lookAtMainCamera))
|
||||
lookAtMainCamera.enabled = true;
|
||||
}
|
||||
|
||||
// Note that I have created layers called Player(6) and Portal(7) and set them
|
||||
// up in the Physics collision matrix so only Player collides with Portal.
|
||||
void OnTriggerEnter(Collider other)
|
||||
{
|
||||
if (!(other is CapsuleCollider)) return; // ignore CharacterController colliders
|
||||
|
||||
//Debug.Log($"Portal.OnTriggerEnter {other}");
|
||||
// tag check in case you didn't set up the layers and matrix as noted above
|
||||
if (!other.CompareTag("Player")) return;
|
||||
|
||||
// applies to host client on server and remote clients
|
||||
if (other.TryGetComponent(out Common.Controllers.Player.PlayerControllerBase playerController))
|
||||
playerController.enabled = false;
|
||||
|
||||
if (isServer)
|
||||
StartCoroutine(SendPlayerToNewScene(other.gameObject));
|
||||
}
|
||||
|
||||
[ServerCallback]
|
||||
IEnumerator SendPlayerToNewScene(GameObject player)
|
||||
{
|
||||
if (!player.TryGetComponent(out NetworkIdentity identity)) yield break;
|
||||
|
||||
NetworkConnectionToClient conn = identity.connectionToClient;
|
||||
if (conn == null) yield break;
|
||||
|
||||
// Tell client to unload previous subscene with custom handling (see NetworkManager::OnClientChangeScene).
|
||||
conn.Send(new SceneMessage { sceneName = gameObject.scene.path, sceneOperation = SceneOperation.UnloadAdditive, customHandling = true });
|
||||
|
||||
// wait for fader to complete.
|
||||
yield return new WaitForSeconds(AdditiveLevelsNetworkManager.singleton.fadeInOut.GetFadeInTime());
|
||||
|
||||
// Remove player after fader has completed
|
||||
NetworkServer.RemovePlayerForConnection(conn, RemovePlayerOptions.Unspawn);
|
||||
|
||||
// yield a frame allowing interest management to update
|
||||
// and all spawned objects to be destroyed on client
|
||||
yield return null;
|
||||
|
||||
// reposition player on server and client
|
||||
player.transform.position = startPosition;
|
||||
|
||||
// Rotate player to face center of scene
|
||||
// Player is 2m tall with pivot at 0,1,0 so we need to look at
|
||||
// 1m height to not tilt the player down to look at origin
|
||||
player.transform.LookAt(Vector3.up);
|
||||
|
||||
// Move player to new subscene.
|
||||
SceneManager.MoveGameObjectToScene(player, SceneManager.GetSceneByPath(destinationScene));
|
||||
|
||||
// Tell client to load the new subscene with custom handling (see NetworkManager::OnClientChangeScene).
|
||||
conn.Send(new SceneMessage { sceneName = destinationScene, sceneOperation = SceneOperation.LoadAdditive, customHandling = true });
|
||||
|
||||
// Player will be spawned after destination scene is loaded
|
||||
NetworkServer.AddPlayerForConnection(conn, player);
|
||||
|
||||
// host client playerController would have been disabled by OnTriggerEnter above
|
||||
// Remote client players are respawned with playerController already enabled
|
||||
if (NetworkClient.localPlayer != null && NetworkClient.localPlayer.TryGetComponent(out Common.Controllers.Player.PlayerControllerBase playerController))
|
||||
playerController.enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user