NetworkInformationPreview.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. using System.Collections.Generic;
  2. using UnityEditor;
  3. using UnityEngine;
  4. namespace Mirror
  5. {
  6. [CustomPreview(typeof(GameObject))]
  7. class NetworkInformationPreview : ObjectPreview
  8. {
  9. struct NetworkIdentityInfo
  10. {
  11. public GUIContent name;
  12. public GUIContent value;
  13. }
  14. struct NetworkBehaviourInfo
  15. {
  16. // This is here just so we can check if it's enabled/disabled
  17. public NetworkBehaviour behaviour;
  18. public GUIContent name;
  19. }
  20. class Styles
  21. {
  22. public GUIStyle labelStyle = new GUIStyle(EditorStyles.label);
  23. public GUIStyle componentName = new GUIStyle(EditorStyles.boldLabel);
  24. public GUIStyle disabledName = new GUIStyle(EditorStyles.miniLabel);
  25. public Styles()
  26. {
  27. Color fontColor = new Color(0.7f, 0.7f, 0.7f);
  28. labelStyle.padding.right += 20;
  29. labelStyle.normal.textColor = fontColor;
  30. labelStyle.active.textColor = fontColor;
  31. labelStyle.focused.textColor = fontColor;
  32. labelStyle.hover.textColor = fontColor;
  33. labelStyle.onNormal.textColor = fontColor;
  34. labelStyle.onActive.textColor = fontColor;
  35. labelStyle.onFocused.textColor = fontColor;
  36. labelStyle.onHover.textColor = fontColor;
  37. componentName.normal.textColor = fontColor;
  38. componentName.active.textColor = fontColor;
  39. componentName.focused.textColor = fontColor;
  40. componentName.hover.textColor = fontColor;
  41. componentName.onNormal.textColor = fontColor;
  42. componentName.onActive.textColor = fontColor;
  43. componentName.onFocused.textColor = fontColor;
  44. componentName.onHover.textColor = fontColor;
  45. disabledName.normal.textColor = fontColor;
  46. disabledName.active.textColor = fontColor;
  47. disabledName.focused.textColor = fontColor;
  48. disabledName.hover.textColor = fontColor;
  49. disabledName.onNormal.textColor = fontColor;
  50. disabledName.onActive.textColor = fontColor;
  51. disabledName.onFocused.textColor = fontColor;
  52. disabledName.onHover.textColor = fontColor;
  53. }
  54. }
  55. GUIContent title;
  56. Styles styles = new Styles();
  57. public override GUIContent GetPreviewTitle()
  58. {
  59. if (title == null)
  60. {
  61. title = new GUIContent("Network Information");
  62. }
  63. return title;
  64. }
  65. public override bool HasPreviewGUI()
  66. {
  67. // need to check if target is null to stop MissingReferenceException
  68. return target != null && target is GameObject gameObject && gameObject.GetComponent<NetworkIdentity>() != null;
  69. }
  70. public override void OnPreviewGUI(Rect r, GUIStyle background)
  71. {
  72. if (Event.current.type != EventType.Repaint)
  73. return;
  74. if (target == null)
  75. return;
  76. GameObject targetGameObject = target as GameObject;
  77. if (targetGameObject == null)
  78. return;
  79. NetworkIdentity identity = targetGameObject.GetComponent<NetworkIdentity>();
  80. if (identity == null)
  81. return;
  82. if (styles == null)
  83. styles = new Styles();
  84. // padding
  85. RectOffset previewPadding = new RectOffset(-5, -5, -5, -5);
  86. Rect paddedr = previewPadding.Add(r);
  87. //Centering
  88. float initialX = paddedr.x + 10;
  89. float Y = paddedr.y + 10;
  90. Y = DrawNetworkIdentityInfo(identity, initialX, Y);
  91. Y = DrawNetworkBehaviors(identity, initialX, Y);
  92. Y = DrawObservers(identity, initialX, Y);
  93. _ = DrawOwner(identity, initialX, Y);
  94. }
  95. float DrawNetworkIdentityInfo(NetworkIdentity identity, float initialX, float Y)
  96. {
  97. IEnumerable<NetworkIdentityInfo> infos = GetNetworkIdentityInfo(identity);
  98. // Get required label size for the names of the information values we're going to show
  99. // There are two columns, one with label for the name of the info and the next for the value
  100. Vector2 maxNameLabelSize = new Vector2(140, 16);
  101. Vector2 maxValueLabelSize = GetMaxNameLabelSize(infos);
  102. Rect labelRect = new Rect(initialX, Y, maxNameLabelSize.x, maxNameLabelSize.y);
  103. Rect idLabelRect = new Rect(maxNameLabelSize.x, Y, maxValueLabelSize.x, maxValueLabelSize.y);
  104. foreach (NetworkIdentityInfo info in infos)
  105. {
  106. GUI.Label(labelRect, info.name, styles.labelStyle);
  107. GUI.Label(idLabelRect, info.value, styles.componentName);
  108. labelRect.y += labelRect.height;
  109. labelRect.x = initialX;
  110. idLabelRect.y += idLabelRect.height;
  111. }
  112. return labelRect.y;
  113. }
  114. float DrawNetworkBehaviors(NetworkIdentity identity, float initialX, float Y)
  115. {
  116. IEnumerable<NetworkBehaviourInfo> behavioursInfo = GetNetworkBehaviorInfo(identity);
  117. // Show behaviours list in a different way than the name/value pairs above
  118. Vector2 maxBehaviourLabelSize = GetMaxBehaviourLabelSize(behavioursInfo);
  119. Rect behaviourRect = new Rect(initialX, Y + 10, maxBehaviourLabelSize.x, maxBehaviourLabelSize.y);
  120. GUI.Label(behaviourRect, new GUIContent("Network Behaviours"), styles.labelStyle);
  121. // indent names
  122. behaviourRect.x += 20;
  123. behaviourRect.y += behaviourRect.height;
  124. foreach (NetworkBehaviourInfo info in behavioursInfo)
  125. {
  126. if (info.behaviour == null)
  127. {
  128. // could be the case in the editor after existing play mode.
  129. continue;
  130. }
  131. GUI.Label(behaviourRect, info.name, info.behaviour.enabled ? styles.componentName : styles.disabledName);
  132. behaviourRect.y += behaviourRect.height;
  133. Y = behaviourRect.y;
  134. }
  135. return Y;
  136. }
  137. float DrawObservers(NetworkIdentity identity, float initialX, float Y)
  138. {
  139. if (identity.observers != null && identity.observers.Count > 0)
  140. {
  141. Rect observerRect = new Rect(initialX, Y + 10, 200, 20);
  142. GUI.Label(observerRect, new GUIContent("Network observers"), styles.labelStyle);
  143. // indent names
  144. observerRect.x += 20;
  145. observerRect.y += observerRect.height;
  146. foreach (KeyValuePair<int, NetworkConnection> kvp in identity.observers)
  147. {
  148. GUI.Label(observerRect, kvp.Value.address + ":" + kvp.Value, styles.componentName);
  149. observerRect.y += observerRect.height;
  150. Y = observerRect.y;
  151. }
  152. }
  153. return Y;
  154. }
  155. float DrawOwner(NetworkIdentity identity, float initialX, float Y)
  156. {
  157. if (identity.connectionToClient != null)
  158. {
  159. Rect ownerRect = new Rect(initialX, Y + 10, 400, 20);
  160. GUI.Label(ownerRect, new GUIContent("Client Authority: " + identity.connectionToClient), styles.labelStyle);
  161. Y += ownerRect.height;
  162. }
  163. return Y;
  164. }
  165. // Get the maximum size used by the value of information items
  166. Vector2 GetMaxNameLabelSize(IEnumerable<NetworkIdentityInfo> infos)
  167. {
  168. Vector2 maxLabelSize = Vector2.zero;
  169. foreach (NetworkIdentityInfo info in infos)
  170. {
  171. Vector2 labelSize = styles.labelStyle.CalcSize(info.value);
  172. if (maxLabelSize.x < labelSize.x)
  173. {
  174. maxLabelSize.x = labelSize.x;
  175. }
  176. if (maxLabelSize.y < labelSize.y)
  177. {
  178. maxLabelSize.y = labelSize.y;
  179. }
  180. }
  181. return maxLabelSize;
  182. }
  183. Vector2 GetMaxBehaviourLabelSize(IEnumerable<NetworkBehaviourInfo> behavioursInfo)
  184. {
  185. Vector2 maxLabelSize = Vector2.zero;
  186. foreach (NetworkBehaviourInfo behaviour in behavioursInfo)
  187. {
  188. Vector2 labelSize = styles.labelStyle.CalcSize(behaviour.name);
  189. if (maxLabelSize.x < labelSize.x)
  190. {
  191. maxLabelSize.x = labelSize.x;
  192. }
  193. if (maxLabelSize.y < labelSize.y)
  194. {
  195. maxLabelSize.y = labelSize.y;
  196. }
  197. }
  198. return maxLabelSize;
  199. }
  200. IEnumerable<NetworkIdentityInfo> GetNetworkIdentityInfo(NetworkIdentity identity)
  201. {
  202. List<NetworkIdentityInfo> infos = new List<NetworkIdentityInfo>
  203. {
  204. GetAssetId(identity),
  205. GetString("Scene ID", identity.sceneId.ToString("X"))
  206. };
  207. if (Application.isPlaying)
  208. {
  209. infos.Add(GetString("Network ID", identity.netId.ToString()));
  210. infos.Add(GetBoolean("Is Client", identity.isClient));
  211. infos.Add(GetBoolean("Is Server", identity.isServer));
  212. infos.Add(GetBoolean("Has Authority", identity.hasAuthority));
  213. infos.Add(GetBoolean("Is Local Player", identity.isLocalPlayer));
  214. }
  215. return infos;
  216. }
  217. IEnumerable<NetworkBehaviourInfo> GetNetworkBehaviorInfo(NetworkIdentity identity)
  218. {
  219. List<NetworkBehaviourInfo> behaviourInfos = new List<NetworkBehaviourInfo>();
  220. NetworkBehaviour[] behaviours = identity.GetComponents<NetworkBehaviour>();
  221. foreach (NetworkBehaviour behaviour in behaviours)
  222. {
  223. behaviourInfos.Add(new NetworkBehaviourInfo
  224. {
  225. name = new GUIContent(behaviour.GetType().FullName),
  226. behaviour = behaviour
  227. });
  228. }
  229. return behaviourInfos;
  230. }
  231. NetworkIdentityInfo GetAssetId(NetworkIdentity identity)
  232. {
  233. string assetId = identity.assetId.ToString();
  234. if (string.IsNullOrEmpty(assetId))
  235. {
  236. assetId = "<object has no prefab>";
  237. }
  238. return GetString("Asset ID", assetId);
  239. }
  240. static NetworkIdentityInfo GetString(string name, string value)
  241. {
  242. return new NetworkIdentityInfo
  243. {
  244. name = new GUIContent(name),
  245. value = new GUIContent(value)
  246. };
  247. }
  248. static NetworkIdentityInfo GetBoolean(string name, bool value)
  249. {
  250. return new NetworkIdentityInfo
  251. {
  252. name = new GUIContent(name),
  253. value = new GUIContent((value ? "Yes" : "No"))
  254. };
  255. }
  256. }
  257. }