NetworkBehaviourInspector.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  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. // sometimes target is null. just return early.
  42. if (target == null) return;
  43. // If target's base class is changed from NetworkBehaviour to MonoBehaviour
  44. // then Unity temporarily keep using this Inspector causing things to break
  45. if (!(target is NetworkBehaviour)) { return; }
  46. Type scriptClass = target.GetType();
  47. syncObjectCollectionsDrawer = new SyncObjectCollectionsDrawer(serializedObject.targetObject);
  48. syncsAnything = SyncsAnything(scriptClass);
  49. }
  50. public override void OnInspectorGUI()
  51. {
  52. DrawDefaultInspector();
  53. DrawSyncObjectCollections();
  54. DrawDefaultSyncSettings();
  55. }
  56. // Draws Sync Objects that are IEnumerable
  57. protected void DrawSyncObjectCollections()
  58. {
  59. // Need this check in case OnEnable returns early
  60. if (syncObjectCollectionsDrawer == null) return;
  61. syncObjectCollectionsDrawer.Draw();
  62. }
  63. // Draws SyncSettings if the NetworkBehaviour has anything to sync
  64. protected void DrawDefaultSyncSettings()
  65. {
  66. // does it sync anything? then show extra properties
  67. // (no need to show it if the class only has Cmds/Rpcs and no sync)
  68. if (!syncsAnything)
  69. {
  70. return;
  71. }
  72. EditorGUILayout.Space();
  73. EditorGUILayout.LabelField("Sync Settings", EditorStyles.boldLabel);
  74. // sync direction
  75. SerializedProperty syncDirection = serializedObject.FindProperty("syncDirection");
  76. EditorGUILayout.PropertyField(syncDirection);
  77. // sync mdoe: only show for ServerToClient components
  78. if (syncDirection.enumValueIndex == (int)SyncDirection.ServerToClient)
  79. EditorGUILayout.PropertyField(serializedObject.FindProperty("syncMode"));
  80. // sync interval
  81. EditorGUILayout.PropertyField(serializedObject.FindProperty("syncInterval"));
  82. // apply
  83. serializedObject.ApplyModifiedProperties();
  84. }
  85. }
  86. }