lvjincheng před 3 roky
rodič
revize
f44f36881e

+ 35 - 0
Assets/BowArrow/Scripts/Manager/GameMode/OnlineObject/WolfSyncData.cs

@@ -0,0 +1,35 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class WolfSyncData
+{
+    public int id;
+    public float rx;
+    public float ry;
+    public float rz;
+    public float rw;
+    public float px;
+    public float py;
+    public float pz;
+    public int ai;
+    public int ct;
+    public int ii;
+    public int di;
+    public void SetData(Wolf wolf) {
+        id = wolf.onlineHandler.uid;
+        Quaternion r = wolf.transform.rotation;
+        Vector3 p = wolf.transform.position;
+        rx = r.x;
+        ry = r.y;
+        rz = r.z;
+        rw = r.w;
+        px = p.x;
+        py = p.y;
+        pz = p.z;
+        ai = wolf.curAnimIndex;
+        ct = wolf.colorType;
+        ii = wolf.onlineHandler.injuredID;
+        di = wolf.onlineHandler.deadID;
+    }
+}

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

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

+ 487 - 0
Assets/BowArrow/Scripts/Manager/GameMode/WolfHuntGameMode_OnlinePK.cs

@@ -0,0 +1,487 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using Newtonsoft.Json;
+using DG.Tweening;
+
+public class WolfHuntGameMode_OnlinePK : WolfHuntGameMode, ChallengeGameModeLocalPK
+{
+    public int currentPlayerIndex = 0; // 双人0和1
+    float singleShootReadyTime = 30f;
+    float singleShootReadyTimeMax = 30f;
+    int[] playerHpList = {20, 20}; 
+    public bool[] playerDieList = {false, false};
+
+    public WolfHuntGameMode_OnlinePK(GameMgr gameMgr) : base(gameMgr) {
+        onlineHelper = new OnlineHelper(this);
+        hunterGamePlayerScoreCounter = new HunterGamePlayerScoreCounter(this);
+        InitByCurPlayerIndex();
+        GameEventCenter.ins.onBowArrowShootOut += (a, b) => {
+            hasShootOut = true;
+        };
+        onHpZero += () => {//监听到当前玩家死亡
+            playerDieList[currentPlayerIndex] = true;
+            if (hasShootOut) return; //此时箭已射出,避免重复处理下面的逻辑,等NextShoot来处理
+            //切换到下一个玩家
+            if (IsOtherPlayerNotDie()) {
+                ArmBow.ins.readyShoot();
+                NextPlayerFinal();
+                NextRound();
+            } else { //游戏结束
+                AnnounceGameOver();
+            }
+        };
+        onHurtEffect += () => {
+            try {
+                onlineHelper.socketPlayer.UploadPKGameData("onHurtEffect", "");
+            }
+            catch (System.Exception e) { Debug.LogError(e.Message + "\n" + e.StackTrace); }
+        };
+        // this.playerHpList[0] = this.playerHpList[1] = this.hpMax = this.hp = 5;
+        // QuicklyCreateAnimalForDebug();
+    }
+
+    public override void Start()
+    {
+        onlineHelper.InitSocketPlayer(OnStart);
+    }
+
+    private void OnStart() {
+        banCreateAnimal = onlineHelper.IsCopyHost();
+        banOnBowArrowShootOut = onlineHelper.IsCopyHost();
+        GameMgr.ins.transform.Find("WolfActGrid").gameObject.SetActive(true);
+        SetLevel(5);
+        AddHuntGameView();
+        this.gameMgr.transform.Find("HunterGameView_LocalPK").gameObject.SetActive(true);
+    }
+
+    public override void Update() {
+        if (!onlineHelper.IsMyPlayerInited()) return;
+        if (!onlineHelper.IsMainHost()) return;
+        if (!onlineHelper.IsMyPlayerRunning()) return;
+        OnUpdate(Time.deltaTime, pauseTimeCounting);
+    }
+
+    void OnUpdate(float dt, bool _pauseTimeCounting) {
+        CheckAutoCreateAnimalByUpdate(dt);
+        if (gameMgr.gameOver || _pauseTimeCounting) return;
+        if (this.time > 0) {
+            this.time -= dt;
+        } else {
+            this.time = 0;
+            AnnounceGameOver();
+        }
+        if (gameMgr.gameOver || _pauseTimeCounting) return;
+        if (!IsOtherPlayerNotDie()) { //另一个玩家已经死了,倒计时就不要走了
+            singleShootReadyTime = singleShootReadyTimeMax;
+            return;
+        }
+        singleShootReadyTime -= dt;
+        if (singleShootReadyTime <= 0) {
+            //切换玩家
+            ArmBow.ins.readyShoot();
+            NextPlayerFinal();
+            NextRound();
+        }
+    }
+
+    public override void FrameUpdate() {
+        onlineHelper.OnFrameUpdate();
+    }
+
+    public override void onBowShoot() {
+        if (onlineHelper.IsCopyHost()) {
+            onlineHelper.socketPlayer.UploadPKGameData("onBowShoot", "");
+        }
+    }
+    
+    bool hasShootOut;
+    public override bool DoNextShoot() { 
+        if (onlineHelper.IsCopyHost()) {
+            onlineHelper.socketPlayer.UploadPKGameData("DoNextShoot", "");
+            return false;
+        }
+        foreach (var item in Wolf.wolfSet) {
+            if (item.onlineHandler.onDoNextShootWillDestroy) {
+                GameObject.Destroy(item.gameObject);
+            }    
+        }
+        hasShootOut = false;
+        if (IsAllPlayerDie()) {
+            AnnounceGameOver();
+            return false;
+        }
+        bool canDo = base.DoNextShoot();
+        if (canDo && IsOtherPlayerNotDie()) {
+            NextPlayerFinal();
+        }
+        if (canDo) {
+            NextRound();
+        }
+        return canDo;
+    }
+
+    void AddReadyView() 
+    {
+        GameObject view = Resources.Load<GameObject>("Prefabs/Views/PKGameReadyView_Challenge");
+        GameObject o = GameObject.Instantiate(view);
+        PKGameReadyView_Challenge script = o.GetComponent<PKGameReadyView_Challenge>();
+        script.currentPlayerIndex = currentPlayerIndex;
+    }
+
+    void NextRound() {
+        onlineHelper.roundID++;
+    }
+
+    //切换到下一个玩家
+    void NextPlayerFinal() {
+        NextPlayer();
+    }
+
+    void NextPlayer() {
+        RecordByCurPlayerIndex();
+        currentPlayerIndex = GetNextPlayerIndex();
+        InitByCurPlayerIndex();
+        singleShootReadyTime = singleShootReadyTimeMax;
+    }
+    int GetNextPlayerIndex() {
+        return (currentPlayerIndex + 1) % 2;
+    }
+    bool IsAllPlayerDie() {
+        return playerHpList[GetNextPlayerIndex()] <= 0 && hp <= 0;
+    }
+    bool IsOtherPlayerNotDie() {
+        return playerHpList[GetNextPlayerIndex()] > 0;
+    }
+
+    void InitByCurPlayerIndex() {
+        hp = playerHpList[currentPlayerIndex];
+        HunterGameView v = GameObject.FindObjectOfType<HunterGameView>();
+        if (v) v.RenderHPImmediate();
+    }
+
+    void RecordByCurPlayerIndex() {
+        playerHpList[currentPlayerIndex] = hp;
+    }
+
+    //localPK interface
+    public int GetCurrentPlayIndex() {
+        return currentPlayerIndex;
+    }
+    public (float, float) GetSingleShootReadyTime() {
+        return (singleShootReadyTime, singleShootReadyTimeMax);
+    }
+    HunterGamePlayerScoreCounter hunterGamePlayerScoreCounter;
+    public HunterGamePlayerScoreCounter getHunterGamePlayerScoreCounter() {
+        return hunterGamePlayerScoreCounter;
+    }
+
+    //###------------
+    //###  联机部分
+    //###------------
+
+    public class SyncLogicData {
+        public int roundID;
+        public int currentPlayerIndex;
+        public float singleShootReadyTime;
+        public int animalCount = 0;
+        public int[] hitScores;
+        public int[] hpList;
+        public int hp;
+        public bool[] dieList;
+        public bool gameEnd = false;
+        public SyncLogicData Input(WolfHuntGameMode_OnlinePK src) {
+            roundID = src.onlineHelper.roundID;
+            currentPlayerIndex = src.currentPlayerIndex;
+            singleShootReadyTime = src.singleShootReadyTime;
+            animalCount = src.animalCount;
+            hitScores = src.getHunterGamePlayerScoreCounter().hitScores;
+            hpList = src.playerHpList;
+            hp = src.hp;
+            dieList = src.playerDieList;
+            gameEnd = src.gameMgr.gameOver;
+            return this;
+        }
+        public void Output(WolfHuntGameMode_OnlinePK dest) {
+            dest.onlineHelper.roundID = roundID;
+            dest.currentPlayerIndex = currentPlayerIndex;
+            dest.singleShootReadyTime = singleShootReadyTime;
+            dest.animalCount = animalCount;
+            dest.getHunterGamePlayerScoreCounter().hitScores = hitScores;
+            dest.playerHpList = hpList;
+            dest.hp = hp;
+            dest.playerDieList = dieList;
+            dest.onlineHelper.gameEnd = gameEnd;
+        }
+    }
+
+    OnlineHelper onlineHelper;
+    public class OnlineHelper {
+        WolfHuntGameMode_OnlinePK gameMode;
+        public OnlineHelper(WolfHuntGameMode_OnlinePK gameMode) {
+            this.gameMode = gameMode;
+        }
+        public SocketPlayer socketPlayer;
+        public int myPlayerIndex = -1;
+        public bool IsMyPlayerInited() {
+            return myPlayerIndex >= 0;
+        }
+        public bool IsMyPlayerRunning() {
+            return myPlayerIndex == gameMode.currentPlayerIndex;
+        }
+        public bool IsMainHost() {
+            return myPlayerIndex == 0;
+        }
+        public bool IsCopyHost() {
+            return myPlayerIndex > 0;
+        }
+        public int roundID = 0;
+        public bool gameEnd = false;
+
+        public void InitSocketPlayer(Action successCallback) {
+            if (GameObject.Find("SocketPlayer") == null) {
+                PKMatchingView.MoniMatchForTestInGameScene(() => {
+                    myPlayerIndex = GlobalData.playerIndexInRoom;
+                    if (successCallback != null) successCallback();
+                });
+            } else {
+                myPlayerIndex = GlobalData.playerIndexInRoom;
+                if (successCallback != null) successCallback();
+            }
+            socketPlayer = GameObject.Find("SocketPlayer").GetComponent<SocketPlayer>();
+            socketPlayer.onReceivePKGameData = onReceivePKGameData;
+            AutoSwitchBanUserControlBow();
+            JC.Unity.CoroutineStarter.Start(CheckAndUpload());
+        }
+        bool IsCanUpload() {
+            return GameMgr.ins == gameMode.gameMgr && gameMode.gameMgr;
+        }
+        WaitForSecondsRealtime uploadOnceTime = new WaitForSecondsRealtime(0.033f);
+        IEnumerator CheckAndUpload() {
+            Debug.Log("协程-同步数据-开始");
+            while (IsCanUpload()) {
+                try
+                {
+                    Upload();
+                }
+                catch (System.Exception e)
+                {
+                    Debug.LogError(e.Message);
+                    Debug.LogError(e.StackTrace);
+                }
+                yield return uploadOnceTime;
+            }
+            Debug.Log("协程-同步数据-停止");
+        }
+
+        Quaternion bowTargetQua; 
+        bool hasBowTargBtQua;
+        void onReceivePKGameData(string key, string data) {
+            if (!IsMyPlayerInited()) return;
+            if (key == "logic") {
+                SyncLogicData syncLogicData = JsonConvert.DeserializeObject<SyncLogicData>(data);
+                syncLogicData.Output(this.gameMode);
+                AutoSwitchBanUserControlBow();
+            }
+            if (key == "bow") {
+                if (!IsMyPlayerRunning()) {
+                    string[] quaStr = data.Split(',');
+                    if (quaStr.Length == 6) {
+                        bowTargetQua.x = float.Parse(quaStr[0]);
+                        bowTargetQua.y = float.Parse(quaStr[1]);
+                        bowTargetQua.z = float.Parse(quaStr[2]);
+                        bowTargetQua.w = float.Parse(quaStr[3]);
+                        hasBowTargBtQua = true;
+                        ArmBow.ins.phase = int.Parse(quaStr[4]);
+                        GameAssistUI.ins.playerScaleAimValue_OnlinePK = int.Parse(quaStr[5]);
+                    } 
+                }
+            }
+            if (key == "arrow") {
+                List<ArrowSync.SyncData> arrowSyncDataList = JsonConvert.DeserializeObject<List<ArrowSync.SyncData>>(data);
+                foreach (var item in arrowSyncMap) {
+                    item.Value.hasSetSyncData = false;
+                }
+                GameObject arrowPrefab = ArmBow.ins.arrow;
+                foreach (var item in arrowSyncDataList) {
+                    ArrowSync arrowSync;
+                    arrowSyncMap.TryGetValue(item.id, out arrowSync);
+                    if (arrowSync == null) {
+                        GameObject arrowObj = GameObject.Instantiate(arrowPrefab);
+                        arrowSync = arrowObj.AddComponent<ArrowSync>();
+                        arrowSync.SetSyncData(item, true);
+                        arrowSyncMap[item.id] = arrowSync;
+                    } else {
+                        arrowSync.SetSyncData(item);
+                    }
+                    arrowSync.hasSetSyncData = true;
+                }
+                List<int> removeIDs = null;
+                foreach (var item in arrowSyncMap) {
+                    if (!item.Value.hasSetSyncData) {
+                        if (removeIDs == null) removeIDs = new List<int>();
+                        removeIDs.Add(item.Key);
+                    } 
+                }
+                if (removeIDs != null) {
+                    foreach (var id in removeIDs) {
+                        ArrowSync arrowSync = arrowSyncMap[id];
+                        arrowSyncMap.Remove(id);
+                        if (arrowSync && arrowSync.gameObject) {
+                            GameObject.Destroy(arrowSync.gameObject);
+                        }
+                    }
+                }
+            }
+            if (key == "onBowShoot") {
+                GameEventCenter.ins.onBowArrowShootOut?.Invoke(null, null);
+            }
+            if (key == "DoNextShoot") {
+                gameMode.DoNextShoot();
+            }
+            if (key == "animals") {
+                List<WolfSyncData> syncDataList = JsonConvert.DeserializeObject<List<WolfSyncData>>(data);
+                foreach (var item in animalSyncMap) {
+                    item.Value.onlineHandler.isInvalid = true;
+                }
+                foreach (var item in syncDataList) {
+                    Wolf animalSync;
+                    animalSyncMap.TryGetValue(item.id, out animalSync);
+                    if (animalSync == null) {
+                        GameObject animalObject = GameObject.Instantiate(gameMode.animalPrefab, Vector3.zero, Quaternion.identity, gameMode.animalsBaseT);
+                        animalSync = animalObject.GetComponent<Wolf>();
+                        animalSync.onlineHandler.isMirror = true;
+                        animalSync.onlineHandler.inputSyncData = item;
+                        animalObject.SetActive(true);
+                        animalSyncMap[item.id] = animalSync;
+                    } else {
+                        animalSync.onlineHandler.inputSyncData = item;
+                    }
+                    animalSync.onlineHandler.isInvalid = false;
+                }
+                List<int> removeIDs = null;
+                foreach (var item in animalSyncMap) {
+                    if (item.Value.onlineHandler.isInvalid) {
+                        if (removeIDs == null) removeIDs = new List<int>();
+                        removeIDs.Add(item.Key);
+                    } 
+                }
+                if (removeIDs != null) {
+                    foreach (var id in removeIDs) {
+                        Wolf animalSync = animalSyncMap[id];
+                        animalSyncMap.Remove(id);
+                        if (animalSync && animalSync.gameObject) {
+                            GameObject.Destroy(animalSync.gameObject);
+                        }
+                    }
+                }
+            }
+            if (key == "RUpdate") {
+                if (int.Parse(data) == roundID) {
+                    gameMode.OnUpdate(uploadOnceTime.waitTime, false);
+                }
+            }
+            if (key == "OnHit") {
+                string[] dataSplits = data.Split(',');
+                int uid = int.Parse(dataSplits[0]);
+                string partName = dataSplits[1];
+                foreach (var item in Wolf.wolfSet) {
+                    if (item.onlineHandler.uid == uid) {
+                        item.OnHitLogic(null, partName);
+                        break; //一定要break,原因1:这是唯一ID,后续也没必要检测了,原因2:这里可能会触发死亡,死亡会触发下个动物生成,Set集合的元素+1,继续遍历会出现modifyException
+                    }    
+                }
+            }
+            if (key == "onHurtEffect") {
+                this.gameMode.DoTweenHurt();
+            }
+        }
+
+        public void AutoSwitchBanUserControlBow() {
+            BowCamera.ins.banLogic = ArmBow.ins.banLogic = !IsMyPlayerRunning();
+        }
+
+        int lastRoundID = -1;
+        int lastRoundTipPlayerIndex = -1; //是否需要切换玩家,提示动画
+        public void OnFrameUpdate() {
+            if (!IsMyPlayerInited()) return;
+            AutoSwitchBanUserControlBow();
+            if (!IsMyPlayerRunning() && hasBowTargBtQua) {
+                BowCamera.ins.transform.rotation = Quaternion.Lerp(BowCamera.ins.transform.rotation, bowTargetQua, Time.deltaTime * 12);
+            }
+            if (roundID > lastRoundID) {
+                lastRoundID = roundID;
+                if (lastRoundTipPlayerIndex != gameMode.currentPlayerIndex) {
+                    lastRoundTipPlayerIndex = gameMode.currentPlayerIndex;
+                    gameMode.BanBowReady();
+                    gameMode.AddReadyView();
+                    gameMode.InitByCurPlayerIndex();
+                } else {
+                    if (IsCopyHost()) {
+                        gameMode.UnbanBowReady();
+                    }
+                }
+            }
+            if (gameEnd && !gameMode.gameMgr.gameOver) {
+                gameMode.AnnounceGameOver();
+            }
+        }
+
+        void Upload() {
+            if (!IsMyPlayerInited()) return;
+            UploadLogic();
+            UploadBow();
+            UploadArrows();
+            UploadAnimals();
+            UploadRequestUpdate();
+            UploadOnHit();
+        }
+        void UploadLogic() {
+            if (!IsMainHost()) return;
+            SyncLogicData data = new SyncLogicData().Input(this.gameMode);
+            socketPlayer.UploadPKGameData("logic", data);
+        }
+        void UploadBow() {
+            if (!IsMyPlayerRunning()) return;
+            Quaternion qua = BowCamera.ins.transform.rotation;
+            int aimScaleValue = GameAssistUI.ins.aimScaleValue;
+            if (!GameAssistUI.ins.scaleAimOn) aimScaleValue = 0;
+            socketPlayer.UploadPKGameData("bow", qua.x + "," + qua.y + "," + qua.z + "," + qua.w + "," + ArmBow.ins.phase + "," + aimScaleValue);
+        }
+        Dictionary<int, ArrowSync> arrowSyncMap = new Dictionary<int, ArrowSync>();
+        void UploadArrows() {
+            List<ArrowSync.SyncData> arrowSyncDataList = new List<ArrowSync.SyncData>();
+            foreach (var item in Arrow.arrowSet) {
+                if (item.outputSyncData == null || !item.outputSyncData.inited) continue;
+                arrowSyncDataList.Add(item.outputSyncData);
+            }
+            socketPlayer.UploadPKGameData("arrow", arrowSyncDataList);
+        }
+        Dictionary<int, Wolf> animalSyncMap = new Dictionary<int, Wolf>();
+        void UploadAnimals() {
+            if (!IsMainHost()) return;
+            List<WolfSyncData> syncDataList = new List<WolfSyncData>();
+            foreach (var item in Wolf.wolfSet) {
+                if (item.onlineHandler.outputSyncData == null) continue;
+                syncDataList.Add(item.onlineHandler.outputSyncData);
+            }
+            socketPlayer.UploadPKGameData("animals", syncDataList);
+        }
+        void UploadRequestUpdate() {
+            if (!IsCopyHost()) return;
+            if (!IsMyPlayerRunning()) return;
+            if (gameMode.pauseTimeCounting) return;
+            socketPlayer.UploadPKGameData("RUpdate", this.roundID.ToString());
+        }
+
+        void UploadOnHit() {
+            foreach (var item in Wolf.wolfSet) {
+                if (item.onlineHandler.onHitData != null) {
+                    socketPlayer.UploadPKGameData("OnHit", item.onlineHandler.onHitData);
+                    item.onlineHandler.onHitData = null;
+                }    
+            }
+        }
+    }
+}

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

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