예제 #1
0
        ///<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));
            }
        }
예제 #2
0
파일: AIState.cs 프로젝트: itcodes/unityRpg
        //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 ();
        }
예제 #3
0
        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 ?");
        }
예제 #4
0
        /// <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);
            }
        }
예제 #5
0
파일: PetIdle.cs 프로젝트: itcodes/unityRpg
        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);
        }
예제 #6
0
 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);
 }
예제 #7
0
        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();
        }
예제 #8
0
        /// <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;
        }
예제 #9
0
        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);
            }
        }
예제 #10
0
파일: PetAI.cs 프로젝트: itcodes/unityRpg
        /// <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);
            }
        }
예제 #11
0
 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);
 }
예제 #12
0
 public override void EnterState()
 {
     Log.AI("Enter Player Move State");
     base.EnterState();
     SetAttrState(CharacterState.Running);
     aiCharacter.SetRun();
 }
예제 #13
0
        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;
        }
예제 #14
0
        /// <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();
        }
예제 #15
0
        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);
        }
예제 #16
0
        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);
            }
        }
예제 #17
0
        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);
        }
예제 #18
0
        public void EnterJump()
        {
            Log.AI("EnterJump");
            var msg = new Message();

            msg.type = MsgType.JUMP;
            InsertMsg(msg);
        }
예제 #19
0
 public void OnInterActive()
 {
     Log.AI("TalkToMe " + TalkToMe);
     if (TalkToMe != null)
     {
         TalkToMe();
     }
 }
예제 #20
0
        // Use this for initialization
        void Start()
        {
            var runner = transform.parent.GetComponent <SkillLayoutRunner> ();

            runner.DoDamage(runner.stateMachine.target);

            Log.AI("HurtDirect " + runner.stateMachine.target.name);
        }
예제 #21
0
 //注册事件处理
 void RegEvent()
 {
     Log.AI("regevent is " + regEvt.Count);
     foreach (MyEvent.EventType e in regEvt)
     {
         MyEventSystem.myEventSystem.RegisterLocalEvent(ownerLocalId, e, OnEvent);
     }
 }
예제 #22
0
        //需要等待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 + " ");
        }
예제 #23
0
파일: Stunned.cs 프로젝트: itcodes/unityRpg
        /// <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);
        }
예제 #24
0
 public override IEnumerator RunLogic()
 {
     if (!birthYet)
     {
         yield return(GetAttr().StartCoroutine(Birth()));
     }
     aiCharacter.ChangeState(AIStateEnum.MOVE);
     Log.AI("State Logic Over " + type);
 }
예제 #25
0
 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);
 }
예제 #26
0
        } // 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)
예제 #27
0
 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);
 }
예제 #28
0
        } // 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)
예제 #29
0
        } // 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)
예제 #30
0
파일: PetIdle.cs 프로젝트: itcodes/unityRpg
        public override IEnumerator RunLogic()
        {
            if (!birthYet)
            {
                yield return(GetAttr().StartCoroutine(Birth()));
            }
            yield return(GetAttr().StartCoroutine(FindTarget()));

            Log.AI("State Logic Over " + type);
        }