slowpoker/Assets/Mirror/Editor/NetworkBehaviourInspector.cs
2024-10-17 17:23:05 +03:00

105 lines
3.8 KiB
C#

using System;
using System.Reflection;
using UnityEditor;
using UnityEngine;
namespace Mirror
{
[CustomEditor(typeof(NetworkBehaviour), true)]
[CanEditMultipleObjects]
public class NetworkBehaviourInspector : Editor
{
bool syncsAnything;
SyncObjectCollectionsDrawer syncObjectCollectionsDrawer;
// does this type sync anything? otherwise we don't need to show syncInterval
bool SyncsAnything(Type scriptClass)
{
// check for all SyncVar fields, they don't have to be visible
foreach (FieldInfo field in InspectorHelper.GetAllFields(scriptClass, typeof(NetworkBehaviour)))
{
if (field.IsSyncVar())
{
return true;
}
}
// has OnSerialize that is not in NetworkBehaviour?
// then it either has a syncvar or custom OnSerialize. either way
// this means we have something to sync.
MethodInfo method = scriptClass.GetMethod("OnSerialize");
if (method != null && method.DeclaringType != typeof(NetworkBehaviour))
{
return true;
}
// SyncObjects are serialized in NetworkBehaviour.OnSerialize, which
// is always there even if we don't use SyncObjects. so we need to
// search for SyncObjects manually.
// Any SyncObject should be added to syncObjects when unity creates an
// object so we can check length of list so see if sync objects exists
return ((NetworkBehaviour)serializedObject.targetObject).HasSyncObjects();
}
void OnEnable()
{
// sometimes target is null. just return early.
if (target == null) return;
// If target's base class is changed from NetworkBehaviour to MonoBehaviour
// then Unity temporarily keep using this Inspector causing things to break
if (!(target is NetworkBehaviour)) { return; }
Type scriptClass = target.GetType();
syncObjectCollectionsDrawer = new SyncObjectCollectionsDrawer(serializedObject.targetObject);
syncsAnything = SyncsAnything(scriptClass);
}
public override void OnInspectorGUI()
{
DrawDefaultInspector();
DrawSyncObjectCollections();
DrawDefaultSyncSettings();
}
// Draws Sync Objects that are IEnumerable
protected void DrawSyncObjectCollections()
{
// Need this check in case OnEnable returns early
if (syncObjectCollectionsDrawer == null) return;
syncObjectCollectionsDrawer.Draw();
}
// Draws SyncSettings if the NetworkBehaviour has anything to sync
protected void DrawDefaultSyncSettings()
{
// does it sync anything? then show extra properties
// (no need to show it if the class only has Cmds/Rpcs and no sync)
if (!syncsAnything)
{
return;
}
EditorGUILayout.Space();
EditorGUILayout.LabelField("Sync Settings", EditorStyles.boldLabel);
// sync direction
SerializedProperty syncDirection = serializedObject.FindProperty("syncDirection");
EditorGUILayout.PropertyField(syncDirection);
// sync mdoe: only show for ServerToClient components
if (syncDirection.enumValueIndex == (int)SyncDirection.ServerToClient)
EditorGUILayout.PropertyField(serializedObject.FindProperty("syncMode"));
// sync interval
EditorGUILayout.PropertyField(serializedObject.FindProperty("syncInterval"));
// apply
serializedObject.ApplyModifiedProperties();
}
}
}