Class ObserverBudgetCondition
Caps how many CHARACTERS one client observes at a time, keeping the most relevant.
[CreateAssetMenu(menuName = "FishMMO/Observers/Observer Budget Condition", fileName = "ObserverBudgetCondition")]
public class ObserverBudgetCondition : ObserverCondition, IOrderable
- Inheritance
-
ObjectScriptableObjectObserverConditionObserverBudgetCondition
- Implements
-
IOrderable
- Inherited Members
-
ObserverCondition.NetworkObjectObserverCondition.OrderObserverCondition.IsConstantObserverCondition.GetIsEnabled()ObserverCondition.Initialize(NetworkObject)ScriptableObject.SetDirty()ScriptableObject.CreateInstance<T>()Object.GetEntityId()Object.GetInstanceID()Object.GetHashCode()Object.InstantiateAsync<T>(T)Object.InstantiateAsync<T>(T, Transform)Object.InstantiateAsync<T>(T, Vector3, Quaternion)Object.InstantiateAsync<T>(T, Transform, Vector3, Quaternion)Object.Instantiate(Object, Vector3, Quaternion)Object.Instantiate(Object, Vector3, Quaternion, Transform)Object.Instantiate(Object)Object.Instantiate(Object, Scene)Object.Instantiate<T>(T, InstantiateParameters)Object.Instantiate<T>(T, Vector3, Quaternion, InstantiateParameters)Object.Instantiate(Object, Transform)Object.Instantiate<T>(T)Object.Instantiate<T>(T, Vector3, Quaternion)Object.Instantiate<T>(T, Vector3, Quaternion, Transform)Object.Instantiate<T>(T, Transform)Object.Destroy(Object)Object.DestroyImmediate(Object)Object.DontDestroyOnLoad(Object)Object.DestroyObject(Object)Object.FindObjectsOfType<T>()Object.FindObjectsByType<T>(FindObjectsSortMode)Object.FindObjectsByType<T>(FindObjectsInactive, FindObjectsSortMode)Object.FindObjectOfType<T>()Object.FindFirstObjectByType<T>()Object.FindAnyObjectByType<T>()Object.FindFirstObjectByType<T>(FindObjectsInactive)Object.FindAnyObjectByType<T>(FindObjectsInactive)Object.FindObjectsByType<T>()Object.FindObjectsByType<T>(FindObjectsInactive)Object.ToString()Object.nameObject.hideFlags
Remarks
Distance alone does not bound a client's cost: a hundred players can stand inside any radius
you pick. This is the bound. ObserverStreamingRegistry already ranks every
character a viewer could see by relevance — combat, party, guild, distance — and this
condition simply admits the top ObserverStreamingPolicy.VisibilityBudget of them.
It gates existence, not fidelity. A character outside the budget is not merely slowed down; it is despawned on that client, taking its audio, nameplate, buffs and every broadcast with it. That is why it must be the LAST condition — everything cheaper should have rejected first — and why it is rank-hysteretic: two characters of near-identical score either side of the boundary would otherwise spawn and despawn each other every pass, which costs far more than any rate change and reads as flicker.
It only budgets registered characters. Anything else — interactables, world items, scene objects, a character whose entry has not been created yet — is admitted untouched, so this is safe to install as a default condition on every object. Their absence would be far more confusing than a missing distant stranger, and they are cheap.
Party members within the ability ceiling and the viewer's current target are pinned by the registry and can never be evicted, however dense the crowd gets.
Methods
ConditionMet(NetworkConnection, bool, out bool)
Whether connection may observe this object under its visibility budget.
public override bool ConditionMet(NetworkConnection connection, bool currentlyAdded, out bool notProcessed)
Parameters
connectionNetworkConnectionThe connection being tested.
currentlyAddedboolTrue when the connection already observes this object.
notProcessedboolTrue when this condition could not decide, which tells FishNet to keep the previous result. Used while a viewer has no ranking yet: the alternative — answering "false" — would hide the world from every client that connects between two scheduler passes.
Returns
- bool
True when the object is inside the budget.
GetConditionType()
Timed: the ranking changes as characters move and fight, so this has to be re-evaluated on the observer sweep rather than only when something structural happens.
public override ObserverConditionType GetConditionType()
Returns
- ObserverConditionType