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; }
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); } }
/// <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); }
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(); }
/// <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(); }
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(); } }
/// <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); }