-
-
Notifications
You must be signed in to change notification settings - Fork 748
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Team Interest Management (#2979)
* feat: Team Interest Management * meta file * Added forceShown * Code Smells * code smell * simplified
- Loading branch information
1 parent
cf76d03
commit 1a43b79
Showing
5 changed files
with
226 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
18 changes: 18 additions & 0 deletions
18
Assets/Mirror/Components/InterestManagement/Team/NetworkTeam.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// simple component that holds team information | ||
using System; | ||
using UnityEngine; | ||
|
||
namespace Mirror | ||
{ | ||
[DisallowMultipleComponent] | ||
[AddComponentMenu("Network/NetworkTeam")] | ||
[HelpURL("https://mirror-networking.gitbook.io/docs/guides/interest-management")] | ||
public class NetworkTeam : NetworkBehaviour | ||
{ | ||
[Tooltip("Set this to the same value on all networked objects that belong to a given team")] | ||
public string teamId = string.Empty; | ||
|
||
[Tooltip("When enabled this object is visible to all clients. Typically this would be true for player objects")] | ||
public bool forceShown; | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
Assets/Mirror/Components/InterestManagement/Team/NetworkTeam.cs.meta
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
178 changes: 178 additions & 0 deletions
178
Assets/Mirror/Components/InterestManagement/Team/TeamInterestManagement.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
|
||
namespace Mirror | ||
{ | ||
public class TeamInterestManagement : InterestManagement | ||
{ | ||
readonly Dictionary<string, HashSet<NetworkIdentity>> teamObjects = | ||
new Dictionary<string, HashSet<NetworkIdentity>>(); | ||
|
||
readonly Dictionary<NetworkIdentity, string> lastObjectTeam = | ||
new Dictionary<NetworkIdentity, string>(); | ||
|
||
readonly HashSet<string> dirtyTeams = new HashSet<string>(); | ||
|
||
public override void OnSpawned(NetworkIdentity identity) | ||
{ | ||
if (!identity.TryGetComponent<NetworkTeam>(out NetworkTeam networkTeam)) | ||
return; | ||
|
||
string currentTeam = networkTeam.teamId; | ||
lastObjectTeam[identity] = currentTeam; | ||
|
||
// string.Empty is never a valid teamId...do not add to teamObjects collection | ||
if (currentTeam == string.Empty) | ||
return; | ||
|
||
if (!teamObjects.TryGetValue(currentTeam, out HashSet<NetworkIdentity> objects)) | ||
{ | ||
objects = new HashSet<NetworkIdentity>(); | ||
teamObjects.Add(currentTeam, objects); | ||
} | ||
|
||
objects.Add(identity); | ||
} | ||
|
||
public override void OnDestroyed(NetworkIdentity identity) | ||
{ | ||
// Do nothing if server has shut down (or not started) | ||
if (!NetworkServer.active) return; | ||
|
||
lastObjectTeam.TryGetValue(identity, out string currentTeam); | ||
lastObjectTeam.Remove(identity); | ||
if (currentTeam != string.Empty && teamObjects.TryGetValue(currentTeam, out HashSet<NetworkIdentity> objects) && objects.Remove(identity)) | ||
RebuildTeamObservers(currentTeam); | ||
} | ||
|
||
[ServerCallback] | ||
void Update() | ||
{ | ||
// for each spawned: | ||
// if team changed: | ||
// add previous to dirty | ||
// add new to dirty | ||
foreach (NetworkIdentity netIdentity in NetworkServer.spawned.Values) | ||
{ | ||
// Ignore objects that don't have a NetworkTeam component | ||
if (!netIdentity.TryGetComponent<NetworkTeam>(out NetworkTeam networkTeam)) | ||
continue; | ||
|
||
string newTeam = networkTeam.teamId; | ||
lastObjectTeam.TryGetValue(netIdentity, out string currentTeam); | ||
|
||
// string.Empty is never a valid teamId | ||
// Nothing to do if teamId hasn't changed | ||
if (newTeam == string.Empty || newTeam == currentTeam) | ||
continue; | ||
|
||
// Mark new/old Teams as dirty so they get rebuilt | ||
UpdateDirtyTeams(newTeam, currentTeam); | ||
|
||
// This object is in a new team so observers in the prior team | ||
// and the new team need to rebuild their respective observers lists. | ||
UpdateTeamObjects(netIdentity, newTeam, currentTeam); | ||
} | ||
|
||
// rebuild all dirty teams | ||
foreach (string dirtyTeam in dirtyTeams) | ||
RebuildTeamObservers(dirtyTeam); | ||
|
||
dirtyTeams.Clear(); | ||
} | ||
|
||
void UpdateDirtyTeams(string newTeam, string currentTeam) | ||
{ | ||
// string.Empty is never a valid teamId | ||
if (currentTeam != string.Empty) | ||
dirtyTeams.Add(currentTeam); | ||
|
||
dirtyTeams.Add(newTeam); | ||
} | ||
|
||
void UpdateTeamObjects(NetworkIdentity netIdentity, string newTeam, string currentTeam) | ||
{ | ||
// Remove this object from the hashset of the team it just left | ||
// string.Empty is never a valid teamId | ||
if (currentTeam != string.Empty) | ||
teamObjects[currentTeam].Remove(netIdentity); | ||
|
||
// Set this to the new team this object just entered | ||
lastObjectTeam[netIdentity] = newTeam; | ||
|
||
// Make sure this new team is in the dictionary | ||
if (!teamObjects.ContainsKey(newTeam)) | ||
teamObjects.Add(newTeam, new HashSet<NetworkIdentity>()); | ||
|
||
// Add this object to the hashset of the new team | ||
teamObjects[newTeam].Add(netIdentity); | ||
} | ||
|
||
void RebuildTeamObservers(string teamId) | ||
{ | ||
foreach (NetworkIdentity netIdentity in teamObjects[teamId]) | ||
if (netIdentity != null) | ||
NetworkServer.RebuildObservers(netIdentity, false); | ||
} | ||
|
||
public override bool OnCheckObserver(NetworkIdentity identity, NetworkConnection newObserver) | ||
{ | ||
// Do nothing if server has shut down (or not started) | ||
if (!NetworkServer.active) return false; | ||
|
||
// Always observed if no NetworkTeam component | ||
if (!identity.TryGetComponent<NetworkTeam>(out NetworkTeam identityNetworkTeam)) | ||
return true; | ||
|
||
// Always observed if no NetworkTeam component | ||
if (!newObserver.identity.TryGetComponent<NetworkTeam>(out NetworkTeam newObserverNetworkTeam)) | ||
return true; | ||
|
||
// Observed only if teamId's match | ||
return identityNetworkTeam.forceShown || identityNetworkTeam.teamId == newObserverNetworkTeam.teamId; | ||
} | ||
|
||
public override void OnRebuildObservers(NetworkIdentity identity, HashSet<NetworkConnection> newObservers, bool initialize) | ||
{ | ||
// Do nothing if server has shut down (or not started) | ||
if (!NetworkServer.active) return; | ||
|
||
// If this object doesn't have a NetworkTeam then it's visible to all clients | ||
if (!identity.TryGetComponent<NetworkTeam>(out NetworkTeam networkTeam)) | ||
{ | ||
AddAllConnections(newObservers); | ||
return; | ||
} | ||
|
||
// If this object has NetworkTeam and forceShown == true then it's visible to all clients | ||
if (networkTeam.forceShown) | ||
{ | ||
AddAllConnections(newObservers); | ||
return; | ||
} | ||
|
||
// string.Empty is never a valid teamId | ||
if (networkTeam.teamId == string.Empty) | ||
return; | ||
|
||
// Abort if this team hasn't been created yet by OnSpawned or UpdateTeamObjects | ||
if (!teamObjects.TryGetValue(networkTeam.teamId, out HashSet<NetworkIdentity> objects)) | ||
return; | ||
|
||
// Add everything in the hashset for this object's current team | ||
foreach (NetworkIdentity networkIdentity in objects) | ||
if (networkIdentity != null && networkIdentity.connectionToClient != null) | ||
newObservers.Add(networkIdentity.connectionToClient); | ||
} | ||
|
||
void AddAllConnections(HashSet<NetworkConnection> newObservers) | ||
{ | ||
foreach (NetworkConnectionToClient conn in NetworkServer.connections.Values) | ||
{ | ||
// authenticated and joined world with a player? | ||
if (conn != null && conn.isAuthenticated && conn.identity != null) | ||
newObservers.Add(conn); | ||
} | ||
} | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
Assets/Mirror/Components/InterestManagement/Team/TeamInterestManagement.cs.meta
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.