static public List <List <uint> > GetEntitiesInRange(Vector3 position, float radius, float offsetX = 0, float offsetY = 0, float angleOffset = 0, LayerMask layerMask = LayerMask.Monster | LayerMask.Character | LayerMask.Trap) { List <List <uint> > list = new List <List <uint> >(); List <uint> listDummy = new List <uint>(); List <uint> listMonster = new List <uint>(); List <uint> listPlayer = new List <uint>(); List <uint> listMercenary = new List <uint>(); if (!MogoWorld.Entities.ContainsKey(MogoWorld.thePlayer.ID)) { MogoWorld.Entities.Add(MogoWorld.thePlayer.ID, MogoWorld.thePlayer); } //遍历entities foreach (KeyValuePair <uint, Mogo.Game.EntityParent> pair in MogoWorld.Entities) { EntityParent entity = pair.Value; if (!entity.Transform) { continue; } if ((1 << entity.Transform.gameObject.layer & (int)layerMask) == 0) { continue; } float entityRadius = ((float)entity.GetIntAttr("scaleRadius")) / 100f; if ((position - entity.Transform.position).magnitude > radius + entityRadius) { continue; } if (pair.Value is EntityDummy) { listDummy.Add(pair.Key); } else if (pair.Value is EntityMonster) { listMonster.Add(pair.Key); } else if (pair.Value is EntityPlayer) { listPlayer.Add(pair.Key); } else if (pair.Value is EntityMercenary) { listMercenary.Add(pair.Key); } } MogoWorld.Entities.Remove(MogoWorld.thePlayer.ID); list.Add(listDummy); list.Add(listMonster); list.Add(listPlayer); list.Add(listMercenary); return(list); }
// 状态处理 public void Process(EntityParent theOwner, params System.Object[] args) { MogoMotor theMotor = theOwner.motor; if (theOwner is EntityMonster || (theOwner is EntityPlayer && !(theOwner is EntityMyself))) { theOwner.ApplyRootMotion(false); theOwner.SetSpeed(1); theMotor.SetSpeed(0.4f); //服务器没有同步其他玩家的速度,这里暂时硬编码处理, //待确定其他玩家与怪物移动位移的控制方案再修改(程序控制还是动作位移) if (theOwner.speed == 0) { //theMotor.SetExrtaSpeed(6); } else { theMotor.SetExrtaSpeed(theOwner.speed); } return; } else if (theOwner is EntityDummy || theOwner is EntityMercenary) { theOwner.ApplyRootMotion(false); //theOwner.SetSpeed(1); theMotor.SetSpeed(0.4f * theOwner.aiRate); theMotor.SetExrtaSpeed(theOwner.GetIntAttr("speed") * 0.01f * theOwner.blackBoard.speedFactor * theOwner.aiRate); } else { theOwner.ApplyRootMotion(true); // theOwner.SetSpeed(1); theMotor.SetExrtaSpeed(5); theMotor.SetSpeed(0.4f); } theMotor.isMovable = true; }
// 状态处理 public void Process(EntityParent theOwner, params Object[] args) { if (theOwner == null || theOwner.Transform == null) { return; } if (theOwner.IsDeath()) { return; } if (args.Length < 2) { LoggerHelper.Error("error skill id"); return; } int hitActionID = (int)(args[0]); uint attackID = (uint)(args[1]); EntityParent attacker = null; if (MogoWorld.Entities.ContainsKey(attackID)) { attacker = MogoWorld.Entities[attackID]; } if (attackID == MogoWorld.thePlayer.ID) { attacker = MogoWorld.thePlayer; } if (theOwner.motor != null) { theOwner.motor.enableStick = false; } //if (attacker == null) //{//没有受击者 // return; //} List <int> hitAction = SkillAction.dataMap[hitActionID].hitAction; if (hitAction == null || hitAction.Count == 0) { return; } int action = Utils.Choice <int>(hitAction); if (action == ActionConstants.HIT) { HitActionRule(theOwner, action, hitActionID); return; } if (!(theOwner is EntityPlayer)) { if (((theOwner is EntityMonster) && theOwner.GetIntAttr("notTurn") == 0) || theOwner is EntityDummy) { if (theOwner.motor == null) { return; } if (attacker != null && attacker.Transform != null) { theOwner.motor.SetTargetToLookAt(attacker.Transform.position); } } } else { if (theOwner.Transform == null) { return; } theOwner.preQuaternion = theOwner.Transform.localRotation; if (attacker != null && attacker.Transform != null) { theOwner.motor.SetTargetToLookAt(attacker.Transform.position); } } HitActionRule(theOwner, action, hitActionID); }
/// <summary> /// 在角色当前朝向的半径radius,扇形角度angle内,在对人物朝向进行最小角度的调整其中一个怪物。 /// 如果区域内无怪,则不调整 /// </summary> /// <param name="t"></param> /// <param name="radius"></param> /// <param name="angle"></param> /// <param name="layerMask"></param> static public void LookAtTargetInRange(this Transform t, float radius, float angle, LayerMask layerMask = LayerMask.Monster | LayerMask.Character | LayerMask.Trap) { Vector3 targetPos = Vector3.zero; float angleMax = Mathf.Infinity; bool isFindSome = false; //遍历entities foreach (KeyValuePair <uint, Mogo.Game.EntityParent> pair in MogoWorld.Entities) { EntityParent entity = pair.Value; if (entity.curHp <= 0) { continue; } if (entity.IsDeath()) { continue; } //if (entity is EntityPlayer) continue; if (entity.m_factionFlag == MogoWorld.thePlayer.m_factionFlag) { continue; } if (entity.Transform == null || t == null) { continue; } if ((1 << entity.Transform.gameObject.layer & (int)layerMask) == 0) { continue; } float entityRadius = ((float)entity.GetIntAttr("scaleRadius")) / 100f; if ((t.position - entity.Transform.position).magnitude > radius + entityRadius) { continue; } //得到切线与(目标物体到人物线)的夹角a float a = Mathf.Atan(entityRadius / (entity.Transform.position - t.position).magnitude); //得到目标点与人物正前方的夹角b float b = Vector3.Angle((entity.Transform.position - t.position), t.forward); //判断b - a 是否在 angle/2内 if ((b - a) > angle / 2) { continue; } //Vector3 tempDir = new Vector3(-t.forward.z, 0, t.forward.x).normalized; //Vector3 lineLeft = Vector3.Slerp(t.forward, tempDir, (angle / (2 * 90f))); //Vector3 lineRight = Vector3.Slerp(t.forward, -tempDir, (angle / (2 * 90f))); //if ((GetDisBetweenLineAndPoint(lineLeft, t.position) > entityRadius || GetDisBetweenLineAndPoint(lineRight, t.position) > entityRadius) // && Vector3.Angle((entity.Transform.position - t.position), t.forward) > (angle / 2f)) continue; //if (Vector3.Angle((entity.Transform.position - t.position), t.forward) > (angle / 2f)) continue; isFindSome = true; if ((b - a) < angleMax) { angleMax = b - a; targetPos = pair.Value.Transform.position; } } if (isFindSome) { t.LookAt(new Vector3(targetPos.x, t.transform.position.y, targetPos.z)); } }
/// <summary> /// 返回角色周围指定扇形范围内的所有对象。 /// </summary> /// <param name="t"></param> /// <param name="radius"></param> /// <param name="angle"></param> /// <param name="layerMask"></param> /// <returns></returns> static public List <List <uint> > GetEntitiesInSector(Matrix4x4 ltwM, Quaternion rotation, Vector3 forward, Vector3 position, float radius, float angle = 180f, float offsetX = 0, float offsetY = 0, float angleOffset = 0, LayerMask layerMask = LayerMask.Monster | LayerMask.Character | LayerMask.Trap) { List <List <uint> > list = new List <List <uint> >(); List <uint> listDummy = new List <uint>(); List <uint> listMonster = new List <uint>(); List <uint> listPlayer = new List <uint>(); List <uint> listMercenary = new List <uint>(); if (!MogoWorld.Entities.ContainsKey(MogoWorld.thePlayer.ID)) { MogoWorld.Entities.Add(MogoWorld.thePlayer.ID, MogoWorld.thePlayer); } Matrix4x4 m = ltwM; Matrix4x4 m1 = new Matrix4x4(); m1.SetRow(0, new Vector4(0, 0, 0, offsetY)); //1 m1.SetRow(1, new Vector4(0, 1, 0, 0)); m1.SetRow(2, new Vector4(0, 0, 0, offsetX)); //-1 m1.SetRow(3, new Vector4(0, 0, 0, 1)); m = m * m1; Vector3 posi = new Vector3(m.m03, m.m13, m.m23); //遍历entities foreach (KeyValuePair <uint, Mogo.Game.EntityParent> pair in MogoWorld.Entities) { EntityParent entity = pair.Value; if (entity.Transform == null) { continue; } if ((1 << entity.Transform.gameObject.layer & (int)layerMask) == 0) { continue; } float entityRadius = ((float)entity.GetIntAttr("scaleRadius")) / 100f; //if ((t.position - entity.Transform.position).magnitude > radius + entityRadius) continue; if ((posi - entity.Transform.position).magnitude > radius + entityRadius) { continue; } //得到切线与(目标物体到人物线)的夹角a //float a = Mathf.Atan(entityRadius / (entity.Transform.position - t.position).magnitude); float a = Mathf.Asin(entityRadius / (entity.Transform.position - posi).magnitude); //得到目标点与人物正前方的夹角b //float b = Vector3.Angle((entity.Transform.position - t.position), t.forward); float b = Vector3.Angle((entity.Transform.position - posi), forward); //判断b - a 是否在 angle/2内 if ((b - a) > angle / 2) { continue; } if (pair.Value is EntityDummy) { listDummy.Add(pair.Key); } else if (pair.Value is EntityMonster) { listMonster.Add(pair.Key); } else if (pair.Value is EntityPlayer) { listPlayer.Add(pair.Key); } else if (pair.Value is EntityMercenary) { listMercenary.Add(pair.Key); } } MogoWorld.Entities.Remove(MogoWorld.thePlayer.ID); list.Add(listDummy); list.Add(listMonster); list.Add(listPlayer); list.Add(listMercenary); return(list); }
/// <summary> /// 返回角色周围指定半径范围内的所有对象。 /// </summary> /// <param name="t"></param> /// <param name="radius"></param> /// <param name="layerMask"></param> /// <returns></returns> static public List <List <uint> > GetEntitiesInRange(Matrix4x4 ltwM, Quaternion rotation, Vector3 forward, Vector3 position, float radius, float offsetX = 0, float offsetY = 0, float angleOffset = 0, LayerMask layerMask = LayerMask.Monster | LayerMask.Character | LayerMask.Trap) { List <List <uint> > list = new List <List <uint> >(); List <uint> listDummy = new List <uint>(); List <uint> listMonster = new List <uint>(); List <uint> listPlayer = new List <uint>(); List <uint> listMercenary = new List <uint>(); if (!MogoWorld.Entities.ContainsKey(MogoWorld.thePlayer.ID)) { MogoWorld.Entities.Add(MogoWorld.thePlayer.ID, MogoWorld.thePlayer); } //float sin = (float)Math.Sin(angleOffset * Math.PI / 180); //float cos = (float)Math.Cos(angleOffset * Math.PI / 180); Matrix4x4 m = ltwM; Matrix4x4 m1 = new Matrix4x4(); m1.SetRow(0, new Vector4(0, 0, offsetY, 0)); //1 m1.SetRow(1, new Vector4(0, 1, 0, 0)); m1.SetRow(2, new Vector4(0, 0, 0, offsetX)); //-1 m1.SetRow(3, new Vector4(0, 0, 0, 1)); m = m * m1; Vector3 posi = new Vector3(m.m03, m.m13, m.m23); //遍历entities foreach (KeyValuePair <uint, Mogo.Game.EntityParent> pair in MogoWorld.Entities) { EntityParent entity = pair.Value; if (!entity.Transform) { continue; } if ((1 << entity.Transform.gameObject.layer & (int)layerMask) == 0) { continue; } float entityRadius = ((float)entity.GetIntAttr("scaleRadius")) / 100f; //if ((t.position - entity.Transform.position).magnitude > radius + entityRadius) continue; if ((posi - entity.Transform.position).magnitude > radius + entityRadius) { continue; } if (pair.Value is EntityDummy) { listDummy.Add(pair.Key); } else if (pair.Value is EntityMonster) { listMonster.Add(pair.Key); } else if (pair.Value is EntityPlayer) { listPlayer.Add(pair.Key); } else if (pair.Value is EntityMercenary) { listMercenary.Add(pair.Key); } } MogoWorld.Entities.Remove(MogoWorld.thePlayer.ID); list.Add(listDummy); list.Add(listMonster); list.Add(listPlayer); list.Add(listMercenary); return(list); }