예제 #1
0
        public void LocalPlayerWalkToDestination(Vector3 targetPos, Task relateTask = null)
        {
            Actor player = Game.GetInstance().GetLocalPlayer();

            if (player == null)
            {
                return;
            }

            targetPos.y = RoleHelp.GetHeightInScene(player.ActorId, targetPos.x, targetPos.z);
            targetPos   = InstanceHelper.ClampInWalkableRange(targetPos, 10);

            // 判断是否可到达
            XNavMeshPath walkMeshPath = new XNavMeshPath();

            XNavMesh.CalculatePath(player.transform.position, targetPos, xc.Dungeon.LevelManager.GetInstance().AreaExclude, walkMeshPath);
            if (walkMeshPath.status != XNavMeshPathStatus.PathComplete)
            {
                // 如果通过任务导航寻路,且在新手副本的不可到达区域,则直接飞过去,以免因为配置错误而导致卡死
                if (relateTask != null && SceneHelp.Instance.CurSceneID == GameConstHelper.GetUint("GAME_BORN_DUNGEON"))
                {
                    GameDebug.LogWarning(DBConstText.GetText("MAP_POS_CAN_NOT_REACH") + ",该场景是新手场景,直接瞬移过去");
                    player.MoveCtrl.SendFly(targetPos);
                    player.SetPosition(targetPos);
                }
                else
                {
                    UINotice.Instance.ShowMessage(DBConstText.GetText("MAP_POS_CAN_NOT_REACH"));
                }
                return;
            }

            InstanceManager.Instance.IsAutoFighting = false;

            mPathWalker.WalkTo(targetPos);
            //player.MoveCtrl.TryWalkTo(targetPos);

            /*
             * uint instanceType = InstanceManager.Instance.InstanceType;
             *
             * if (instanceType == GameConst.WAR_TYPE_WILD || instanceType == GameConst.WAR_TYPE_HOLE || instanceType == GameConst.WAR_SUBTYPE_WILD_PUB || instanceType == GameConst.WAR_TYPE_MULTI)
             * {
             *  if(mPathWalker == null)
             *  {
             *      return;
             *  }
             *
             *  mPathWalker.WalkTo(targetPos);
             * }
             * else
             * {
             *  player.MoveCtrl.TryWalkTo(targetPos);
             * }*/

            TaskNavigationActive(true);
            IsNavigating = true;
        }
예제 #2
0
        public override void HandleActorCreate(Actor actor)
        {
            base.HandleActorCreate(actor);

            mActorUID = actor.UID;

            if (Actor == null)
            {
                return;
            }

            var monster = actor as Monster;

            monster.Color = (Monster.QualityColor)Info.color;
            monster.SetNameText();
            monster.CurLife         = Info.hp; // 同步当前血量
            monster.AlwaysShowHpBar = true;
            //monster.SpartanMonsterGroupId = (int)Info.group_id;

            // 设置玩家坐标
            Actor.Stop();

            var unit_scale = GlobalConst.UnitScale;
            var x          = AppearInfo.pos.px * unit_scale;
            var z          = AppearInfo.pos.py * unit_scale;
            var pos        = new Vector3(x, RoleHelp.GetHeightInScene(Actor.ActorId, x, z), z);

            //pos = InstanceHelper.ClampInWalkableRange(pos);

            Actor.transform.position = pos;

            // 进入AOI视野增加buff
            if (BuffList != null)
            {
                uint server_time = Game.Instance.ServerTime;
                for (int i = 0; i < BuffList.Count; ++i)
                {
                    uint end_time = (uint)(BuffList[i].v / 1000);
                    uint second   = 1;
                    if (end_time > server_time)
                    {
                        second = end_time - server_time;
                    }
                    //GameDebug.LogError(string.Format("servertime = {0} BuffList[i].v = {1} second = {2}", server_time, end_time, second));
                    Actor.BuffCtrl.AddBuff(BuffList[i].k, second);
                }
            }

            if (AppearInfo.speed > 0)
            {
                Actor.MoveCtrl.ReceiveWalkBegin(AppearInfo);
            }
        }
예제 #3
0
        /// <summary>
        /// 实际创建Actor
        /// </summary>
        protected override void CreateActor()
        {
            base.CreateActor();

            Vector3 pos_born = Vector3.zero;

            if (AppearInfo != null)
            {
                var unit_scale = GlobalConst.UnitScale;
                var x          = AppearInfo.pos.px * unit_scale;
                var z          = AppearInfo.pos.py * unit_scale;
                pos_born = new Vector3(x, RoleHelp.GetHeightInScene(Info.actor_id, x, z), z);
            }

            var cache_info = ActorHelper.CreateUnitCacheInfo(Info, pos_born);

            ActorManager.Instance.PushUnitCacheData(cache_info);
        }
예제 #4
0
        public void SetPosition(Vector3 pos)
        {
            Vector3 newPos = pos;

            newPos.y = RoleHelp.GetHeightInScene(mOwner.ActorId, newPos.x, newPos.z);

            /*if (m_NavMeshAgent != null)
             * {
             *  m_NavMeshAgent.enabled = false;
             * }*/

            mOwnerTrans.position = newPos;

            /*if (m_NavMeshAgent != null)
             * {
             *  m_NavMeshAgent.enabled = true;
             * }*/

            m_IsGround = true;
            OnMove();
        }
예제 #5
0
        /// <summary>
        /// 移动固定的位置
        /// </summary>
        /// <param name="offset">移动的偏移数值</param>
        /// <param name="on_ground">移动时是否贴近地面</param>
        /// <param name="slider">移动时是否沿着边界滑动</param>
        public void Move(Vector3 offset, bool on_ground, bool slider = true)
        {
//             MoveAgent(offset, on_ground, slider);
//             return;

            if (offset == Vector3.zero || mOwner.DisableMoveState)
            {
                return;
            }

            move_data.pos = new PkgNwarPos();

            // 减少Trans.position 这样的调用,会显著影响性能
            Vector3 ownerPos = mOwnerTrans.position;

            // 当移动不贴近地面(浮空等)时,需要先计算贴近地面的高度,不然NavMesh的碰撞检测可能检测不到
            if (on_ground == false)
            {
                float height = RoleHelp.GetHeightInScene(mOwner.ActorId, ownerPos.x, ownerPos.z);
                ownerPos.y = height;
            }

            Vector3 origin = ownerPos;        // 碰撞检测的起点
            Vector3 newPos = origin + offset; // 移动后的新位置

            Vector3 move     = offset;        // 偏移量
            float   offset_y = move.y;        // 记录原有的高度偏移

            move.y = 0;                       // 碰撞检测时将高度偏移设置为0

            bool touchEdge = false;           // 已经触碰到边界

            bool is_localplayer = mOwner.IsLocalPlayer;

            bool collide_check = true;
            bool is_monster    = mOwner.IsMonster();//怪物不进行碰撞检测

            if (is_monster)
            {
                collide_check = false;
            }
            else
            {
                collide_check = true;
            }

            if (collide_check)
            {
                Vector3     final_move = move;
                XNavMeshHit hit;
                if (XNavMesh.Raycast(origin, origin + move * (1.0f + Radius / move.magnitude), out hit, LevelManager.GetInstance().AreaExclude))
                {
                    touchEdge = true;

                    if (slider)// 需要沿着边界滑动时
                    {
                        float sameDir = Vector3.Dot(hit.normal, final_move);
                        if (sameDir > 0)// 法线与移动方向相同,说明角色在边界外
                        {
                            final_move.y = offset_y;
                            newPos       = origin + final_move;
                        }
                        else
                        {
                            if (hit.normal == Vector3.zero)// NavMesh获得的法线数值可能为0
                            {
                                Debug.DrawLine(origin, origin + final_move, Color.yellow, 5.0f);

                                final_move.y = offset_y;
                                newPos       = origin + final_move;
                                //final_move = Vector3.zero;
                                //newPos = origin;
                            }
                            else
                            {
                                // 碰到边界进行滑动
                                Vector3 tanget = Vector3.Cross(Vector3.up, hit.normal);
                                final_move = tanget * Vector3.Dot(tanget, final_move);
                                float sMoveLen = final_move.magnitude;
                                if (sMoveLen < DBActor.MinDisToGround)// 移动方向垂直于法线
                                {
                                    final_move = Vector3.zero;
                                    newPos     = origin;
                                }
                                else
                                {
                                    // 沿着切线方向再次做检测,以免滑动的时候移动到另一个边界外
                                    if (XNavMesh.Raycast(origin, origin + final_move * (1.0f + Radius / sMoveLen), out hit, LevelManager.GetInstance().AreaExclude))
                                    {
                                        final_move = Vector3.zero;
                                        newPos     = origin;
                                    }
                                    else
                                    {
                                        final_move.y = offset_y;
                                        newPos       = origin + final_move;
                                    }
                                }
                            }
                        }
                    }
                    else// 不滑动,则直接移动到碰撞点
                    {
                        Vector3 radius_pos = PhysicsHelp.BoundaryHitPos(origin, hit.position);
                        newPos.x = radius_pos.x;
                        newPos.z = radius_pos.z;
                    }
                }
            }

            float terrain_height = RoleHelp.GetHeightInScene(mOwner.ActorId, newPos.x, newPos.z);

            if (newPos.y < terrain_height + DBActor.MinDisToGround)// 如果当前位置已经贴近地面,则设置m_IsGround为true
            {
                m_IsGround = true;
                newPos.y   = terrain_height;
            }
            else
            {
                if (on_ground || touchEdge) // 如果角色已经触碰到边界,则让其掉到地上
                {
                    newPos.y   = terrain_height;
                    m_IsGround = true;
                }
                else
                {
                    m_IsGround = false;
                }
            }

            // 在多人副本、野外地图中,本地玩家碰到障碍物的时候需要通知服务端
            if (is_localplayer && slider)
            {
                if (touchEdge)
                {
                    m_IsTouchEdge = true;

                    Vector3 totalMove = newPos - origin;
                    totalMove.y = 0;
                    Vector3 moveDir = totalMove.normalized;

                    move_data.id     = mOwner.UID.obj_idx;
                    move_data.pos.px = (int)(origin.x * 100.0f);
                    move_data.pos.py = (int)(origin.z * 100.0f);
                    move_data.dir    = Maths.Util.VectorToAngle(moveDir);

                    float   totalMoveLen = totalMove.magnitude;
                    Vector3 xz_offset    = offset;
                    xz_offset.y = 0;
                    float ortMoveLen = xz_offset.magnitude;
                    if (totalMoveLen > 0 && ortMoveLen > 0)
                    {
                        move_data.speed = (uint)(mOwner.MoveSpeed * (totalMoveLen / ortMoveLen) * 100);
                    }
                    else
                    {
                        move_data.speed = 0;
                    }

                    // 数据发生变化时才发送滑动协议
                    if (!mSliderData.Equal(move_data))
                    {
                        mSliderData.Assign(move_data);

                        slider_data.slide = move_data;
                        NetClient.GetCrossClient().SendData <C2SNwarSlide>(NetMsg.MSG_NWAR_SLIDE, slider_data);
                    }
                }
                // 当滑动结束时,需要同步一次方向和位置
                else if (m_IsTouchEdge)
                {
                    m_IsTouchEdge = false;

                    Vector3 totalMove = newPos - origin;
                    totalMove.y = 0;
                    Vector3 moveDir = totalMove.normalized;

                    move_data.id     = mOwner.UID.obj_idx;
                    move_data.pos.px = (int)(origin.x * 100.0f);
                    move_data.pos.py = (int)(origin.z * 100.0f);
                    move_data.dir    = Maths.Util.VectorToAngle(moveDir);

                    float   totalMoveLen = totalMove.magnitude;
                    Vector3 xz_offset    = offset;
                    xz_offset.y = 0;
                    float ortMoveLen = xz_offset.magnitude;
                    if (totalMoveLen > 0 && ortMoveLen > 0)
                    {
                        move_data.speed = (uint)(mOwner.MoveSpeed * (totalMoveLen / ortMoveLen) * 100);
                    }
                    else
                    {
                        move_data.speed = 0;
                    }

                    mSliderData.Assign(move_data);
                    slider_data.slide = move_data;
                    NetClient.GetCrossClient().SendData <C2SNwarSlide>(NetMsg.MSG_NWAR_SLIDE, slider_data);
                }
            }

            mOwnerTrans.position = newPos;
            OnMove();
        }
예제 #6
0
        public void HandleAppear(PkgNwarMove appear, uint version, List <PkgKv> buffs, uint appear_bit)
        {
            DeadTime = 0f;

            var redundancy_appear = false;

            if (AppearInfo != null)
            {
                redundancy_appear = true;
            }

            AppearInfo = appear;
            BuffList   = buffs;
            AppearBit  = appear_bit;

            if (Actor != null)
            {
                if (FlagOperate.HasFlag(appear_bit, GameConst.APPEAR_BIT_IS_DEAD))// 初始就是死亡状态
                {
                    if (!Actor.IsDead())
                    {
                        Actor.BeattackedCtrl.KillSelf();
                    }
                }
                else
                {
                    if (Actor.IsDead())
                    {
                        Actor.Relive();
                    }
                }

                // Actor已经创建了,直接更新下就好
                var unit_scale = GlobalConst.UnitScale;
                var x          = AppearInfo.pos.px * unit_scale;
                var z          = AppearInfo.pos.py * unit_scale;
                var pos        = new Vector3(x, RoleHelp.GetHeightInScene(Actor.ActorId, x, z), z);

                Actor.transform.position = pos;

                // 进入AOI视野增加buff
                if (BuffList != null)
                {
                    uint server_time = Game.Instance.ServerTime;
                    for (int i = 0; i < BuffList.Count; ++i)
                    {
                        uint end_time = (uint)(BuffList[i].v / 1000);
                        uint second   = 1;
                        if (end_time > server_time)
                        {
                            second = end_time - server_time;
                        }
                        //GameDebug.LogError(string.Format("servertime = {0} BuffList[i].v = {1} second = {2}", server_time, end_time, second));
                        Actor.BuffCtrl.AddBuff(BuffList[i].k, second);
                    }
                }

                if (AppearInfo.speed > 0)
                {
                    Actor.MoveCtrl.ReceiveWalkBegin(appear);
                }

                // version有变化的时候更新缓存
                if (Info != null && Info.version != version)
                {
                    SendUpdateInfo();
                }

                return;
            }

            // 如果已经appear过了,不要再处理了
            if (redundancy_appear)
            {
                return;
            }

            if (Info == null || IsInfoOutOfDate || Info.version != version)
            {
                // 获取玩家信息
                SendUpdateInfo();
                return;
            }

            if (!mIsWaittingCreateActor)
            {
                CreateActor();
            }
        }
예제 #7
0
        /// <summary>
        /// 处理actor创建成功
        /// </summary>
        /// <param name="actor"></param>
        public override void HandleActorCreate(Actor actor)
        {
            base.HandleActorCreate(actor);

            mActorUID = actor.UID;

            if (Actor == null)
            {
                return;
            }

            // 设置玩家坐标
            Actor.Stop();

            if (AppearInfo == null)
            {
                GameDebug.LogError("HandleActorCreate AppearInfo == null, uuid = " + UUID);
                return;
            }

            var unit_scale = GlobalConst.UnitScale;
            var x          = AppearInfo.pos.px * unit_scale;
            var z          = AppearInfo.pos.py * unit_scale;
            var pos        = new Vector3(x, RoleHelp.GetHeightInScene(Actor.ActorId, x, z), z);

            //pos = InstanceHelper.ClampInWalkableRange(pos);

            Actor.transform.position = pos;

            // 进入AOI视野增加buff
            if (BuffList != null)
            {
                uint server_time = Game.Instance.ServerTime;
                for (int i = 0; i < BuffList.Count; ++i)
                {
                    uint end_time = (uint)(BuffList[i].v / 1000);
                    uint second   = 1;
                    if (end_time > server_time)
                    {
                        second = end_time - server_time;
                    }
                    //GameDebug.LogError(string.Format("servertime = {0} BuffList[i].v = {1} second = {2}", server_time, end_time, second));
                    Actor.BuffCtrl.AddBuff(BuffList[i].k, second);
                }
            }

            if (FlagOperate.HasFlag(AppearBit, GameConst.APPEAR_BIT_IS_DEAD))// 初始就是死亡状态
            {
                if (!Actor.IsDead())
                {
                    Actor.BeattackedCtrl.KillSelf();
                }
            }
            else
            {
                if (Actor.IsDead())
                {
                    Actor.Relive();
                }
            }

            if (AppearInfo.speed > 0)
            {
                Actor.MoveCtrl.ReceiveWalkBegin(AppearInfo);
            }

            if (Info == null)
            {
                GameDebug.LogError("HandleActorCreate Info == null, uuid = " + UUID);
                return;
            }

            if (Info.war != null)
            {
                foreach (PkgAttrElm attrElm in Info.war.attr_elm)
                {
                    if (attrElm.attr == GameConst.AR_MAX_HP)
                    {
                        Actor.FullLife = attrElm.value;
                    }
                    else if (attrElm.attr == GameConst.AR_MAX_MP)
                    {
                        Actor.FullMp = attrElm.value;
                        Actor.CurMp  = Actor.FullMp; // 初始化时将蓝量加满
                    }
                }

                Actor.CurLife = Info.war.hp;
                // 进入AOI视野增加buff

                /*for(int i = 0; i < Info.war.buffs.Count; ++i)
                 * {
                 *  Actor.AuraCtrl.AddAura(Info.war.buffs[i].k);
                 * }*/
            }

            Actor.SubscribeActorEvent(Actor.ActorEvent.DEAD, OnActorDead);
            Actor.UpdateNameColor(Info.name_color);
            if (Info.war != null)
            {
                //Actor.PKLvProtect = Info.war.pk_lv_protect;
                Actor.UpdateByBitState(Info.bit_states);
            }

            WaittingLookExtList.Add(UUID);
        }