コード例 #1
0
    private void OnActorAiState(SocketAsyncEventArgs args, byte[] bytes)
    {
        ActorAiState input = ActorAiState.Parser.ParseFrom(bytes);

        if (input.RoomId != RoomId)
        {
            return; // 不是自己房间的消息,略过
        }
        if (input.AiCellIndexFrom == 0)
        {
            string msg = $"Actor position is lost!";
            ServerRoomManager.Instance.Log("RoomLogic OnActorAiState Error - " + msg);
            ActorAiStateReply output2 = new ActorAiStateReply()
            {
                RoomId  = input.RoomId,
                OwnerId = input.OwnerId,
                ActorId = input.ActorId,
                Ret     = false,
                ErrMsg  = msg,
            };

            ServerRoomManager.Instance.SendMsg(args, ROOM_REPLY.ActorAiStateReply, output2.ToByteArray());
            return;
        }

        // 更新单元Ai信息,在服务器的ActorBehaviour里保存一份
        var ab = ActorManager.GetActor(input.ActorId);

        if (ab != null)
        {
            ab.AiState        = input.AiState;
            ab.CellIndex      = input.AiCellIndexFrom;
            ab.AiCellIndexTo  = input.AiCellIndexTo;
            ab.AiTargetId     = input.AiTargetId;
            ab.Orientation    = input.Orientation;
            ab.AiDurationTime = input.AiDurationTime;
            ab.AiTotalTime    = input.AiTotalTime;
            ab.AiStartTime    = DateTime.Now; // 记录得到当前状态的时间, 在存盘的时候再记录一下时间, 把剩余时间保存起来
        }

        // 注意: 有一种情况, 可能是ab并不存在,但是这条消息还是有用的,因为ActorRemoveReply消息里, 服务器已经把本单元删掉了,
        // 但是服务器仍然需要转发一条将单位状态设置为StateEnum.DIE的消息
        ActorAiStateReply output = new ActorAiStateReply()
        {
            RoomId          = input.RoomId,
            OwnerId         = input.OwnerId,
            ActorId         = input.ActorId,
            AiState         = input.AiState,
            AiCellIndexFrom = input.AiCellIndexFrom,
            AiCellIndexTo   = input.AiCellIndexTo,
            AiTargetId      = input.AiTargetId,
            Orientation     = input.Orientation,
            AiDurationTime  = input.AiDurationTime,
            AiTotalTime     = input.AiTotalTime,
            Ret             = true,
        };

        BroadcastMsg(ROOM_REPLY.ActorAiStateReply, output.ToByteArray());
    }
コード例 #2
0
        private void OnActorAiStateReply(byte[] bytes)
        {
            ActorAiStateReply input = ActorAiStateReply.Parser.ParseFrom(bytes);

            if (input.ActorId != ActorId)
            {
                return; // 不是自己,略过
            }
            if (!input.Ret)
            {
                return;
            }

            HexCell fromCell = GameRoomManager.Instance.HexmapHelper.GetCell(input.AiCellIndexFrom);

            Vector3         newPosition = Vector3.zero;
            HexCell         targetCell  = null;
            ActorVisualizer avTarget    = null;

            if (AllActors.ContainsKey(input.AiTargetId))
            { //如果目标是单位,优先用单位的[所在格子的]坐标作为目标点, 注意, 也不是目标点的实际坐标
                avTarget   = AllActors[input.AiTargetId];
                targetCell = avTarget.HexUnit.Location;
            }
            else
            {
                targetCell = GameRoomManager.Instance.HexmapHelper.GetCell(input.AiCellIndexTo);
            }
            newPosition = targetCell.Position;

            StateEnum newAiState = (StateEnum)input.AiState;

            // 注: 在客户端: input.DurationTime是没有用的, 时间完全由 服务器端/AI端 控制

            switch (CurrentAiState)
            {
            case StateEnum.GUARD:
                ShowShield(false);
                break;

            case StateEnum.HARVEST:
                ShowSliderHarvest(false);
                break;

            case StateEnum.FIGHT:
                break;
            }

            CurrentAiState  = newAiState;
            TargetPosition  = newPosition;
            TargetActorId   = input.AiTargetId;
            TargetCellIndex = input.AiCellIndexTo;

            if (avTarget == null || avTarget.IsDead)
            {
                TargetActorId = 0;
            }

            AnimationState[] aniState = null;
            switch (CurrentAiState)
            {
            case StateEnum.IDLE:
                TargetPosition = CurrentPosition;
                GameRoomManager.Instance.HexmapHelper.Stop(input.ActorId);
                aniState = idleStates;
                break;

            case StateEnum.VANISH:
                //aniState = vanishStates; // vanishStates这个状态的动画不知道为什么不正确,这里只能继续沿用Die的最后一帧了
                break;

            case StateEnum.DIE:
                GameRoomManager.Instance.HexmapHelper.Stop(input.ActorId);
                aniState = deathStates;
                break;

            case StateEnum.WALK:
            case StateEnum.WALKFIGHT:
                _listPath = GameRoomManager.Instance.HexmapHelper.DoMove(input.ActorId, input.AiCellIndexFrom, input.AiCellIndexTo);
                Debug.Log($"MSG: ActorAiState - {CurrentAiState} - From<{fromCell.coordinates.X},{fromCell.coordinates.X}> - To<{targetCell.coordinates.X},{targetCell.coordinates.Z}>");
                //aniState = movementStates;
                aniState = runningStates;
                break;

            case StateEnum.FIGHT:
                GameRoomManager.Instance.HexmapHelper.Stop(input.ActorId);
                GameRoomManager.Instance.HexmapHelper.LookAt(input.ActorId, TargetPosition);
                ShowSliderBlood();
                aniState = attackingStates;
                break;

            case StateEnum.DELAYFIGHT:
                ShowSliderBlood();
                aniState = idleStates;     // 先不播放战斗动画,过了AttackInternal的时间以后再通过ActorPlayAni消息来播
                break;

            case StateEnum.GUARD:
                ShowShield();
                GameRoomManager.Instance.HexmapHelper.Stop(input.ActorId);
                aniState = idleStates;
                break;

            case StateEnum.HARVEST:
                ShowSliderHarvest(true, input.AiDurationTime, input.AiTotalTime);
                aniState = harvestStates;
                break;

            case StateEnum.NONE:
                aniState = idleStates;
                break;
            }
            PlayAnimation(aniState);
        }