lvjincheng 4 tahun lalu
induk
melakukan
949588bf8f

+ 6 - 0
Assets/BowArrow/Scripts/Game/BowCamera.cs

@@ -26,6 +26,8 @@ public class BowCamera : MonoBehaviour
     JC.Unity.TouchChecker touchChecker = new JC.Unity.TouchChecker();
     //触摸模式开关
     public static bool isTouchMode = true;
+    //禁止弓镜头被用户输入控制
+    [NonSerialized] public bool banUserControl = false;
     public static BowCamera ins;
 
     void Awake() {
@@ -35,6 +37,7 @@ public class BowCamera : MonoBehaviour
 
     void Start() {
         touchChecker.onMoved += delegate(Touch t, bool isOnUI) {
+            if (banUserControl) return;
             if (isOnUI) return;
             //触摸控制镜头和拉弓射箭
             this.localEulerAngles.x = Mathf.Clamp(this.localEulerAngles.x - t.deltaPosition.y * Time.deltaTime * 5, -36, 36);
@@ -42,6 +45,7 @@ public class BowCamera : MonoBehaviour
             this.transform.localEulerAngles = this.localEulerAngles; 
         };
         touchChecker.onEnded += delegate(Touch t, bool isOnUI) {
+            if (banUserControl) return;
             if (!isOnUI) armBow.ADS_fire();
         };
     }
@@ -53,6 +57,8 @@ public class BowCamera : MonoBehaviour
             cameraComp.fieldOfView = cameraFieldOfView;
         }
 
+        if (banUserControl) return;
+
         //满足以下条件则阻止控制输入
         if (GameMgr.ins.gameOver) {
            return;

+ 2 - 1
Assets/BowArrow/Scripts/Manager/GameMgr.cs

@@ -8,7 +8,7 @@ using UnityEngine.SceneManagement;
 public class GameMgr : MonoBehaviour
 {
     public static bool debugInEditor = false;
-    public static int gameType = 8;
+    public static int gameType = 9;
     public GameMode gameMode;
     [System.NonSerialized] public bool gameOver = false;
     public static GameMgr ins;
@@ -63,6 +63,7 @@ public class GameMgr : MonoBehaviour
         if (gameType == 6) gameMode = new RabbitHuntGameMode_LocalPK(this);
         if (gameType == 7) gameMode = new YejiHuntGameMode_LocalPK(this);
         if (gameType == 8) gameMode = new WolfHuntGameMode_LocalPK(this);
+        if (gameType == 9) gameMode = new PKGameMode_OnlinePK(this);
     }
 
     public void StopGame() {

+ 15 - 0
Assets/BowArrow/Scripts/Manager/GameMode/PKGameMode_OnlinePK.cs

@@ -0,0 +1,15 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+using DG.Tweening;
+
+/**双人PK模式 */
+public class PKGameMode_OnlinePK : PKGameMode {
+    SocketPlayer socketPlayer;
+
+    public PKGameMode_OnlinePK(GameMgr gameMgr) : base(gameMgr) {
+        socketPlayer = new GameObject().AddComponent<SocketPlayer>();
+        socketPlayer.gameMode = this;
+    }
+}

+ 11 - 0
Assets/BowArrow/Scripts/Manager/GameMode/PKGameMode_OnlinePK.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 7c3f0fdbc339c654da25fffd0ae06a57
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/BowArrow/Scripts/Network.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 41a70367ffd504a4198208b855e162dc
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 393 - 0
Assets/BowArrow/Scripts/Network/SocketIO-Test.unity

@@ -0,0 +1,393 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!29 &1
+OcclusionCullingSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_OcclusionBakeSettings:
+    smallestOccluder: 5
+    smallestHole: 0.25
+    backfaceThreshold: 100
+  m_SceneGUID: 00000000000000000000000000000000
+  m_OcclusionCullingData: {fileID: 0}
+--- !u!104 &2
+RenderSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 9
+  m_Fog: 0
+  m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
+  m_FogMode: 3
+  m_FogDensity: 0.01
+  m_LinearFogStart: 0
+  m_LinearFogEnd: 300
+  m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
+  m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
+  m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
+  m_AmbientIntensity: 1
+  m_AmbientMode: 0
+  m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
+  m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
+  m_HaloStrength: 0.5
+  m_FlareStrength: 1
+  m_FlareFadeSpeed: 3
+  m_HaloTexture: {fileID: 0}
+  m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
+  m_DefaultReflectionMode: 0
+  m_DefaultReflectionResolution: 128
+  m_ReflectionBounces: 1
+  m_ReflectionIntensity: 1
+  m_CustomReflection: {fileID: 0}
+  m_Sun: {fileID: 0}
+  m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1}
+  m_UseRadianceAmbientProbe: 0
+--- !u!157 &3
+LightmapSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 12
+  m_GIWorkflowMode: 1
+  m_GISettings:
+    serializedVersion: 2
+    m_BounceScale: 1
+    m_IndirectOutputScale: 1
+    m_AlbedoBoost: 1
+    m_EnvironmentLightingMode: 0
+    m_EnableBakedLightmaps: 1
+    m_EnableRealtimeLightmaps: 0
+  m_LightmapEditorSettings:
+    serializedVersion: 12
+    m_Resolution: 2
+    m_BakeResolution: 40
+    m_AtlasSize: 1024
+    m_AO: 0
+    m_AOMaxDistance: 1
+    m_CompAOExponent: 1
+    m_CompAOExponentDirect: 0
+    m_ExtractAmbientOcclusion: 0
+    m_Padding: 2
+    m_LightmapParameters: {fileID: 0}
+    m_LightmapsBakeMode: 1
+    m_TextureCompression: 1
+    m_FinalGather: 0
+    m_FinalGatherFiltering: 1
+    m_FinalGatherRayCount: 256
+    m_ReflectionCompression: 2
+    m_MixedBakeMode: 2
+    m_BakeBackend: 1
+    m_PVRSampling: 1
+    m_PVRDirectSampleCount: 32
+    m_PVRSampleCount: 512
+    m_PVRBounces: 2
+    m_PVREnvironmentSampleCount: 256
+    m_PVREnvironmentReferencePointCount: 2048
+    m_PVRFilteringMode: 1
+    m_PVRDenoiserTypeDirect: 1
+    m_PVRDenoiserTypeIndirect: 1
+    m_PVRDenoiserTypeAO: 1
+    m_PVRFilterTypeDirect: 0
+    m_PVRFilterTypeIndirect: 0
+    m_PVRFilterTypeAO: 0
+    m_PVREnvironmentMIS: 1
+    m_PVRCulling: 1
+    m_PVRFilteringGaussRadiusDirect: 1
+    m_PVRFilteringGaussRadiusIndirect: 5
+    m_PVRFilteringGaussRadiusAO: 2
+    m_PVRFilteringAtrousPositionSigmaDirect: 0.5
+    m_PVRFilteringAtrousPositionSigmaIndirect: 2
+    m_PVRFilteringAtrousPositionSigmaAO: 1
+    m_ExportTrainingData: 0
+    m_TrainingDataDestination: TrainingData
+    m_LightProbeSampleCountMultiplier: 4
+  m_LightingDataAsset: {fileID: 0}
+  m_LightingSettings: {fileID: 0}
+--- !u!196 &4
+NavMeshSettings:
+  serializedVersion: 2
+  m_ObjectHideFlags: 0
+  m_BuildSettings:
+    serializedVersion: 2
+    agentTypeID: 0
+    agentRadius: 0.5
+    agentHeight: 2
+    agentSlope: 45
+    agentClimb: 0.4
+    ledgeDropHeight: 0
+    maxJumpAcrossDistance: 0
+    minRegionArea: 2
+    manualCellSize: 0
+    cellSize: 0.16666667
+    manualTileSize: 0
+    tileSize: 256
+    accuratePlacement: 0
+    maxJobWorkers: 0
+    preserveTilesOutsideBounds: 0
+    debug:
+      m_Flags: 0
+  m_NavMeshData: {fileID: 0}
+--- !u!1 &150459559
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 150459561}
+  - component: {fileID: 150459560}
+  m_Layer: 0
+  m_Name: SocketPlayer
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &150459560
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 150459559}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 14d82bff517f19445b29f20462969b53, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  textSend: {fileID: 0}
+  textReceive: {fileID: 0}
+  textSendUsedTime: {fileID: 0}
+--- !u!4 &150459561
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 150459559}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 471.74866, y: 237.7269, z: -1282.9579}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 2
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1312951503
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1312951505}
+  - component: {fileID: 1312951504}
+  m_Layer: 0
+  m_Name: Directional Light
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!108 &1312951504
+Light:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1312951503}
+  m_Enabled: 1
+  serializedVersion: 10
+  m_Type: 1
+  m_Shape: 0
+  m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
+  m_Intensity: 1
+  m_Range: 10
+  m_SpotAngle: 30
+  m_InnerSpotAngle: 21.80208
+  m_CookieSize: 10
+  m_Shadows:
+    m_Type: 2
+    m_Resolution: -1
+    m_CustomResolution: -1
+    m_Strength: 1
+    m_Bias: 0.05
+    m_NormalBias: 0.4
+    m_NearPlane: 0.2
+    m_CullingMatrixOverride:
+      e00: 1
+      e01: 0
+      e02: 0
+      e03: 0
+      e10: 0
+      e11: 1
+      e12: 0
+      e13: 0
+      e20: 0
+      e21: 0
+      e22: 1
+      e23: 0
+      e30: 0
+      e31: 0
+      e32: 0
+      e33: 1
+    m_UseCullingMatrixOverride: 0
+  m_Cookie: {fileID: 0}
+  m_DrawHalo: 0
+  m_Flare: {fileID: 0}
+  m_RenderMode: 0
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_RenderingLayerMask: 1
+  m_Lightmapping: 4
+  m_LightShadowCasterMode: 0
+  m_AreaSize: {x: 1, y: 1}
+  m_BounceIntensity: 1
+  m_ColorTemperature: 6570
+  m_UseColorTemperature: 0
+  m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
+  m_UseBoundingSphereOverride: 0
+  m_UseViewFrustumForShadowCasterCull: 1
+  m_ShadowRadius: 0
+  m_ShadowAngle: 0
+--- !u!4 &1312951505
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1312951503}
+  m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
+  m_LocalPosition: {x: 0, y: 3, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
+--- !u!1 &1766978633
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1766978636}
+  - component: {fileID: 1766978635}
+  - component: {fileID: 1766978634}
+  m_Layer: 0
+  m_Name: Main Camera
+  m_TagString: MainCamera
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!81 &1766978634
+AudioListener:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1766978633}
+  m_Enabled: 1
+--- !u!20 &1766978635
+Camera:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1766978633}
+  m_Enabled: 1
+  serializedVersion: 2
+  m_ClearFlags: 1
+  m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
+  m_projectionMatrixMode: 1
+  m_GateFitMode: 2
+  m_FOVAxisMode: 0
+  m_SensorSize: {x: 36, y: 24}
+  m_LensShift: {x: 0, y: 0}
+  m_FocalLength: 50
+  m_NormalizedViewPortRect:
+    serializedVersion: 2
+    x: 0
+    y: 0
+    width: 1
+    height: 1
+  near clip plane: 0.3
+  far clip plane: 1000
+  field of view: 60
+  orthographic: 0
+  orthographic size: 5
+  m_Depth: -1
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_RenderingPath: -1
+  m_TargetTexture: {fileID: 0}
+  m_TargetDisplay: 0
+  m_TargetEye: 3
+  m_HDR: 1
+  m_AllowMSAA: 1
+  m_AllowDynamicResolution: 0
+  m_ForceIntoRT: 0
+  m_OcclusionCulling: 1
+  m_StereoConvergence: 10
+  m_StereoSeparation: 0.022
+--- !u!4 &1766978636
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1766978633}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 1, z: -10}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1856964627
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1856964629}
+  - component: {fileID: 1856964628}
+  m_Layer: 0
+  m_Name: SocketPlayer (1)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 0
+--- !u!114 &1856964628
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1856964627}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 14d82bff517f19445b29f20462969b53, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  textSend: {fileID: 0}
+  textReceive: {fileID: 0}
+  textSendUsedTime: {fileID: 0}
+--- !u!4 &1856964629
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1856964627}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 471.74866, y: 237.7269, z: -1282.9579}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 3
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

+ 7 - 0
Assets/BowArrow/Scripts/Network/SocketIO-Test.unity.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 73c0bf3ad7cd50b4f87ca003fcf63405
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 91 - 0
Assets/BowArrow/Scripts/Network/SocketPlayer.cs

@@ -0,0 +1,91 @@
+using System;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class SocketPlayer : JC.SocketIO.SocketIOClient
+{
+    public PKGameMode_OnlinePK gameMode;
+
+    void Start()
+    {
+        connectServer("http://192.168.101.14:8000/socket.io/");
+    }
+
+    public override void onLoad()
+    {
+        Debug.Log("onLoad");
+
+        call("RandomMatchRoom", 0);
+    }
+
+    public override void onReload()
+    {
+        Debug.Log("onReload");
+    }
+
+    public override void onDestroy()
+    {
+        Debug.Log("onDestroy");
+    }
+
+    public override void onMiss()
+    {
+        Debug.Log("onMiss");
+    }
+
+    bool isMyTime = false;
+
+    float uploadTimeCountDown = 0;
+
+    void Update() {
+        if (playerIndex < 0) return;
+        isMyTime = playerIndex == gameMode.currentPlayerIndex;
+        BowCamera.ins.banUserControl = !isMyTime;
+
+        if (isMyTime) {
+            uploadTimeCountDown -= Time.deltaTime;
+            if (uploadTimeCountDown <= 0) {
+                uploadTimeCountDown = 1f / 30;
+                UploadPKGameData();
+            }
+        } else {
+            BowCamera.ins.transform.rotation = Quaternion.Lerp(BowCamera.ins.transform.rotation, bowCameraTargetRotation, Time.deltaTime * 10);
+        }
+    }
+
+    PKGameData pkGameDataSend = new PKGameData();
+
+    void UploadPKGameData() {
+        Quaternion bowCameraR = BowCamera.ins.transform.rotation;
+        pkGameDataSend.rx = bowCameraR.x;
+        pkGameDataSend.ry = bowCameraR.y;
+        pkGameDataSend.rz = bowCameraR.z; 
+        pkGameDataSend.rw = bowCameraR.w;
+        call("UploadPKGameData", pkGameDataSend);
+    } 
+
+    Quaternion bowCameraTargetRotation;
+
+    public void OnReceivePKGameData(PKGameData pkGameData) {
+        bowCameraTargetRotation.x = pkGameData.rx;
+        bowCameraTargetRotation.y = pkGameData.ry;
+        bowCameraTargetRotation.z = pkGameData.rz;
+        bowCameraTargetRotation.w = pkGameData.rw;
+    }
+
+    //被服务器调用接口
+    int roomID;
+    int playerIndex = -1;
+    public void OnJoinRoomSuccess(int roomID, int playerIndex) {
+        this.roomID = roomID;
+        this.playerIndex = playerIndex;
+        Debug.Log("OnJoinRoomSuccess " + roomID + ", " + playerIndex);
+    }
+}
+
+public class PKGameData {
+    public float rx;
+    public float ry;
+    public float rz;
+    public float rw;
+}

+ 11 - 0
Assets/BowArrow/Scripts/Network/SocketPlayer.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 14d82bff517f19445b29f20462969b53
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 143 - 0
Assets/DependAsset/JC/JCSocketIO.cs

@@ -0,0 +1,143 @@
+using System;
+using UnityEngine;
+using BestHTTP.SocketIO;
+using Newtonsoft.Json;
+
+namespace JC.SocketIO {
+
+    public class SocketIOClient : MonoBehaviour {
+        private SocketManager _manager;
+        private Socket _socket;
+        private string _uri;
+
+        public virtual void OnDestroy() {
+            if (_manager != null) {
+                _manager.Close();
+            }
+        }
+
+        public void connectServer(string uri) {
+            _uri = uri;
+            _manager = new SocketManager(new System.Uri(_uri));
+            _manager.Options.AutoConnect = true; //自动打开
+            _manager.Options.Reconnection = true; //自动重连
+            _socket = _manager.Socket;
+            _socket.On(SocketIOEventTypes.Error, delegate(Socket socket, Packet packet, object[] args) {
+                if (!isValid) {
+                    try {
+                        onMiss();
+                    } catch (Exception e) { Debug.LogError(e.Message); }
+                }
+            });
+            _socket.On(SocketIOEventTypes.Disconnect, delegate(Socket socket, Packet packet, object[] args) {
+                if (isValid) {
+                    isValid = false;
+                    try {
+                        onDestroy();
+                    } catch (Exception e) { Debug.LogError(e.Message); }
+                }
+            });
+            _socket.On("call", delegate(Socket socket, Packet packet, object[] args) {
+                string str = packet.Payload;
+                int si = str.IndexOf("{");
+                int ei = str.LastIndexOf("]");
+                str = str.Substring(si, ei - si);
+                invoke(JsonConvert.DeserializeObject<DataPack>(str));
+            });
+        }
+
+        public void reconnectServer() {
+            if (_manager != null) {
+                _manager.Close();
+            }
+            connectServer(_uri);
+        }
+
+        [NonSerialized] public bool isValid;
+        [NonSerialized] public bool loaded;
+
+        public virtual void onLoad() {}
+
+        public virtual void onReload() {}
+
+        public virtual void onDestroy() {}
+
+        public virtual void onMiss() {}
+
+        public void call(string func, params object[] args) {
+            if (!isValid) return;
+            DataPack dataPack = new DataPack();
+            dataPack.type = 1;
+            dataPack.func = func;
+            dataPack.args = Utility.FormatArgs(args);
+            _socket.Emit("call", JsonConvert.SerializeObject(dataPack));
+        }
+
+        private void invoke(DataPack dataPack) {
+            if (dataPack.type == 0) {
+                if (dataPack.func == "onLoad") {
+                    isValid = true;
+                    try {
+                        if (loaded) {
+                            onReload();
+                        } else {
+                            onLoad();
+                        }
+                    } catch (Exception e) { Debug.LogError(e.Message); }
+                    loaded = true;
+                }
+            } else if (dataPack.type == 1) {
+                System.Reflection.MethodInfo method = this.GetType().GetMethod(dataPack.func);
+                Utility.FormatArgsType(dataPack.args, method.GetParameters());
+                method.Invoke(this, dataPack.args);
+            }
+        }
+
+        class DataPack {
+            public int type;
+            public string func;
+            public object[] args;
+        }
+
+        class Utility {
+            public static long GetTimestamp() {
+                TimeSpan ts = DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1);
+                return (long)ts.TotalMilliseconds;
+            }
+            public static object[] FormatArgs(object[] args) {
+                object[] newArgs = new object[args.Length];
+                for (int i = 0; i < args.Length; i++) {
+                    object arg = args[i];
+                    if (!IsBaseType(arg.GetType())) {
+                        newArgs[i] = JsonConvert.SerializeObject(arg);
+                    } else {
+                        newArgs[i] = arg;
+                    }
+                }
+                return newArgs;
+            }
+            public static void FormatArgsType(object[] args, System.Reflection.ParameterInfo[] parameters) {
+                int i = 0;
+                foreach (var param in parameters) {
+                    Type type = param.ParameterType;
+                    if (IsBaseType(type)) {
+                        args[i] = Convert.ChangeType(args[i], type);
+                    } else {
+                        args[i] = JsonConvert.DeserializeObject((string) args[i], type);
+                    }
+                    i++;
+                }
+            }
+            public static bool IsBaseType(Type type) {
+                if (typeof(System.Int32).Equals(type)) return true;
+                if (typeof(System.Int64).Equals(type)) return true;
+                if (typeof(System.Single).Equals(type)) return true;
+                if (typeof(System.Double).Equals(type)) return true;
+                if (typeof(System.String).Equals(type)) return true;
+                if (typeof(System.Boolean).Equals(type)) return true;
+                return false;
+            }
+        }
+    }
+    
+}

+ 11 - 0
Assets/DependAsset/JC/JCSocketIO.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 11432745983e1b6468486549f2bb7c02
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: