新增FishNet文档
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
---
|
||||
description: >-
|
||||
Fish-Networking features an advanced area-of-interest system that controls
|
||||
which clients receive updates about specific objects.
|
||||
---
|
||||
|
||||
# Area of Interest (Observer System)
|
||||
|
||||
An **observer** is a client which can see an object and use communications for the object. You may control which clients can observe an object by using the [NetworkObserver](../../../fishnet-building-blocks/components/network-observer.md) and/or [ObserverManager](../../../fishnet-building-blocks/components/managers/observermanager/) components.
|
||||
|
||||
If a client is not an observer of an object, then the object will not activate, and the client will not receive network messages or callbacks for that object. Should the object be a [scene object](../../high-level-overview/terminology/miscellaneous.md#scene-object) then it will remain disabled on the client until they become an observer of it. If the object is [instantiated](../../high-level-overview/terminology/miscellaneous.md#instantiated-object), then the client will simply not instantiate the object until after becoming an observer.
|
||||
|
||||
The observer system is designed to work out of the box for new developers. When it comes time to customize how clients observe objects, the observer system additionally offers a large amount of flexibility, keeping in mind there are many condition types, and that you may also create your own.
|
||||
|
||||
FishNet comes with a NetworkManager prefab which contains the recommended minimum components to begin working on a new project. Within that prefab is the [ObserverManager](../../../fishnet-building-blocks/components/managers/observermanager/) with an included [Scene Condition](../../../fishnet-building-blocks/components/network-observer.md#component-settings). If you have not familiarized yourself with the ObserverManager and condition types, please do so now using the links above.
|
||||
|
||||
A common problem new developers encounter is scene network objects not being enabled for clients. This occurs when the client is not considered part of the scene where the object resides, and the scene condition is preventing that object from spawning for the client. The NetworkManager prefab contains a PlayerSpawner script which adds the player to the current scene; this makes the client an observer for objects in that scene. This requires a player object to be spawned. Should you have made your own NetworkManager object or removed the PlayerSpawner script you will need to add the client to the scene you wish the client to be an observer of.
|
||||
|
||||
<div data-full-width="false"><figure><img src="../../../.gitbook/assets/player-spawner-component.png" alt=""><figcaption><p>The "Add To Default Scene" option enabled on the PlayerSpawner</p></figcaption></figure></div>
|
||||
|
||||
When encountering such an issue you may of course also remove the ObserverManager or scene condition from the ObserverManager, but this is not recommended as objects in other scenes will attempt to spawn for clients which do not occupy such scenes. Alternatively, you may add the client to the scene where the objects reside; there's a variety of ways to accomplish this.
|
||||
|
||||
You can use a script such as the following on an object in the scene. But be careful not to place it on a potentially DDoL object such as the NetworkManager.
|
||||
|
||||
{% code expandable="true" %}
|
||||
```csharp
|
||||
using FishNet;
|
||||
using FishNet.Connection;
|
||||
using UnityEngine;
|
||||
|
||||
public class InitialSceneObserver : MonoBehaviour
|
||||
{
|
||||
private void Start()
|
||||
{
|
||||
NetworkManager networkManager = InstanceFinder.NetworkManager;
|
||||
if (networkManager != null)
|
||||
networkManager.SceneManager.OnClientLoadedStartScenes += OnClientLoadedStartScenes;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
NetworkManager networkManager = InstanceFinder.NetworkManager;
|
||||
if (networkManager != null)
|
||||
networkManager.SceneManager.OnClientLoadedStartScenes -= OnClientLoadedStartScenes;
|
||||
}
|
||||
|
||||
private void OnClientLoadedStartScenes(NetworkConnection conn, bool asServer)
|
||||
{
|
||||
if (!asServer)
|
||||
return;
|
||||
|
||||
if (!conn.Scenes.Contains(gameObject.scene))
|
||||
InstanceFinder.NetworkManager.SceneManager.AddConnectionToScene(conn, gameObject.scene);
|
||||
}
|
||||
}
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
Under the assumption you removed the PlayerSpawner and/or are not using _SceneManager.AddOwnerToDefaultScene_ or the method above, then you must load the client into the scene using the SceneManager. Clients are only considered networked into scenes when those scenes are loaded using the SceneManager. Clients may become part of a scene by loading a scene globally or by loading a scene for a specific client (connection). See the [SceneManager](../scene-management/) section for more information on how to manage networked client scenes as well understand the difference between global and connection scenes.
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
description: A simple guide on how to write a custom observer condition.
|
||||
---
|
||||
|
||||
# Custom Conditions
|
||||
|
||||
Sometimes you may have unique requirements for an observer condition. When this is the case you can easily create your own ObserverCondition. The code below comments on how to create your own condition.
|
||||
|
||||
```csharp
|
||||
// The example below does not have many practical uses
|
||||
// but it shows the bare minimum needed to create a custom condition.
|
||||
// This condition makes an object only visible if the connections
|
||||
// ClientId mathes the serialized value, _id.
|
||||
|
||||
// Make a new class which inherits from ObserverCondition.
|
||||
// ObserverCondition is a scriptable object, so also create an asset
|
||||
// menu to create a new scriptable object of your condition.
|
||||
[CreateAssetMenu(menuName = "FishNet/Observers/ClientId Condition", fileName = "New ClientId Condition")]
|
||||
public class ClientIdCondition : ObserverCondition
|
||||
{
|
||||
/// <summary>
|
||||
/// ClientId a connection must be to pass the condition.
|
||||
/// </summary>
|
||||
[Tooltip("ClientId a connection must be to pass the condition.")]
|
||||
[SerializeField]
|
||||
private int _id = 0;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// Awake can be optionally used to initialize values based on serialized
|
||||
// data. The source file of DistanceCondition is a good example
|
||||
// of where Awake may be used.
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns if the object which this condition resides should be visible to connection.
|
||||
/// </summary>
|
||||
/// <param name="connection">Connection which the condition is being checked for.</param>
|
||||
/// <param name="currentlyAdded">True if the connection currently has visibility of this object.</param>
|
||||
/// <param name="notProcessed">True if the condition was not processed. This can be used to skip processing for performance. While output as true this condition result assumes the previous ConditionMet value.</param>
|
||||
public override bool ConditionMet(NetworkConnection connection, bool currentlyAdded, out bool notProcessed)
|
||||
{
|
||||
notProcessed = false;
|
||||
|
||||
// When true is returned it means the connection meets
|
||||
// the condition requirements. When false, the
|
||||
// connection does not and will not see the object.
|
||||
|
||||
// Will return true if connection Id matches _id.
|
||||
return (connection.ClientId == _id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Type of condition this is. Certain types are handled different, such as Timed which are checked for changes at timed intervals.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/* Since clientId does not change a normal condition type will work.
|
||||
* See API on ObserverConditionType for more information on what each
|
||||
* type does. */
|
||||
public override ObserverConditionType GetConditionType() => ObserverConditionType.Normal;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
You can get an idea of the flexibility of a condition by exploring the source of other premade conditions.
|
||||
@@ -0,0 +1,23 @@
|
||||
# Modifying Conditions
|
||||
|
||||
Several conditions may be modified at run-time. What can be modified for each condition may vary. I encourage you to view the [API](https://fish-networking.com/FishNet/api/api/FishNet.Component.Observing.html) to see what each condition exposes.
|
||||
|
||||
To change properties on a condition you must access the condition through the [NetworkObserver](../../../fishnet-building-blocks/components/network-observer.md) component.
|
||||
|
||||
```csharp
|
||||
// Below is an example of modifying the distance requirement
|
||||
// on a DistanceCondition. This line of code can be called from
|
||||
// any NetworkBehaviour. You may also use nbReference.NetworkObserver...
|
||||
base.NetworkObserver.GetObserverCondition<DistanceCondition>().MaximumDistance = 10f;
|
||||
```
|
||||
|
||||
All conditions can be enabled or disabled. When a condition is disabled it's requirements are ignored, as if the condition does not exist. This can be useful for temporarily disabling condition requirements on objects.
|
||||
|
||||
```csharp
|
||||
// The OwnerOnlyCondition is returned and disabled.
|
||||
// This allows all players to see the object, rather than just the owner.
|
||||
ObserverCondition c = base.NetworkObject.NetworkObserver.GetObserverCondition<OwnerOnlyCondition>();
|
||||
c.SetIsEnabled(false);
|
||||
// Even though we are returning ObserverCondition type, it could be casted to
|
||||
// OwnerOnlyCondition.
|
||||
```
|
||||
Reference in New Issue
Block a user