public static ETTask PushBackedTo(this CharacterMoveComponent self, Vector3 target, float speed) { self.moveTarget = target; self.RaycastPushBackPos(ref self.moveTarget); float distance = Vector3.Distance(self.unit.Position, self.moveTarget); self.moveType = MoveType.PushedBack; self.moveSpeed = speed; self.startPosition = self.unit.Position; self.moveDir = (self.moveTarget - self.unit.Position).normalized; self.moveTcs = new ETTaskCompletionSource(); self.startTime = TimeHelper.Now(); float time = distance / speed; self.needTime = (long)(time * 1000); self.endTime = self.startTime + self.needTime; M2C_Pushback m2C = new M2C_Pushback(); m2C.Frame = Game.Scene.GetComponent <UnitStateMgrComponent>().currFrame; m2C.Id = self.unit.Id; m2C.MoveTarget = self.moveTarget.ToV3Info(); m2C.Time = time; ETHotfix.MessageHelper.Broadcast(m2C); Log.Debug("击退,击退用时" + time); return(self.moveTcs.Task); }
public static void FixedUpdate(this CharacterMoveComponent self) { if (self.moveTcs != null) { var property_CharacterState = self.unit.GetComponent <CharacterStateComponent>(); if (property_CharacterState.Get(SpecialStateType.CantDoAction)) { Log.Debug("角色无法行动!"); self.OnMoveEnd(); return; } long timeNow = TimeHelper.Now(); if (timeNow >= self.endTime || Vector3.Distance(self.unit.Position, self.moveTarget) < 0.01f) { self.OnMoveEnd(); return; } if (self.moveType == MoveType.Move) { self.unit.Rotation = Quaternion.Slerp(self.unit.Rotation, self.aimRotation, EventSystem.FixedUpdateTime * 15); } float amount = (timeNow - self.startTime) * 1f / self.needTime; self.unit.Position = Vector3.Lerp(self.startPosition, self.moveTarget, amount); } }
public static void OnMoveEnd(this CharacterMoveComponent self) { //var Body = GetParent<Unit>().GetComponent<P2DBodyComponent>().body; //Body.SetLinearVelocity(System.Numerics.Vector2.Zero); switch (self.moveType) { case MoveType.Move: break; case MoveType.PushedBack: break; case MoveType.Launched: break; case MoveType.Floated: break; case MoveType.Sunk: break; } var t = self.moveTcs; self.moveTcs = null; t?.SetResult(); }
public async void ActionHandle(BuffHandlerVar buffHandlerVar) { #if !SERVER if (Game.Scene.GetComponent <GlobalConfigComponent>().networkPlayMode) { //联网模式是服务器发消息,才执行 return; } #endif try { Buff_Move buff_Move = (Buff_Move)buffHandlerVar.data; if (!buffHandlerVar.GetBufferValue(out BufferValue_Pos bufferValue_Pos)) { Log.Error("给移动的Buff提供的参数不包含目标位置! " + buffHandlerVar.skillId); return; } if (!buffHandlerVar.GetBufferValue(out BufferValue_TargetUnits bufferValue_TargetUnits)) { Log.Error("给移动的Buff提供的参数不包含移动的目标! " + buffHandlerVar.skillId); return; } foreach (var v in bufferValue_TargetUnits.targets) { if (buff_Move.resetDir) { v.Rotation = Quaternion.LookRotation(bufferValue_Pos.aimPos - v.Position, Vector3.up); } Vector3 aimPos = bufferValue_Pos.aimPos; //TODO: 下面的移动都不严谨, 要做位移的合法性检查 if (buff_Move.flash || buff_Move.moveDuration == 0) { //需要检查目标位置是否能瞬移过去,然后瞬移不过去的时候,找到最合理的一个点瞬移过去 //瞬移 v.Position = aimPos; } else { //需要检查目标位置是否能移动过去,如果不行的话,就不位移了 CharacterMoveComponent characterMoveComponent = buffHandlerVar.source.GetComponent <CharacterMoveComponent>(); float moveSpeed = Vector3.Distance(v.Position, aimPos) / buff_Move.moveDuration; await characterMoveComponent.MoveTo(aimPos, moveSpeed); } } } catch (Exception e) { Log.Error(e.ToString()); } }
async ETVoid PushBack(Unit unit, Vector3 target, Buff_PushBack buff) { CharacterMoveComponent characterMoveComponent = unit.GetComponent <CharacterMoveComponent>(); float moveSpeed = Vector3.Distance(unit.Position, target) / buff.moveDuration; CharacterStateComponent characterStateComponent = unit.GetComponent <CharacterStateComponent>(); characterStateComponent.Set(SpecialStateType.NotInControl, true); //击退效果尝试打断. 以后这里要传参数,代表打断来源,然后下面这个方法里判断来源和技能允许被打断的类型 unit.GetComponent <ActiveSkillComponent>().Interrupt(TypeOfInterruption.FromNotInControl); await characterMoveComponent.PushBackedTo(target, moveSpeed); characterStateComponent.Set(SpecialStateType.NotInControl, false); }
static void RaycastPushBackPos(this CharacterMoveComponent self, ref Vector3 moveTarget) { RayCastStaticObjCallback rayCast = new RayCastStaticObjCallback(); Game.Scene.GetComponent <PhysicWorldComponent>().world.RayCast(rayCast, self.unit.Position.ToVector2(), moveTarget.ToVector2()); if (rayCast.Hit) { var dir = moveTarget - self.unit.Position; moveTarget = (rayCast.Point - dir.normalized.ToVector2() * self.unit.GetComponent <P2DBodyComponent>().fixture.Shape.Radius).ToVector3(moveTarget.y); Log.Debug(string.Format("射线检测点+{0} ", moveTarget)); } }
protected override async void Run(ETModel.Session session, M2C_Pushback message) { Unit unit = UnitComponent.Instance.Get(message.Id); CharacterMoveComponent characterMoveComponent = unit.GetComponent <CharacterMoveComponent>(); float moveSpeed = Vector3.Distance(unit.Position, message.MoveTarget.ToV3()) / message.Time; CharacterStateComponent characterStateComponent = unit.GetComponent <CharacterStateComponent>(); characterStateComponent.Set(SpecialStateType.NotInControl, true); await characterMoveComponent.PushBackedTo(message.MoveTarget.ToV3(), moveSpeed); characterStateComponent.Set(SpecialStateType.NotInControl, false); }
public static void SyncStateFrame(this UnitStateComponent self, Move move) { // 获取输出数据,传入CharacterMovementComponet // 服务器上要有一份同样的角色移动数据,用于服务端的各种计算与判断 CharacterMoveComponent characterMoveComponent = self.unit.GetComponent <CharacterMoveComponent>(); characterMoveComponent.MoveAsync(move); // 向附近玩家广播targetMove,更新preSendMsgFrame if (self.preSendMsgFrame != self.currFrame) { MapHelper.BroadcastMove(characterMoveComponent.targetMove, self.unit); self.preSendMsgFrame = self.currFrame; } }
public static void MoveAsync(this CharacterMoveComponent self, Move target) { // 验证移动是否有效,延迟补偿等 // ... // 验证通过或不需补偿,更新targetMove,获得服务器currFrame self.targetMove = target; int key = Game.Scene.GetComponent <UnitStateMgrComponent>().currFrame; self.targetMove.frame = key; self.unit.GetComponent <UnitStateComponent>().currFrame = key; // 获得新的移动速度 // ... // 暂时使用baseMoveSpeed,实际上要加上buff,技能,装备,坐骑能产生的速度,这是一个变化的数值 self.MoveTo(self.baseMoveSpeed); }
public static void FixedUpdate(this CharacterMoveComponent self) { long timeNow = TimeHelper.Now(); // 移动距离过大不进行插值移动 float distance = Vector3.Distance(self.unit.Position, self.targetPosition); if (distance > 15) { return; } // 目标move的位置与角度插值 self.unit.Rotation = Quaternion.Slerp(self.unit.Rotation, self.yEuler, EventSystem.FixedUpdateTime * 15); float amount = (timeNow - self.startTime) * 1f / self.needTime; self.unit.Position = Vector3.Lerp(self.startPosition, self.targetPosition, amount); }
public static async ETVoid MoveAsync(this CharacterMoveComponent self, List <Vector3> path) { if (path.Count == 0) { return; } if (self.moveTcs != null) { self.moveTcs = null; } float speed = self.unit.GetComponent <NumericComponent>().GetAsFloat(NumericType.MoveSpeed); // 第一个点是unit的当前位置,所以不用发送 for (int i = 1; i < path.Count; ++i) { Vector3 v3 = path[i]; await self.MoveTo(v3, speed); } }
public static ETTask MoveTo(this CharacterMoveComponent self, Vector3 target, float speed) { self.moveTarget = target; float distance = Vector3.Distance(self.unit.Position, self.moveTarget); if (distance < 0.02f) { return(ETTask.CompletedTask); } self.moveType = MoveType.Move; self.moveSpeed = speed; self.moveTcs = new ETTaskCompletionSource(); self.startPosition = self.unit.Position; self.moveDir = (self.moveTarget - self.unit.Position).normalized; self.aimRotation = Quaternion.LookRotation(self.moveDir, Vector3.up); self.startTime = TimeHelper.Now(); float time = distance / speed; self.needTime = (long)(time * 1000); self.endTime = self.startTime + self.needTime; return(self.moveTcs.Task); }
public static void MoveTo(this CharacterMoveComponent self, float speed) { self.yRotation = self.targetMove.yRotation; self.yEuler = Quaternion.Euler(new Vector3(0, self.targetMove.yRotation, 0)); // 移动距离过大或过小都不更新移动位置 float distance = Vector3.Distance(self.unit.Position, self.targetMove.position); if (distance < 0.02f || distance > 15) { return; } self.startPosition = self.unit.Position; self.targetPosition = self.targetMove.position; self.moveSpeed = speed; // 计算移动到新位置需要的与结束的时间点 self.startTime = TimeHelper.Now(); float time = distance / speed; self.needTime = (long)(time * 1000); self.endTime = self.startTime + self.needTime; }