///<summary> /// 副本内怪物构建流程 /// 单人副本通过Scene配置来产生怪物 /// 多人副本通过服务器推送消息产生怪物 /// </summary> //TODO: 多人副本怪物产生机制 public void CreateMonster(UnitData unitData, SpawnTrigger spawn) { if (WorldManager.worldManager.station == WorldManager.WorldStation.Enter) { Log.Sys("UnityDataIs " + unitData.ID); if (unitData.Config == null) { Debug.LogError("NotFoundMonster " + unitData.ID); return; } Log.Sys("Create Monster Unit " + unitData.name); var Resource = Resources.Load <GameObject> (unitData.ModelName); //本地怪兽不需要Player信息 GameObject g = Instantiate(Resource) as GameObject; NpcAttribute npc = NGUITools.AddMissingComponent <NpcAttribute> (g); npc.spawnTrigger = spawn.gameObject; var type = Type.GetType("ChuMeng." + unitData.AITemplate); var t = typeof(NGUITools); var m = t.GetMethod("AddMissingComponent"); Log.AI("Monster Create Certain AI " + unitData.AITemplate + " " + type); var geMethod = m.MakeGenericMethod(type); //var petAI = geMethod.Invoke(null, new object[] { g });// as AIBase; g.transform.parent = transform; g.tag = GameTag.Enemy; g.layer = (int)GameLayer.Npc; spawn.FirstMonster = g; var netView = g.GetComponent <KBEngine.KBNetworkView> (); netView.SetID(new KBEngine.KBViewID(myPlayer.ID, myPlayer)); netView.IsPlayer = false; npc.SetObjUnitData(unitData); AddObject(netView.GetServerID(), netView); float angle = UnityEngine.Random.Range(0, 360); Vector3 v = Vector3.forward; v = Quaternion.Euler(new Vector3(0, angle, 0)) * v; float rg = UnityEngine.Random.Range(0, spawn.Radius); npc.transform.position = spawn.transform.position + v * rg; if (unitData.IsElite) { npc.transform.localScale = new Vector3(2, 2, 2); } BattleManager.battleManager.AddEnemy(npc.gameObject); npc.SetDeadDelegate = BattleManager.battleManager.EnemyDead; //npc.Level = spawn.Level; } else { cacheMonster.Add(new MonsterInit(unitData, spawn)); } }
//TODO:检测一些事件 然后进行状态切换 //获得对应注册哪些事件, 就检测哪些事件? //只有状态切换成功才回 CheckEvent 返回true protected bool CheckEvent() { if (CheckBaseEvent()) { return(true); } var msg = GetEvent().NextMsg(); lastMsg = msg; if (msg != null) { Log.AI("CheckEventIs " + msg.type); if (msg.type == MyAnimationEvent.MsgType.IDLE) { return(aiCharacter.ChangeState(AIStateEnum.IDLE)); } else if (msg.type == MyAnimationEvent.MsgType.DoSkill) { var isBaseAttack = GetSkill().IsDefaultSkill(msg.skillData); Log.AI("CheckCastSkill " + isBaseAttack); if (isBaseAttack) { Log.AI("CheckAttack " + msg.type); var skillPart = GetSkill(); skillPart.SetDefaultActive(); return(aiCharacter.ChangeState(AIStateEnum.COMBAT)); } else { Log.AI("Enter CastSkill"); var skillPart = GetSkill(); skillPart.SetActiveSkill(msg.skillData); return(aiCharacter.ChangeState(AIStateEnum.CAST_SKILL)); } } else if (msg.type == MyAnimationEvent.MsgType.STUNNED) { return(aiCharacter.ChangeState(AIStateEnum.Stunned)); } else if (msg.type == MyAnimationEvent.MsgType.EXIT_STUNNED) { return(aiCharacter.ChangeState(AIStateEnum.IDLE)); } else if (msg.type == MyAnimationEvent.MsgType.DEAD) { return(aiCharacter.ChangeState(AIStateEnum.DEAD)); } else if (msg.type == MyAnimationEvent.MsgType.JUMP) { Log.AI("EnterJumpStateNow"); return(aiCharacter.ChangeState(AIStateEnum.JUMP)); } else { return(CheckEventOverride(msg)); } } return(false); //return CheckAttackEvent (); }
IEnumerator FindTarget() { while (!quit) { if (CheckEvent()) { yield break; } Log.AI("sentry idle find target "); var enemy = NearestEnemy(); if (enemy != null) { aiCharacter.SetEnemy(enemy); var dir = enemy.transform.position - GetAttr().transform.position; var qua = Quaternion.FromToRotation(Vector3.forward, new Vector3(dir.x, 0, dir.z)); Log.AI("sentry find target " + enemy); //根据攻击目标调整 攻击方向 GetAttr().transform.localRotation = qua; GetSkill().SetDefaultActive(); //发动技能攻击 aiCharacter.ChangeState(AIStateEnum.CAST_SKILL); yield break; } yield return(null); } Log.AI("Idle state Logic quit ?"); }
/// <summary> /// 初始化特定事件发生时候的技能层 /// 或者 创建孩子技能 /// </summary> /// <param name="item">Item.</param> /// <param name="evt">Evt.</param> void InitLayout(SkillDataConfig.EventItem item, MyEvent evt) { if (item.layout != null) { var g = Instantiate(item.layout) as GameObject; g.transform.parent = transform; //陷阱粒子效果 位置是 当前missile爆炸的位置 //瞬间调整SkillLayout的方向为 攻击者的正方向 g.transform.localPosition = InitPos; var y = attacker.transform.localRotation.eulerAngles.y; g.transform.localRotation = Quaternion.Euler(new Vector3(0, y, 0)); g.transform.localScale = Vector3.one; var runner = g.AddComponent <SkillLayoutRunner>(); runner.stateMachine = this; runner.Event = item; runner.triggerEvent = evt; allRunners.Add(g); Log.AI("SkillLayout " + item.layout.name); } else if (item.childSkillId != 0 && item.childSkillId != -1) { Log.AI("Create Child Skill " + item.childSkillId); SkillLogic.CreateSkillStateMachine(attacker, Util.GetSkillData(item.childSkillId, 1), evt.missile.position); } }
IEnumerator Birth() { if (CheckAni("spawn")) { SetAttrState(CharacterState.Birth); PlayAni("spawn", 2, WrapMode.Once); Log.AI("spawn particle is " + GetAttr().ObjUnitData.SpawnEffect); if (GetAttr().ObjUnitData.SpawnEffect != "") { GameObject g = GameObject.Instantiate(Resources.Load <GameObject>(GetAttr().ObjUnitData.SpawnEffect)) as GameObject; //g.transform.position = GetAttr().transform.position; g.transform.parent = GetAttr().transform; g.transform.localPosition = Vector3.zero; g.transform.localRotation = Quaternion.identity; g.transform.localScale = Vector3.one; } yield return(GetAttr().StartCoroutine(Util.WaitForAnimation(GetAttr().animation))); SetAttrState(CharacterState.Idle); aiCharacter.SetIdle(); } birthYet = true; Log.AI("Birth finish " + GetAttr().gameObject); }
public static SkillDataConfig GetSkillInfo(SkillData activeSkill) { Log.AI("active skillName " + activeSkill.SkillName); Log.AI("Get Skill Template is " + activeSkill.template); if (activeSkill.template != null) { if (!skillConfigCache.ContainsKey(activeSkill.template) || skillConfigCache[activeSkill.template] == null) { var tem = Resources.Load <GameObject>("skills/" + activeSkill.template); if (tem == null) { Debug.LogError("NotFind Template " + activeSkill.template); return(null); } else { //切换场景不要摧毁对象 var go = GameObject.Instantiate(tem) as GameObject; GameObject.DontDestroyOnLoad(go); skillConfigCache.Add(activeSkill.template, go); } } return(skillConfigCache[activeSkill.template].GetComponent <SkillDataConfig>()); } return(null); }
IEnumerator CastSkill(GameObject targetPlayer) { GetAttr().GetComponent <SkillInfoComponent> ().SetRandomActive(); var activeSkill = GetAttr().GetComponent <SkillInfoComponent>().GetActiveSkill(); var skillStateMachine = SkillLogic.CreateSkillStateMachine(GetAttr().gameObject, activeSkill.skillData, GetAttr().transform.position, targetPlayer); Log.AI("Skill SetAni " + activeSkill.skillData.AnimationName); var realAttackTime = activeSkill.skillData.AttackAniTime / GetAttr().GetSpeedCoff(); var rate = GetAttr().animation[activeSkill.skillData.AnimationName].length / realAttackTime; SetAni(activeSkill.skillData.AnimationName, rate, WrapMode.Once); var physic = GetAttr().GetComponent <PhysicComponent>(); while (GetAttr().animation.isPlaying&& !quit) { if (CheckEvent()) { break; } //自动向目标旋转 Vector3 dir = targetPlayer.transform.position - GetAttr().transform.position; dir.y = 0; var newDir = Vector3.Slerp(GetAttr().transform.forward, dir, Time.deltaTime * FastRotateSpeed); physic.TurnTo(newDir); yield return(null); } skillStateMachine.Stop(); }
/// <summary> /// 生成子弹同时附着上当前Runner所对应事件的Affix /// </summary> /// <param name="deg">Deg.</param> void MakeMissile(float deg) { Log.AI("bullet degree " + deg); var b = new GameObject("bullet_" + Missile.name); var bullet = b.AddComponent <Bullet>(); bullet.OffsetPos = Position; GameObject attacker = null; if (runner != null) { bullet.skillData = runner.stateMachine.skillFullData.skillData; attacker = runner.stateMachine.attacker; bullet.attacker = runner.stateMachine.attacker; bullet.runner = runner; } bullet.missileData = Missile; bullet.transform.parent = ObjectManager.objectManager.transform; var playerForward = Quaternion.Euler(new Vector3(0, 0 + attacker.transform.rotation.eulerAngles.y, 0)); var bulletForward = Quaternion.Euler(new Vector3(0, deg + attacker.transform.eulerAngles.y, 0)); bullet.transform.localPosition = attacker.transform.localPosition + playerForward * Position; bullet.transform.localRotation = bulletForward; }
IEnumerator MoveAlongPoint() { var physic = GetAttr().GetComponent <PhysicComponent>(); while (!quit) { if (CheckEvent()) { break; } var nextTP = curTracePoint; var pos = GetAttr().transform.position; var tarPos = tracePoints [nextTP].transform.position; var dis = Util.XZSqrMagnitude(pos, tarPos); Log.AI("Move Target Distance " + tarPos + " dis " + dis + " pos " + pos); //足够靠近目标点了 if (dis < 2f) { curTracePoint++; curTracePoint %= tracePoints.Count; } else { var dir = tarPos - pos; dir.y = 0; dir.Normalize(); physic.TurnTo(dir); physic.MoveSpeed(dir * WalkSpeed); } yield return(null); } }
/// <summary> ///检测附近如果有相关的机关则引爆 /// 当落到地面的时候 /// </summary> void CheckNearByBomb() { var sp = gameObject.AddComponent <SphereCollider>(); sp.isTrigger = true; sp.radius = 4; var col = Physics.OverlapSphere(transform.position, 4, 1 << (int)GameLayer.Npc); var goDie = false; var meType = attribute.ObjUnitData.ID; foreach (var c in col) { var npc = c.GetComponent <NpcAttribute>(); if (npc.ObjUnitData.ID == meType && npc.GetLocalId() != attribute.GetLocalId() && !npc.IsDead) { var evt = npc.GetComponent <MyAnimationEvent>(); var et = new MyAnimationEvent.Message(); et.type = MyAnimationEvent.MsgType.BOMB; evt.InsertMsg(et); goDie = true; } } Log.AI("CheckNearBy ToBomb " + goDie + " col " + col.Length + " name " + gameObject.name); if (goDie) { //GetComponent<MyAnimationEvent>().timeToDead = true; var evt = new MyAnimationEvent.Message(); evt.type = MyAnimationEvent.MsgType.BOMB; GetComponent <MyAnimationEvent>().InsertMsg(evt); } }
public SimpleJSON.JSONArray GetSkillList() { if (skList == null) { Log.AI("MonsterConfig " + config.name + " " + config.skillList); var p = SimpleJSON.JSON.Parse(config.skillList); if (p != null) { skList = p.AsArray; int min = 0; foreach (SimpleJSON.JSONNode j in skList) { if (string.IsNullOrEmpty(j ["ignore"].Value)) { j ["min"].AsInt = min; j ["max"].AsInt = min + j ["chance"].AsInt; min += j ["chance"].AsInt; } } } else { skList = new SimpleJSON.JSONArray(); } } return(skList); }
public override void EnterState() { Log.AI("Enter Player Move State"); base.EnterState(); SetAttrState(CharacterState.Running); aiCharacter.SetRun(); }
void MakeMissile(int deg) { Log.AI("bullet degree " + deg); var offX = new float[] { 0, -offSetX, offSetX, }; var b = new GameObject("bullet_" + Missile.name); var bullet = b.AddComponent <Bullet>(); bullet.OffsetPos = Position; GameObject attacker = null; if (runner != null) { bullet.skillData = runner.stateMachine.skillFullData.skillData; attacker = runner.stateMachine.attacker; bullet.attacker = runner.stateMachine.attacker; bullet.runner = runner; } bullet.missileData = Missile; bullet.transform.parent = ObjectManager.objectManager.transform; bullet.transform.localPosition = attacker.transform.localPosition + new Vector3(offX[deg], 0, 0); bullet.transform.localRotation = attacker.transform.localRotation; }
/// <summary> ///怪物随机一个技能 /// </summary> public void SetRandomActive() { Log.AI("SetRandomActive " + gameObject.name); var rd = UnityEngine.Random.Range(0, 100); var skList = attribute.ObjUnitData.GetSkillList(); Log.AI("skList is " + skList.Count); foreach (SimpleJSON.JSONNode j in skList) { if (string.IsNullOrEmpty(j ["ignore"].Value) && rd >= j ["min"].AsInt && rd < j ["max"].AsInt) { var tp = Type.GetType("ChuMeng.Skill" + j ["id"].AsInt); if (tp == null) { activeSkill = Util.GetSkillData(j ["id"].AsInt, j ["level"].AsInt); Log.AI("Set Random Skill Active " + activeSkill.SkillName); return; } else { //技能有额外的条件需要检测 var sk = (SkillObj)Activator.CreateInstance(tp); var ret = sk.CheckCondition(gameObject); Log.AI("CheckSkillCondition " + j ["id"].Value); if (ret) { activeSkill = Util.GetSkillData(j ["id"].AsInt, j ["level"].AsInt); Log.AI("Set Random Skill Active " + activeSkill.SkillName); return; } } } } SetDefaultActive(); }
public override IEnumerator RunLogic() { Log.AI("Check Animation " + GetAttr().animation.IsPlaying(activeSkill.skillData.AnimationName)); float passTime = 0; var animation = GetAttr().animation; var attackAniName = activeSkill.skillData.AnimationName; while (!quit) { if (CheckEvent()) { yield break; } if (skillStateMachine.skillDataConfig.animationLoop) { if (passTime >= skillStateMachine.skillDataConfig.attackDuration) { break; } } else { if (passTime >= animation [attackAniName].length * 0.8f / animation [attackAniName].speed) { break; } } passTime += Time.deltaTime; yield return(null); } Log.AI("Stop SkillState "); skillStateMachine.Stop(); aiCharacter.ChangeState(AIStateEnum.IDLE); }
private void PerformChangeState() { if (requestedNewState == null) { throw new ArgumentNullException("requestedNewState"); } if (requestedNewState.Owner == null) { throw new ArgumentNullException("requestedNewState.owner"); } Log.AI(owner.ToString(), "Changing state to " + requestedNewState.ToString()); State previousState = CurrentState; Log.AI(owner.ToString(), "Previous state was " + (previousState != null ? previousState.ToString() : "null")); if (CurrentState != null) { CurrentState.Leave(); } CurrentState = requestedNewState; requestedNewState = null; if (CurrentState.Enter() == false) { CurrentState = null; Log.AI(owner.ToString(), "Failed to enter new state. Reverting to previous state."); ChangeState(previousState); } }
void MakeMonster() { Affix af = null; if (runner.Event.affix.target == Affix.TargetType.Pet) { af = runner.Event.affix; } var pos = gameObject.transform.position + runner.stateMachine.InitPos; if (runner.stateMachine.attacker != null) { var npc = runner.stateMachine.attacker.GetComponent <NpcAttribute>(); if (npc.spawnTrigger != null) { var c = npc.spawnTrigger.transform.childCount; if (c > 0) { var rd = Random.Range(0, c); var child = npc.spawnTrigger.transform.GetChild(rd); pos = child.transform.position; Log.AI("CreateMonster Use Dynamic Pos " + pos + " index " + rd); } } } ObjectManager.objectManager.CreatePet(MonsterId, runner.stateMachine.attacker, af, pos); }
public void EnterJump() { Log.AI("EnterJump"); var msg = new Message(); msg.type = MsgType.JUMP; InsertMsg(msg); }
public void OnInterActive() { Log.AI("TalkToMe " + TalkToMe); if (TalkToMe != null) { TalkToMe(); } }
// Use this for initialization void Start() { var runner = transform.parent.GetComponent <SkillLayoutRunner> (); runner.DoDamage(runner.stateMachine.target); Log.AI("HurtDirect " + runner.stateMachine.target.name); }
//注册事件处理 void RegEvent() { Log.AI("regevent is " + regEvt.Count); foreach (MyEvent.EventType e in regEvt) { MyEventSystem.myEventSystem.RegisterLocalEvent(ownerLocalId, e, OnEvent); } }
//需要等待SKillStateMachine 设置Rotation完成 之后才调整当前的粒子参数 //动画等配置完成之后 启动粒子 void Start() { var el = GetComponent <EffectLayer> (); oldPos = el.EmitPoint; initDeg = new Vector2(el.OriRotationMin, el.OriRotationMax); Log.AI("Adjust Effect Layer emitPoint and rotation " + gameObject.name + " "); }
/// <summary> /// 进入STUNNED状态不出来了 如果死亡也会出来 /// </summary> public override void OnActive() { Log.AI("Stunned Buff Active"); var ani = obj.GetComponent <MyAnimationEvent> (); var msg = new MyAnimationEvent.Message(MyAnimationEvent.MsgType.STUNNED); ani.InsertMsg(msg); }
public override IEnumerator RunLogic() { if (!birthYet) { yield return(GetAttr().StartCoroutine(Birth())); } aiCharacter.ChangeState(AIStateEnum.MOVE); Log.AI("State Logic Over " + type); }
public override void EnterState() { base.EnterState(); Log.AI("Enter Skill State "); //启动技能状态机 启动动画 activeSkill = GetAttr().GetComponent <SkillInfoComponent> ().GetActiveSkill(); skillStateMachine = SkillLogic.CreateSkillStateMachine(GetAttr().gameObject, activeSkill.skillData, GetAttr().transform.position); //GetAttr ().GetComponent<AnimationController> ().SetAnimationSampleRate (100); }
} // AttackMove(x, y) /// <summary> /// Orders the entity to attack the given target /// </summary> /// <param name="Target">The entity to attack</param> public void Attack(Entity Target) { if (CanAttack) { Log.AI(this.ToString(), "Attacking " + Target.Name + Target.UniqueID); StateMachine.ChangeState(new StateAttack(this, Target)); } } // Attack(Target)
public void AddState(AIState state) { if (stateMap.ContainsKey(state.type)) { Log.AI("Error Has SameState In Map " + state.type + " " + stateMap[state.type] + " " + state); } stateMap [state.type] = state; state.SetChar(this); }
} // Idle() /// <summary> /// Orders the entity to move to the coordinates and attack everything it passes on its way to the target /// </summary> /// <param name="x">Target X tile</param> /// <param name="y">Target Y tile</param> public void AttackMove(int x, int y) { if (CanMove) { Log.AI(this.ToString(), "Moving to " + x + "," + y + " and attacking all enemies on the way!"); StateMachine.ChangeState(new StateAttackMove(this, x, y)); } } // AttackMove(x, y)
} // Attack(Target) /// <summary> /// Orders the unit to move to the coordinates ignoring all enemy entities on the way. /// </summary> /// <param name="x">Target X tile</param> /// <param name="y">Target Y tile</param> public void MoveTo(int x, int y) { if (CanMove) { Log.AI(this.ToString(), "Moving to " + x + "," + y); StateMachine.ChangeState(new StateMove(this, x, y)); } } // MoveTo(x, y)
public override IEnumerator RunLogic() { if (!birthYet) { yield return(GetAttr().StartCoroutine(Birth())); } yield return(GetAttr().StartCoroutine(FindTarget())); Log.AI("State Logic Over " + type); }