diff --git a/Assets/Scenes/main.unity b/Assets/Scenes/main.unity
index f10b5f10..e748a221 100644
--- a/Assets/Scenes/main.unity
+++ b/Assets/Scenes/main.unity
@@ -449,7 +449,7 @@ Transform:
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 2061060682}
- m_RootOrder: 9
+ m_RootOrder: 10
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &291980959
MonoBehaviour:
@@ -593,7 +593,7 @@ Transform:
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 2061060682}
- m_RootOrder: 7
+ m_RootOrder: 8
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1176880019
MonoBehaviour:
@@ -681,7 +681,7 @@ Transform:
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 2061060682}
- m_RootOrder: 6
+ m_RootOrder: 7
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1538699882
MonoBehaviour:
@@ -869,7 +869,7 @@ Transform:
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 2061060682}
- m_RootOrder: 8
+ m_RootOrder: 9
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1947304786
MonoBehaviour:
@@ -996,7 +996,7 @@ Transform:
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 2061060682}
- m_RootOrder: 5
+ m_RootOrder: 6
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &2049602907
MonoBehaviour:
@@ -1052,6 +1052,7 @@ Transform:
- {fileID: 23410075}
- {fileID: 1599070679}
- {fileID: 1513514423}
+ - {fileID: 2088009247}
- {fileID: 2049602906}
- {fileID: 1538699881}
- {fileID: 1176880018}
@@ -1083,6 +1084,49 @@ MonoBehaviour:
m_GameSpeed: 1
m_RunInBackground: 1
m_NeverSleep: 1
+--- !u!1 &2088009246
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 2088009247}
+ - component: {fileID: 2088009248}
+ m_Layer: 0
+ m_Name: Network
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &2088009247
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2088009246}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_Children: []
+ m_Father: {fileID: 2061060682}
+ m_RootOrder: 5
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &2088009248
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2088009246}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 8edbc7d090fd4bb1ad2c6aa967ff0b76, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
--- !u!1 &2108959335
GameObject:
m_ObjectHideFlags: 0
@@ -1112,7 +1156,7 @@ Transform:
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 2061060682}
- m_RootOrder: 10
+ m_RootOrder: 11
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &2108959337
MonoBehaviour:
diff --git a/Assets/TEngine/Editor/Inspector/NetworkInspector.cs b/Assets/TEngine/Editor/Inspector/NetworkInspector.cs
new file mode 100644
index 00000000..bf680dbf
--- /dev/null
+++ b/Assets/TEngine/Editor/Inspector/NetworkInspector.cs
@@ -0,0 +1,62 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace TEngine.Editor.Inspector
+{
+ [CustomEditor(typeof(Network))]
+ internal sealed class NetworkInspector : GameFrameworkInspector
+ {
+ public override void OnInspectorGUI()
+ {
+ base.OnInspectorGUI();
+
+ if (!EditorApplication.isPlaying)
+ {
+ EditorGUILayout.HelpBox("Available during runtime only.", MessageType.Info);
+ return;
+ }
+
+ Network t = (Network)target;
+
+ if (IsPrefabInHierarchy(t.gameObject))
+ {
+ EditorGUILayout.LabelField("Network Channel Count", t.NetworkChannelCount.ToString());
+
+ INetworkChannel[] networkChannels = t.GetAllNetworkChannels();
+ foreach (INetworkChannel networkChannel in networkChannels)
+ {
+ DrawNetworkChannel(networkChannel);
+ }
+ }
+
+ Repaint();
+ }
+
+ private void DrawNetworkChannel(INetworkChannel networkChannel)
+ {
+ EditorGUILayout.BeginVertical("box");
+ {
+ EditorGUILayout.LabelField(networkChannel.Name, networkChannel.Connected ? "Connected" : "Disconnected");
+ EditorGUILayout.LabelField("Service Type", networkChannel.ServiceType.ToString());
+ EditorGUILayout.LabelField("Address Family", networkChannel.AddressFamily.ToString());
+ EditorGUILayout.LabelField("Local Address", networkChannel.Connected ? networkChannel.Socket.LocalEndPoint.ToString() : "Unavailable");
+ EditorGUILayout.LabelField("Remote Address", networkChannel.Connected ? networkChannel.Socket.RemoteEndPoint.ToString() : "Unavailable");
+ EditorGUILayout.LabelField("Send Packet", Utility.Text.Format("{0} / {1}", networkChannel.SendPacketCount, networkChannel.SentPacketCount));
+ EditorGUILayout.LabelField("Receive Packet", Utility.Text.Format("{0} / {1}", networkChannel.ReceivePacketCount, networkChannel.ReceivedPacketCount));
+ EditorGUILayout.LabelField("Miss Heart Beat Count", networkChannel.MissHeartBeatCount.ToString());
+ EditorGUILayout.LabelField("Heart Beat", Utility.Text.Format("{0:F2} / {1:F2}", networkChannel.HeartBeatElapseSeconds, networkChannel.HeartBeatInterval));
+ EditorGUI.BeginDisabledGroup(!networkChannel.Connected);
+ {
+ if (GUILayout.Button("Disconnect"))
+ {
+ networkChannel.Close();
+ }
+ }
+ EditorGUI.EndDisabledGroup();
+ }
+ EditorGUILayout.EndVertical();
+
+ EditorGUILayout.Separator();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/TEngine/Editor/Inspector/NetworkInspector.cs.meta b/Assets/TEngine/Editor/Inspector/NetworkInspector.cs.meta
new file mode 100644
index 00000000..24e390c1
--- /dev/null
+++ b/Assets/TEngine/Editor/Inspector/NetworkInspector.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 3301ba180cdc446bbdf823c860ae7a68
+timeCreated: 1682045195
\ No newline at end of file
diff --git a/Assets/TEngine/Runtime/GameFramework/Network/Network.cs b/Assets/TEngine/Runtime/GameFramework/Network/Network.cs
new file mode 100644
index 00000000..b2767580
--- /dev/null
+++ b/Assets/TEngine/Runtime/GameFramework/Network/Network.cs
@@ -0,0 +1,135 @@
+using System.Collections.Generic;
+using System.Net.Sockets;
+using UnityEngine;
+
+namespace TEngine
+{
+ ///
+ /// 网络组件。
+ ///
+ [DisallowMultipleComponent]
+ public sealed class Network : GameFrameworkModuleBase
+ {
+ private static INetworkManager m_NetworkManager = null;
+
+ ///
+ /// 获取网络频道数量。
+ ///
+ public int NetworkChannelCount => m_NetworkManager.NetworkChannelCount;
+
+ ///
+ /// 游戏框架组件初始化。
+ ///
+ protected override void Awake()
+ {
+ base.Awake();
+
+ m_NetworkManager = GameFrameworkEntry.GetModule();
+ if (m_NetworkManager == null)
+ {
+ Log.Fatal("Network manager is invalid.");
+ return;
+ }
+
+ m_NetworkManager.NetworkConnected += OnNetworkConnected;
+ m_NetworkManager.NetworkClosed += OnNetworkClosed;
+ m_NetworkManager.NetworkMissHeartBeat += OnNetworkMissHeartBeat;
+ m_NetworkManager.NetworkError += OnNetworkError;
+ m_NetworkManager.NetworkCustomError += OnNetworkCustomError;
+ }
+
+ ///
+ /// 检查是否存在网络频道。
+ ///
+ /// 网络频道名称。
+ /// 是否存在网络频道。
+ public static bool HasNetworkChannel(string name)
+ {
+ return m_NetworkManager.HasNetworkChannel(name);
+ }
+
+ ///
+ /// 获取网络频道。
+ ///
+ /// 网络频道名称。
+ /// 要获取的网络频道。
+ public static INetworkChannel GetNetworkChannel(string name)
+ {
+ return m_NetworkManager.GetNetworkChannel(name);
+ }
+
+ ///
+ /// 获取所有网络频道。
+ ///
+ /// 所有网络频道。
+ public static INetworkChannel[] StaticGetAllNetworkChannels()
+ {
+ return m_NetworkManager.GetAllNetworkChannels();
+ }
+
+ ///
+ /// 获取所有网络频道。
+ ///
+ /// 所有网络频道。
+ public INetworkChannel[] GetAllNetworkChannels()
+ {
+ return m_NetworkManager.GetAllNetworkChannels();
+ }
+
+ ///
+ /// 获取所有网络频道。
+ ///
+ /// 所有网络频道。
+ public static void GetAllNetworkChannels(List results)
+ {
+ m_NetworkManager.GetAllNetworkChannels(results);
+ }
+
+ ///
+ /// 创建网络频道。
+ ///
+ /// 网络频道名称。
+ /// 网络服务类型。
+ /// 网络频道辅助器。
+ /// 要创建的网络频道。
+ public static INetworkChannel CreateNetworkChannel(string name, ServiceType serviceType, INetworkChannelHelper networkChannelHelper)
+ {
+ return m_NetworkManager.CreateNetworkChannel(name, serviceType, networkChannelHelper);
+ }
+
+ ///
+ /// 销毁网络频道。
+ ///
+ /// 网络频道名称。
+ /// 是否销毁网络频道成功。
+ public static bool DestroyNetworkChannel(string channelName)
+ {
+ return m_NetworkManager.DestroyNetworkChannel(channelName);
+ }
+
+ private void OnNetworkConnected(INetworkChannel channel, object userdata)
+ {
+ GameEvent.Send(NetworkEvent.NetworkConnectedEvent, channel, userdata);
+ }
+
+ private void OnNetworkClosed(INetworkChannel channel)
+ {
+ GameEvent.Send(NetworkEvent.NetworkClosedEvent, channel);
+ }
+
+ private void OnNetworkMissHeartBeat(INetworkChannel channel, int missCount)
+ {
+ GameEvent.Send(NetworkEvent.NetworkMissHeartBeatEvent, channel, missCount);
+ }
+
+ private void OnNetworkError(INetworkChannel channel, NetworkErrorCode networkErrorCode, SocketError socketError, string errorMessage)
+ {
+ GameEvent.Send(NetworkEvent.NetworkErrorEvent, channel, networkErrorCode, socketError, errorMessage);
+ }
+
+ private void OnNetworkCustomError(INetworkChannel channel, object userData)
+ {
+ GameEvent.Send(NetworkEvent.NetworkCustomErrorEvent, channel, userData);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/TEngine/Runtime/GameFramework/Network/Network.cs.meta b/Assets/TEngine/Runtime/GameFramework/Network/Network.cs.meta
new file mode 100644
index 00000000..ec73e25c
--- /dev/null
+++ b/Assets/TEngine/Runtime/GameFramework/Network/Network.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 8edbc7d090fd4bb1ad2c6aa967ff0b76
+timeCreated: 1682044812
\ No newline at end of file