NetworkBehaviourInspector.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. using System;
  2. using System.Reflection;
  3. using UnityEditor;
  4. using UnityEngine;
  5. namespace Mirror
  6. {
  7. [CustomEditor(typeof(NetworkBehaviour), true)]
  8. [CanEditMultipleObjects]
  9. public class NetworkBehaviourInspector : Editor
  10. {
  11. bool syncsAnything;
  12. SyncObjectCollectionsDrawer syncObjectCollectionsDrawer;
  13. // does this type sync anything? otherwise we don't need to show syncInterval
  14. bool SyncsAnything(Type scriptClass)
  15. {
  16. // check for all SyncVar fields, they don't have to be visible
  17. foreach (FieldInfo field in InspectorHelper.GetAllFields(scriptClass, typeof(NetworkBehaviour)))
  18. {
  19. if (field.IsSyncVar())
  20. {
  21. return true;
  22. }
  23. }
  24. // has OnSerialize that is not in NetworkBehaviour?
  25. // then it either has a syncvar or custom OnSerialize. either way
  26. // this means we have something to sync.
  27. MethodInfo method = scriptClass.GetMethod("OnSerialize");
  28. if (method != null && method.DeclaringType != typeof(NetworkBehaviour))
  29. {
  30. return true;
  31. }
  32. // SyncObjects are serialized in NetworkBehaviour.OnSerialize, which
  33. // is always there even if we don't use SyncObjects. so we need to
  34. // search for SyncObjects manually.
  35. // Any SyncObject should be added to syncObjects when unity creates an
  36. // object so we can check length of list so see if sync objects exists
  37. return ((NetworkBehaviour)serializedObject.targetObject).HasSyncObjects();
  38. }
  39. void OnEnable()
  40. {
  41. if (target == null) { Debug.LogWarning("NetworkBehaviourInspector had no target object"); return; }
  42. // If target's base class is changed from NetworkBehaviour to MonoBehaviour
  43. // then Unity temporarily keep using this Inspector causing things to break
  44. if (!(target is NetworkBehaviour)) { return; }
  45. Type scriptClass = target.GetType();
  46. syncObjectCollectionsDrawer = new SyncObjectCollectionsDrawer(serializedObject.targetObject);
  47. syncsAnything = SyncsAnything(scriptClass);
  48. }
  49. public override void OnInspectorGUI()
  50. {
  51. DrawDefaultInspector();
  52. DrawSyncObjectCollections();
  53. DrawDefaultSyncSettings();
  54. }
  55. // Draws Sync Objects that are IEnumerable
  56. protected void DrawSyncObjectCollections()
  57. {
  58. // Need this check in case OnEnable returns early
  59. if (syncObjectCollectionsDrawer == null) return;
  60. syncObjectCollectionsDrawer.Draw();
  61. }
  62. // Draws SyncSettings if the NetworkBehaviour has anything to sync
  63. protected void DrawDefaultSyncSettings()
  64. {
  65. // does it sync anything? then show extra properties
  66. // (no need to show it if the class only has Cmds/Rpcs and no sync)
  67. if (!syncsAnything)
  68. {
  69. return;
  70. }
  71. EditorGUILayout.Space();
  72. EditorGUILayout.LabelField("Sync Settings", EditorStyles.boldLabel);
  73. // sync direction
  74. SerializedProperty syncDirection = serializedObject.FindProperty("syncDirection");
  75. EditorGUILayout.PropertyField(syncDirection);
  76. // sync mdoe: only show for ServerToClient components
  77. if (syncDirection.enumValueIndex == (int)SyncDirection.ServerToClient)
  78. EditorGUILayout.PropertyField(serializedObject.FindProperty("syncMode"));
  79. // sync interval
  80. EditorGUILayout.PropertyField(serializedObject.FindProperty("syncInterval"));
  81. // apply
  82. serializedObject.ApplyModifiedProperties();
  83. }
  84. }
  85. }