using System.Collections.Generic;
using Fusion.Analyzer;
using UnityEngine;
namespace Fusion {
#if UNITY_EDITOR
using UnityEditor;
#endif
///
/// Automatically adds a for each indicated component.
/// These indicated components will be limited to no more than one enabled instance when running in Multi-Peer mode.
///
[AddComponentMenu("Fusion/Enable On Single Runner")]
public class EnableOnSingleRunner : Fusion.Behaviour {
///
/// If more than one runner instance is visible, this indicates which peer's clone of this entity should be visible.
///
[InlineHelp]
[SerializeField]
#pragma warning disable IDE0044 // Add readonly modifier
public RunnerVisibilityLink.PreferredRunners PreferredRunner;
#pragma warning restore IDE0044 // Add readonly modifier
///
/// Collection of components that will be marked for Multi-Peer mode as objects that should only have one enabled instance.
///
[InlineHelp]
public UnityEngine.Component[] Components = new Component[0];
///
/// Prefix for the GUIDs of components which are added at runtime.
///
[HideInInspector]
[SerializeField]
private string _guid = System.Guid.NewGuid().ToString().Substring(0, 19);
///
/// At runtime startup, this adds a for each component reference to this GameObject.
///
internal void AddNodes(List existingNodes) {
for(int i = 0; i < Components.Length; ++i) {
var found = false;
foreach (var existingNode in existingNodes) {
if (existingNode.Component == Components[i]) {
found = true;
break;
}
}
if (found) continue;
var node = Components[i].gameObject.AddComponent();
node.Guid = _guid + i;
node.Component = Components[i];
node.SetupOnSingleRunnerLink(PreferredRunner);
existingNodes.Add(node);
}
}
///
/// Finds visual/audio components on this GameObject, and adds them to the Components collection.
///
[EditorButton("Find on GameObject", EditorButtonVisibility.EditMode, dirtyObject: true)]
public void FindRecognizedTypes() {
Components = FindRecognizedComponentsOnGameObject(gameObject);
}
///
/// Finds visual/audio nested components on this GameObject and its children, and adds them to the Components collection.
///
[EditorButton("Find in Nested Children", EditorButtonVisibility.EditMode, dirtyObject: true)]
public void FindNestedRecognizedTypes() {
Components = FindRecognizedNestedComponents(gameObject);
}
[StaticField(StaticFieldResetMode.None)]
private static readonly List reusableComponentsList = new List();
[StaticField(StaticFieldResetMode.None)]
private static readonly List reusableComponentsList2 = new List();
private static Component[] FindRecognizedComponentsOnGameObject(GameObject go) {
try {
go.GetComponents(reusableComponentsList);
reusableComponentsList2.Clear();
foreach (var comp in reusableComponentsList) {
var type = comp.GetType();
if (type.IsRecognizedByRunnerVisibility()) {
reusableComponentsList2.Add(comp);
}
}
return reusableComponentsList2.ToArray();
} finally {
reusableComponentsList.Clear();
reusableComponentsList2.Clear();
}
}
private static Component[] FindRecognizedNestedComponents(GameObject go) {
try {
go.transform.GetNestedComponentsInChildren(reusableComponentsList, true);
reusableComponentsList2.Clear();
foreach (var comp in reusableComponentsList) {
var type = comp.GetType();
if (type.IsRecognizedByRunnerVisibility()) {
reusableComponentsList2.Add(comp);
}
}
return reusableComponentsList2.ToArray();
} finally {
reusableComponentsList.Clear();
reusableComponentsList2.Clear();
}
}
}
}