fishnet installed
This commit is contained in:
@ -0,0 +1,75 @@
|
||||
using FishNet.Connection;
|
||||
using FishNet.Object;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FishNet.Example.Scened
|
||||
{
|
||||
|
||||
|
||||
public class PlayerController : NetworkBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
private GameObject _camera;
|
||||
[SerializeField]
|
||||
private float _moveRate = 4f;
|
||||
[SerializeField]
|
||||
private bool _clientAuth = true;
|
||||
|
||||
public override void OnStartClient()
|
||||
{
|
||||
base.OnStartClient();
|
||||
if (base.IsOwner)
|
||||
_camera.SetActive(true);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!base.IsOwner)
|
||||
return;
|
||||
|
||||
float hor = Input.GetAxisRaw("Horizontal");
|
||||
float ver = Input.GetAxisRaw("Vertical");
|
||||
|
||||
/* If ground cannot be found for 20 units then bump up 3 units.
|
||||
* This is just to keep player on ground if they fall through
|
||||
* when changing scenes. */
|
||||
if (_clientAuth || (!_clientAuth && base.IsServer))
|
||||
{
|
||||
if (!Physics.Linecast(transform.position + new Vector3(0f, 0.3f, 0f), transform.position - (Vector3.one * 20f)))
|
||||
transform.position += new Vector3(0f, 3f, 0f);
|
||||
}
|
||||
|
||||
if (_clientAuth)
|
||||
Move(hor, ver);
|
||||
else
|
||||
ServerMove(hor, ver);
|
||||
}
|
||||
|
||||
[ServerRpc]
|
||||
private void ServerMove(float hor, float ver)
|
||||
{
|
||||
Move(hor, ver);
|
||||
}
|
||||
|
||||
private void Move(float hor, float ver)
|
||||
{
|
||||
float gravity = -10f * Time.deltaTime;
|
||||
//If ray hits floor then cancel gravity.
|
||||
Ray ray = new Ray(transform.position + new Vector3(0f, 0.05f, 0f), -Vector3.up);
|
||||
if (Physics.Raycast(ray, 0.1f + -gravity))
|
||||
gravity = 0f;
|
||||
|
||||
/* Moving. */
|
||||
Vector3 direction = new Vector3(
|
||||
0f,
|
||||
gravity,
|
||||
ver * _moveRate * Time.deltaTime);
|
||||
|
||||
transform.position += transform.TransformDirection(direction);
|
||||
transform.Rotate(new Vector3(0f, hor * 100f * Time.deltaTime, 0f));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26e4f626a9ca9704f9befe7673a8dd15
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,148 @@
|
||||
using FishNet.Connection;
|
||||
using FishNet.Managing.Logging;
|
||||
using FishNet.Managing.Scened;
|
||||
using FishNet.Object;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FishNet.Example.Scened
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Loads a single scene, additive scenes, or both when a client
|
||||
/// enters or exits this trigger.
|
||||
/// </summary>
|
||||
public class SceneLoaderExample : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// True to move the triggering object.
|
||||
/// </summary>
|
||||
[Tooltip("True to move the triggering object.")]
|
||||
[SerializeField]
|
||||
private bool _moveObject = true;
|
||||
/// <summary>
|
||||
/// True to move all connection objects (clients).
|
||||
/// </summary>
|
||||
[Tooltip("True to move all connection objects (clients).")]
|
||||
[SerializeField]
|
||||
private bool _moveAllObjects;
|
||||
/// <summary>
|
||||
/// True to replace current scenes with new scenes. First scene loaded will become active scene.
|
||||
/// </summary>
|
||||
[Tooltip("True to replace current scenes with new scenes. First scene loaded will become active scene.")]
|
||||
[SerializeField]
|
||||
private ReplaceOption _replaceOption = ReplaceOption.None;
|
||||
/// <summary>
|
||||
/// Scenes to load.
|
||||
/// </summary>
|
||||
[Tooltip("Scenes to load.")]
|
||||
[SerializeField]
|
||||
private string[] _scenes = new string[0];
|
||||
/// <summary>
|
||||
/// True to only unload for the connectioning causing the trigger.
|
||||
/// </summary>
|
||||
[Tooltip("True to only unload for the connectioning causing the trigger.")]
|
||||
[SerializeField]
|
||||
private bool _connectionOnly;
|
||||
/// <summary>
|
||||
/// True to automatically unload the loaded scenes when no more connections are using them.
|
||||
/// </summary>
|
||||
[Tooltip("True to automatically unload the loaded scenes when no more connections are using them.")]
|
||||
[SerializeField]
|
||||
private bool _automaticallyUnload = true;
|
||||
/// <summary>
|
||||
/// True to fire when entering the trigger. False to fire when exiting the trigger.
|
||||
/// </summary>
|
||||
[Tooltip("True to fire when entering the trigger. False to fire when exiting the trigger.")]
|
||||
[SerializeField]
|
||||
private bool _onTriggerEnter = true;
|
||||
|
||||
/// <summary>
|
||||
/// Used to prevent excessive triggering when two clients are loaded and server is separate.
|
||||
/// Client may enter trigger intentionally then when moved to a new scene will re-enter trigger
|
||||
/// since original scene will still be loaded on server due to another client being in it.
|
||||
/// This scenario is extremely unlikely in production but keep it in mind.
|
||||
/// </summary>
|
||||
private Dictionary<NetworkConnection, float> _triggeredTimes = new Dictionary<NetworkConnection, float>();
|
||||
|
||||
|
||||
[Server(Logging = LoggingType.Off)]
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
if (!_onTriggerEnter)
|
||||
return;
|
||||
|
||||
LoadScene(other.GetComponent<NetworkObject>());
|
||||
}
|
||||
|
||||
[Server(Logging = LoggingType.Off)]
|
||||
private void OnTriggerExit(Collider other)
|
||||
{
|
||||
if (_onTriggerEnter)
|
||||
return;
|
||||
|
||||
LoadScene(other.GetComponent<NetworkObject>());
|
||||
}
|
||||
|
||||
private void LoadScene(NetworkObject triggeringIdentity)
|
||||
{
|
||||
if (!InstanceFinder.NetworkManager.IsServer)
|
||||
return;
|
||||
|
||||
//NetworkObject isn't necessarily needed but to ensure its the player only run if found.
|
||||
if (triggeringIdentity == null)
|
||||
return;
|
||||
|
||||
/* Dont let trigger hit twice by same connection too frequently
|
||||
* See _triggeredTimes field for more info. */
|
||||
if (_triggeredTimes.TryGetValue(triggeringIdentity.Owner, out float time))
|
||||
{
|
||||
if (Time.time - time < 0.5f)
|
||||
return;
|
||||
}
|
||||
_triggeredTimes[triggeringIdentity.Owner] = Time.time;
|
||||
|
||||
//Which objects to move.
|
||||
List<NetworkObject> movedObjects = new List<NetworkObject>();
|
||||
if (_moveAllObjects)
|
||||
{
|
||||
foreach (NetworkConnection item in InstanceFinder.ServerManager.Clients.Values)
|
||||
{
|
||||
foreach (NetworkObject nob in item.Objects)
|
||||
movedObjects.Add(nob);
|
||||
}
|
||||
}
|
||||
else if (_moveObject)
|
||||
{
|
||||
movedObjects.Add(triggeringIdentity);
|
||||
}
|
||||
//Load options.
|
||||
LoadOptions loadOptions = new LoadOptions
|
||||
{
|
||||
AutomaticallyUnload = _automaticallyUnload,
|
||||
};
|
||||
|
||||
//Make scene data.
|
||||
SceneLoadData sld = new SceneLoadData(_scenes);
|
||||
sld.PreferredActiveScene = sld.SceneLookupDatas[0];
|
||||
sld.ReplaceScenes = _replaceOption;
|
||||
sld.Options = loadOptions;
|
||||
sld.MovedNetworkObjects = movedObjects.ToArray();
|
||||
|
||||
//Load for connection only.
|
||||
if (_connectionOnly)
|
||||
InstanceFinder.SceneManager.LoadConnectionScenes(triggeringIdentity.Owner, sld);
|
||||
//Load for all clients.
|
||||
else
|
||||
InstanceFinder.SceneManager.LoadGlobalScenes(sld);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fa23b6e6f9b08d74885e3707aa0d9bc7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,91 @@
|
||||
using FishNet.Managing.Logging;
|
||||
using FishNet.Managing.Scened;
|
||||
using FishNet.Object;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FishNet.Example.Scened
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Unloads specified scenes when entering or exiting this trigger.
|
||||
/// </summary>
|
||||
public class SceneUnloaderExample : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// Scenes to unload.
|
||||
/// </summary>
|
||||
[Tooltip("Scenes to unload.")]
|
||||
[SerializeField]
|
||||
private string[] _scenes = new string[0];
|
||||
/// <summary>
|
||||
/// True to only unload for the connectioning causing the trigger.
|
||||
/// </summary>
|
||||
[Tooltip("True to only unload for the connectioning causing the trigger.")]
|
||||
[SerializeField]
|
||||
private bool _connectionOnly;
|
||||
/// <summary>
|
||||
/// True to unload unused scenes.
|
||||
/// </summary>
|
||||
[Tooltip("True to unload unused scenes.")]
|
||||
[SerializeField]
|
||||
private bool _unloadUnused = true;
|
||||
/// <summary>
|
||||
/// True to fire when entering the trigger. False to fire when exiting the trigger.
|
||||
/// </summary>
|
||||
[Tooltip("True to fire when entering the trigger. False to fire when exiting the trigger.")]
|
||||
[SerializeField]
|
||||
private bool _onTriggerEnter = true;
|
||||
|
||||
|
||||
[Server(Logging = LoggingType.Off)]
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
if (!_onTriggerEnter)
|
||||
return;
|
||||
|
||||
UnloadScenes(other.gameObject.GetComponent<NetworkObject>());
|
||||
}
|
||||
|
||||
[Server(Logging = LoggingType.Off)]
|
||||
private void OnTriggerExit(Collider other)
|
||||
{
|
||||
if (_onTriggerEnter)
|
||||
return;
|
||||
|
||||
UnloadScenes(other.gameObject.GetComponent<NetworkObject>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unload scenes.
|
||||
/// </summary>
|
||||
/// <param name="triggeringIdentity"></param>
|
||||
private void UnloadScenes(NetworkObject triggeringIdentity)
|
||||
{
|
||||
if (!InstanceFinder.NetworkManager.IsServer)
|
||||
return;
|
||||
|
||||
//NetworkObject isn't necessarily needed but to ensure its the player only run if nob is found.
|
||||
if (triggeringIdentity == null)
|
||||
return;
|
||||
|
||||
UnloadOptions unloadOptions = new UnloadOptions()
|
||||
{
|
||||
Mode = (_unloadUnused) ? UnloadOptions.ServerUnloadMode.UnloadUnused : UnloadOptions.ServerUnloadMode.KeepUnused
|
||||
};
|
||||
|
||||
SceneUnloadData sud = new SceneUnloadData(_scenes);
|
||||
sud.Options = unloadOptions;
|
||||
|
||||
//Unload only for the triggering connection.
|
||||
if (_connectionOnly)
|
||||
InstanceFinder.SceneManager.UnloadConnectionScenes(triggeringIdentity.Owner, sud);
|
||||
//Unload for all players.
|
||||
else
|
||||
InstanceFinder.SceneManager.UnloadGlobalScenes(sud);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 84ae572fef1171b41ab287d1c9b5da63
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user