Example #1
0
    /// <summary> 순차적으로 영웅 스폰. phase = Battle 이 된 직후 실행 </summary>
    protected IEnumerator SpawnHero(BattleUnit.Team team = BattleUnit.Team.Red, List <BattleHero> list = null)
    {
        List <BattleHero> unitList = list;

        if (unitList == null)
        {
            unitList = battleTeamList[(int)team].actorList;
        }

        if (unitList == null || unitList.Count == 0)
        {
            yield break;
        }

        //스폰될애들 리스트. 순서 무작위로 출현하기 위함
        List <BattleHero> spawnedHeroList = new List <BattleHero>();
        BattleHero        temp            = null;

        while (spawnedHeroList.Count != unitList.Count)
        {
            temp = unitList[UnityEngine.Random.Range(0, unitList.Count)];
            if (!spawnedHeroList.Find(x => x == temp))
            {
                spawnedHeroList.Add(temp);
            }

            yield return(null);
        }

        //하나씩 출현
        for (int i = 0; i < spawnedHeroList.Count; i++)
        {
            //죽은 캐릭터는 스폰하지 않음
            if (spawnedHeroList[i].isDie)
            {
                continue;
            }

            spawnedHeroList[i].gameObject.SetActive(true);

            spawnedHeroList[i].ReGen();

            if (i > 0)
            {
                float dist = spawnedHeroList[i].team == BattleUnit.Team.Red ? -5f : 5f;

                float x = spawnedHeroList[i - 1].transform.position.x + dist;
                spawnedHeroList[i].transform.position = new Vector3(x, spawnedHeroList[i].transform.position.y, spawnedHeroList[i].transform.position.z);

                OrderController oc = spawnedHeroList[i].GetComponent <OrderController>();
                if (oc)
                {
                    oc.UpdateScale();
                }
            }
        }
    }
Example #2
0
    IEnumerator Init(BattleUnit.Team team = BattleUnit.Team.Red, List <HeroData> heroList = null)
    {
        battleTeamList[(int)team].Init(this, team, heroList);

        if (team == BattleUnit.Team.Blue)
        {
            // 적 세팅이 되면 전투 시작
            StartCoroutine(BattleProcess());
        }

        yield return(null);
    }
Example #3
0
    /// <summary> (영웅세팅)해당 클래스에서 가장 처름 시작되야 하는 곳</summary>
    public void Init(BattleGroup _battleGroup, HeroData data, BattleUnit.Team team = Team.Red)
    {
        heroData = data;

        if (_battleGroup != null)
        {
            heroData.battleGroupID = _battleGroup.battleType.ToString();
        }
        else
        {
            heroData.battleGroupID = string.Empty;
        }

        SetBattleGroup(_battleGroup);

        buffController.owner = this;

        if (team != Team.Red)
        {
            data.level = battleGroup.stage;
        }

        //heroDataID = data.id;

        if (team == Team.Red && !isSummonded)
        {
            //ModifiableStat statHPRegen = stats.CreateOrGetStat<ModifiableStat>(StatType.HPRegen);
            //statHPRegen.baseValue = 5;
            //statHPRegen.UpdateModifiers();
        }

        stats.Init();

        heroData.RecalculateStats(team == Team.Red, power);

        //RecalculateBaseParams();

        defaultMoveBehavior       = new HeroMoveBehaviorRun();
        defaultMoveBehavior.owner = this;
        currentMoveBehavior       = defaultMoveBehavior;

        curHP = maxHP;

        transform.localScale = originalScale;

        //보스 사이즈 보정
        orderController.bossModify = isBoss ? 1.3f : 1f;

        UpdateActiveState();

        shakeAmount = 0f;
    }
Example #4
0
    protected void Init(SkillBase skill)
    {
        this.skill = skill;
        this.owner = skill.owner;

        battleGroup = owner.battleGroup;

        if (!battleGroup)
        {
            return;
        }

        //if (skillList == null || skillList.Count == 0)
        //    return;

        enemyList = null;
        allyList  = null;

        BattleUnit.Team team = owner.team;



        if (team == BattleUnit.Team.none)
        {
            return;
        }

        else if (team == BattleUnit.Team.Red)
        {
            allyList  = battleGroup.redTeamList;
            enemyList = battleGroup.blueTeamList;
        }
        else if (team == BattleUnit.Team.Blue)
        {
            allyList  = battleGroup.blueTeamList;
            enemyList = battleGroup.redTeamList;
        }

        isInitialized = true;
    }
Example #5
0
    public override BattleHero CollectTarget(SkillBase skill)
    {
        this.skill = skill;

        //이전 대상이 살아있는데, 검색 주기 전이면 새로 검색 안 함
        if (lastTarget && !skill.skillData.canCastToDeadUnit && lastTarget.isDie)
        {
        }
        else
        {
            if (Time.time < lastCollectTargetTime + refreshInterval)
            {
                return(lastTarget);
            }
        }


        base.CollectTarget(skill);

        if (!owner.battleGroup)
        {
            return(null);
        }

        if (owner.team == BattleUnit.Team.none || enemyList == null || enemyList.Count == 0)
        {
            return(null);
        }

        //도발한 적이 있으면 해당 적을 캐스팅 대상으로 지정
        if (owner.provokeEnemy && owner.provokeEnemy.gameObject.activeSelf)
        {
            if (skill.skillData.canCastToDeadUnit || (!skill.skillData.canCastToDeadUnit && !owner.provokeEnemy.isDie) ||
                skill.skillData.castToDeadUnit == owner.provokeEnemy.isDie)
            {
                return(owner.provokeEnemy);
            }
        }

        nearestEnemy = null;
        float distance = -9999f;

        //BattleHero frontMostEnemy = null;

        BattleUnit.Team team = owner.team;
        //Buff buff = owner.buffController.buffList.Find(x => x.id == "Buff_Succubus_Charm" && x.isActive);
        //if (buff != null)
        //{
        //    if (team != BattleUnit.Team.none)
        //        team = team == BattleUnit.Team.Blue ? BattleUnit.Team.Red : BattleUnit.Team.Blue;
        //    Debug.Log(" 매혹 걸림 캐스팅" + owner.team.ToString() + "->" + team.ToString());
        //}


        //거리 체크 안 해도 되는 조금 빠른 방식
        if (team == BattleUnit.Team.Red)
        {
            BattleHero enemy = owner.battleGroup.frontMostMonster;
            if (enemy == owner as BattleHero)
            {
                //Debug.Log("본인 타겟 " + owner.heroData.heroName);
            }
            else if (enemy && enemy.isFinishSpawned && skill.skillData.castToDeadUnit == enemy.isDie && enemy.transform.position.x > owner.transform.position.x)
            {
                if (skill.skillData.canCastToAir || enemy.skeletonAnimation.transform.localPosition.y < 3f)
                {
                    if (!enemy.isDie || (enemy.isDie && enemy.canResurrect))
                    //if(enemy.transform.position.x - owner.transform.position.x >= skill.skillData.minDistance
                    //    && enemy.transform.position.x - owner.transform.position.x <= skill.skillData.maxDistance)
                    {
                        lastTarget            = enemy;
                        lastCollectTargetTime = Time.time;
                        return(enemy);
                    }
                }
            }
        }
        else if (team == BattleUnit.Team.Blue)
        {
            BattleHero enemy = owner.battleGroup.frontMostHero;
            if (enemy == owner as BattleHero)
            {
                //Debug.Log("본인 타겟 " + owner.heroData.heroName);
            }
            else if (enemy && enemy.isFinishSpawned && skill.skillData.castToDeadUnit == enemy.isDie && enemy.transform.position.x < owner.transform.position.x)
            {
                if (skill.skillData.canCastToAir || enemy.skeletonAnimation.transform.localPosition.y < 3f)
                {
                    if (!enemy.isDie || (enemy.isDie && enemy.canResurrect))
                    //if (enemy.transform.position.x - owner.transform.position.x >= skill.skillData.minDistance
                    //       && enemy.transform.position.x - owner.transform.position.x <= skill.skillData.maxDistance)
                    {
                        lastTarget            = enemy;
                        lastCollectTargetTime = Time.time;
                        return(enemy);
                    }
                }
            }
        }


        for (int i = 0; i < enemyList.Count; i++)
        {
            BattleHero enemy = enemyList[i];

            if (!enemy.gameObject.activeSelf)
            {
                continue;
            }

            if (enemy == owner as BattleHero)
            {
                //Debug.Log("11본인 타겟 " + owner.heroData.heroName);
                continue;
            }

            if (!skill.skillData.canCastToDeadUnit && enemy.isDie)
            {
                continue;
            }

            if (skill.skillData.castToDeadUnit != enemy.isDie)
            {
                continue;
            }

            if (enemy.isDie && !enemy.canResurrect)
            {
                continue;
            }

            if (skill.skillData.canCastToAir || enemy.skeletonAnimation.transform.localPosition.y < 3f)
            {
                distance = enemy.GetDistanceFrom(owner);

                //if (distance < skill.skillData.minDistance || distance > skill.skillData.maxDistance)
                //    continue;

                if (!nearestEnemy)
                {
                    nearestEnemy = enemy;
                    continue;
                }
                else
                {
                    //이전 대상 보다 가까우면 교체
                    if (nearestEnemy.GetDistanceFrom(owner) > distance)
                    {
                        nearestEnemy = enemy;
                    }
                }
            }
        }



        lastTarget            = nearestEnemy;
        lastCollectTargetTime = Time.time;
        //lastDistanceFromTarget = distance;

        return(nearestEnemy);
    }
Example #6
0
    public IEnumerator InitCoroutine(BattleGroup battleGroup, BattleUnit.Team team = BattleUnit.Team.Red, List <HeroData> heroList = null)
    {
        while (actorList.Count > 0)
        {
            actorList[0].onDie -= OnDie;
            actorList[0].Despawn();
            yield return(null);
        }
        deadTeamMemberCount = 0;
        teamMemberCount     = 0;

        if (heroList == null)
        {
            yield break;
        }
        teamMemberCount = heroList.Count;

        for (int i = 0; i < teamMemberCount; i++)
        {
            BattleHero battleHero = null;
            yield return(StartCoroutine(actorPool.Instance.GetActor(heroList[i].heroID, x => battleHero = x)));

            if (!battleHero)
            {
                continue;
            }

            battleHero.team = team;
            if (battleGroup.battleType == BattleGroup.BattleType.PvP)
            {
                battleHero.InitPvP(battleGroup, heroList[i]);
            }
            else if (battleGroup.battleType == BattleGroup.BattleType.Normal)
            {
                battleHero.Init(battleGroup, heroList[i]);
            }

            battleHero.gameObject.SetActive(true);
            battleHero.ReGen();
            battleHero.onDie += OnDie;

            actorList.Add(battleHero);
        }


        //스테이지 시작 trigger인 버프 적용하기
        for (int i = 0; i < actorList.Count; i++)
        {
            BattleHero hero = actorList[i];
            for (int a = 0; a < hero.buffController.buffList.Count; a++)
            {
                Buff buff = hero.buffController.buffList[a];
                if (buff.baseData.trigger != "OnStartStage")
                {
                    continue;
                }

                if (buff.triggerProbability < UnityEngine.Random.Range(1, 10001))
                {
                    continue;
                }

                BattleUnit target = null;
                if (buff.baseData.triggerTarget == "SkillTarget")
                {
                    target = hero;
                }
                else if (buff.baseData.triggerTarget == "BuffTarget")
                {
                    target = hero;
                }

                if (target && !target.isDie)
                {
                    target.buffController.AttachBuff(hero, buff.baseData.triggerBuff, 1, buff);
                }
            }
        }
    }
Example #7
0
 public void Init(BattleGroup battleGroup, BattleUnit.Team team = BattleUnit.Team.Red, List <HeroData> heroList = null)
 {
     StartCoroutine(InitCoroutine(battleGroup, team, heroList));
 }
Example #8
0
    IEnumerator MoveToTarget()
    {
        //스킬 초기화 안 되어 있으면 초기화 한 다음에 날아감.
        if (!isInitializedSkillList)
        {
            InitSkillList();
        }
        //yield return StartCoroutine(InitSkillList());

        //발사 주체와 목표물 설정 안 되면 날아가지 않음
        while (!master || !target)
        {
            yield return(null);
        }

        //파티클 있으면 플레이 시키고
        ParticleSystem p = GetComponentInChildren <ParticleSystem>();

        if (p)
        {
            p.Play();
        }

        //애니메이션 있으면 플레이 시키고
        Animation anim = GetComponentInChildren <Animation>();

        if (anim)
        {
            anim.Play();
        }

        //사운드 재생
        AudioSource audio = GetComponentInChildren <AudioSource>();

        if (audio)
        {
            audio.Play();
        }

        Vector3 targetPoint = target.transform.position;
        //transform.LookAt(targetPoint, Vector3.forward);
        Vector3 a = new Vector3(0, 0, 80);
        Vector3 b = new Vector3(0, 0, -80);

        float force = 10;

        if (target.transform.position.x < transform.position.x)
        {
            force = -force;
        }
        isMoveForwardRight = target.transform.position.x < transform.position.x;

        float startTime = Time.time;

        while (startTime > 0)
        {
            float t = (Time.time - startTime) / flyTime;
            if (isCurve)
            {
                transform.eulerAngles = Vector3.Lerp(a, b, t);
                transform.position    = GetPointOnBezierCurve(startPos, startPos + (Vector3.up * curveHeight), targetPoint + (Vector3.up * curveHeight), targetPoint, t);
            }
            else
            {
                transform.position = Vector3.MoveTowards(transform.position, transform.position + (Vector3.right * force), flySpeed * Time.deltaTime);
                //transform.position = Vector2.Lerp(transform.position, transform.position + transform.right, 3 * t);
            }


            if (isCanCounter)
            {
                if (isDisChacking)
                {
                    if (ChackingDistance())
                    {
                        break;
                    }
                }
            }
            else if (isPush)
            {
                for (int i = 0; i < skillList.Count; i++)
                {
                    SkillBase skill = skillList[i];
                    skill.owner = owner;

                    skill.CheckCastCondition();

                    if (skill.isCoolTime == false && skill.skillData.autoExecute)
                    {
                        skill.Execute();
                    }
                }
            }

            if (t > 1)
            {
                break;
            }

            yield return(null);
        }

        bool isCounter = false;

        if (isCanCounter && owner.master.team != target.team)
        {
            BattleUnit.Team team = owner.master.team;
            SkillBase       counterRangeSkill = target.counterSkillList.Find(x => x.skillData.effectType == "CounterRange");

            if (counterRangeSkill != null && counterRangeSkill.isCoolTime == false)
            {
                //Debug.Log(owner.master.heroData.heroName + "의 공격 카운터 !!");
                isCounter = true;

                counterRangeSkill.Execute();
                BattleUnit attacker = target;
                target = owner.master;

                //캐릭터 위치에 따라 뒤집기
                if (attacker is BattleHero)
                {
                    BattleHero h      = attacker as BattleHero;
                    bool       isFlip = h.flipX;
                    float      z      = isFlip ? 180f : 0f;
                    //transform.Rotate(new Vector3(0, 0, z));
                    Quaternion quaternion = new Quaternion(0, 0, z, 0);
                    transform.rotation = quaternion;
                }

                float distance = target.GetDistanceFrom(this);

                while (distance > 1)
                {
                    distance           = target.GetDistanceFrom(this);
                    transform.position = Vector3.MoveTowards(transform.position, target.collider.transform.position, 1);
                    //transform.position = Vector3.Lerp(transform.position,target.transform.position,t);
                    yield return(null);
                }

                //Debug.Log(owner.master.heroData.heroName + " 끝");

                //Debug.Log("팀 변경 " + owner.master.team + "->" + attacker.team);
                owner.master.team = attacker.team;
            }
        }

        if (isPush == false)
        {
            for (int i = 0; i < skillList.Count; i++)
            {
                skillList[i].owner      = owner;
                skillList[i].castTarget = target as BattleHero;
                skillList[i].Execute();
            }
        }
        if (isCounter)
        {
            //Debug.Log("팀 변경 " + owner.master.team + "->" + team);
            owner.master.team = team;
        }

        //발사체 명중 시 파티클 재생
        if (hitParticle)
        {
            GameObject hitEffectObj = Battle.GetObjectInPool(hitParticle.name);

            //풀링 안되어 있으면 함.
            if (!hitEffectObj)
            {
                hitEffectObj      = Instantiate(hitParticle, target.transform.position, Quaternion.identity, owner.transform.parent) as GameObject;
                hitEffectObj.name = hitParticle.name;
                //if(!hitEffectObj.GetComponent<SelfDestroyParticle>())
                //    hitEffectObj.AddComponent<SelfDestroyParticle>();
                hitEffectObj.SetActive(false);
                hitEffectObj.AddComponent <BattleGroupElement>();

                Battle.AddObjectToPool(hitEffectObj);
            }

            if (hitEffectObj)
            {
                Vector3 hitPos = target.GetClosestPoint(transform.position);
                hitEffectObj.transform.position = hitPos;

                hitEffectObj.transform.localScale = Vector3.one;

                //발사체 오브젝트 활성
                hitEffectObj.SetActive(true);
                hitEffectObj.GetComponent <BattleGroupElement>().SetBattleGroup(owner.battleGroup);
                ParticleSystem p2 = hitEffectObj.GetComponentInChildren <ParticleSystem>();
                if (p2)
                {
                    p2.Play();
                }

                Animation _anim = hitEffectObj.GetComponentInChildren <Animation>();
                if (_anim)
                {
                    anim.Play();
                }
            }
        }

        //파티클 끄기. (뿅하고 끄면 이상함)
        if (particle)
        {
            particle.Stop();
        }

        //파티클 완전히 꺼질 때 까지 대기. 즉시 꺼지기 설정되어 있으면 이 과정 생략
        while (particle && !particle.isStopped)
        {
            yield return(null);
        }

        //그리고 디스폰
        Despawn();
    }
Example #9
0
    IEnumerator MoveToTarget()
    {
        //스킬 초기화 안 되어 있으면 초기화 한 다음에 날아감.
        if (!isInitializedSkillList)
        {
            InitSkillList();
        }
        //yield return StartCoroutine(InitSkillList());

        //발사 주체와 목표물 설정 안 되면 날아가지 않음
        while (!master || !target)
        {
            yield return(null);
        }

        //파티클 있으면 플레이 시키고
        ParticleSystem p = GetComponentInChildren <ParticleSystem>();

        if (p)
        {
            p.Play();
        }

        //애니메이션 있으면 플레이 시키고
        Animation anim = GetComponentInChildren <Animation>();

        if (anim)
        {
            anim.Play();
        }

        //사운드 재생
        AudioSource audio = GetComponentInChildren <AudioSource>();

        if (audio)
        {
            audio.Play();
        }

        //startPos = transform.position;

        float startTime   = Time.time;
        float elapsedTime = 0f;

        //대상 방향에 따라 연출 방향 좌우 뒤집음
        float isNeedFlip = 1f;

        //if (transform.position.x > target.transform.position.x)
        //    isNeedFlip = -1f;

        transform.localScale = Vector3.one * isNeedFlip;// new Vector3(isNeedFlip, transform.localScale.y, transform.localScale.z);

        Vector2 lastPos  = transform.position;
        Vector2 velocity = Vector2.zero;

        //커브의 절대 값만큼 이동
        while (elapsedTime < flyingTime)
        {
            float a = elapsedTime / flyingTime; //진척도

            //현재 경과 시간의 비율에 비례해서 설정해둔 커브값 만큼 움직임
            x = startPos.x + animationCurveX.Evaluate(a) * isNeedFlip;
            y = startPos.y + animationCurveY.Evaluate(a);

            Vector2 destPos = new Vector3(x, y, transform.position.z);

            //Vector3 dir = enemy.position - transform.position;
            float angle = Mathf.Atan2(destPos.y, destPos.x) * Mathf.Rad2Deg;
            //transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);

            transform.LookAt(destPos, Vector3.up);

            transform.position = new Vector2(x, y);//, transform.position.z);

            velocity = (Vector2)transform.position - lastPos;


            elapsedTime = Time.time - startTime;
            lastPos     = transform.position;

            if (!target || target.isDie)
            {
                if (parentSkill)
                {
                    parentSkill.CollectTargets();
                    if (parentSkill.targetList != null && parentSkill.targetList.Count > 0)
                    {
                        target = parentSkill.targetList[0];
                    }
                    else
                    {
                        //파티클 끄기. (뿅하고 끄면 이상함)
                        if (particle)
                        {
                            particle.Stop();
                        }

                        //파티클 완전히 꺼질 때 까지 대기
                        while (particle && !particle.isStopped)
                        {
                            yield return(null);
                        }

                        //그리고 디스폰
                        Despawn();
                        yield break;
                    }
                }
            }


            yield return(null);
        }

        transform.LookAt(target.transform, Vector3.up);

        //위치
        x = startPos.x + animationCurveX.Evaluate(1f) * isNeedFlip;
        y = startPos.y + animationCurveY.Evaluate(1f);
        transform.position = new Vector2(x, y);//, transform.position.z);


        //Debug.Log(velocity);

        if (flyingType == FryingType.Absolute)
        {
            startTime   = Time.time;
            elapsedTime = 0f;
            float   lastTime      = Time.time;
            Vector3 startPosition = transform.position;
            while (target.GetDistanceFrom(this) > hitThreshold)
            {
                float deltaTime = Time.time - lastTime;

                //transform.position = Vector3.Lerp(startPosition, target.transform.position, acc * acc * speed * elapsedTime);

                Vector2 direction       = (Vector2)transform.position + velocity * deltaTime;
                Vector2 targetDirection = (Vector2)transform.position + (Vector2)(target.transform.position - transform.position).normalized * velocity.magnitude * deltaTime;

                Vector3 nextPos = Vector3.Lerp(direction, targetDirection, followTargetWeight);


                //transform.LookAt(Vector2.Lerp(transform.position + transform.forward.normalized * speed,  target.transform.position, followTargetWeight * deltaTime));


                Vector2 fowardDir = transform.position + transform.right.normalized * speed - transform.position;
                Vector2 targetDir = target.GetClosestPoint(transform.position) /*target.transform.position*/ - transform.position;
                Vector2 final     = Vector2.Lerp(fowardDir, targetDir, followTargetWeight * deltaTime);

                float angle = Mathf.Atan2(final.y, final.x) * Mathf.Rad2Deg;
                transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);


                transform.position = Vector2.Lerp(transform.position, transform.position + transform.right, speed * deltaTime);

                //transform.position = Vector2.MoveTowards(transform.position, transform.position + transform.right, speed * deltaTime);

                //transform.position += transform.right * speed * Time.deltaTime;

                //transform.position = Vector3.Lerp(transform.position, transform.position.x)

                //transform.position = nextPos;// Vector3.Lerp(transform.position, nextPos, speed * deltaTime);

                //transform.position = Vector3.Lerp(nextPos, target.transform.position, speed * deltaTime);

                //velocity += targetDirection.normalized * acc * deltaTime;

                //transform.position += (Vector3) velocity;

                //transform.position = Vector3.Lerp(transform.position, target.transform.position, speed * deltaTime);
                velocity = (Vector2)transform.position - lastPos;

                elapsedTime = Time.time - startTime;

                lastTime = Time.time;

                lastPos = transform.position;

                if (!target || target.isDie)
                {
                    if (parentSkill)
                    {
                        parentSkill.CollectTargets();
                        if (parentSkill.targetList != null && parentSkill.targetList.Count > 0)
                        {
                            target = parentSkill.targetList[0];
                        }
                        else
                        {
                            speedTemp = speed;
                            Stop();
                            yield break;
                        }
                    }
                }

                yield return(null);
            }
        }
        else
        {
            elapsedTime = 0f;
            float animValue = 0f;
            float lastTime  = Time.time;

            startPos = transform.position;
            lastPos  = transform.position;

            float distance = target.GetDistanceFrom(this);
            float goalTime = distance / speed;

            while (animValue < 1f)
            {
                elapsedTime = Time.time - lastTime;

                if (goalTime <= 0f)
                {
                    animValue = 1f;
                }
                else
                {
                    animValue += elapsedTime / goalTime;
                }


                float   x, y;
                Vector3 targetPos = target.transform.position;
                if (target.collider)
                {
                    targetPos = target.collider.transform.position;
                }


                if (reverseX)
                {
                    //Vector3 temp = startPos;
                    startPos  = targetPos;
                    targetPos = master.transform.position;
                }

                //x축은 그냥 시간에 비례해서 보간함.
                Vector3 a = Vector3.Slerp(startPos, targetPos, animValue);
                x = a.x;

                //y축은 애님그래프 값만큼 보정하고, 날아가야 하는 시간에 비례해서 높이 조절함
                y = a.y + flyingCurveY.Evaluate(animValue) * goalTime;

                transform.position = new Vector3(x, y, transform.position.z);

                //날아가는 방향 바라보기. 화살 같은거
                Vector2 targetDir = (Vector2)transform.position - lastPos;
                targetDir = targetDir.normalized;
                float angle = Mathf.Atan2(targetDir.y, targetDir.x) * Mathf.Rad2Deg;

                Quaternion rot = Quaternion.AngleAxis(angle, Vector3.forward);

                transform.rotation         = Quaternion.Lerp(transform.rotation, rot, 25f * elapsedTime);//.AngleAxis(angle, Vector3.forward);
                transform.localEulerAngles = new Vector3(0f, 0f, transform.localEulerAngles.z);

                lastTime = Time.time;
                lastPos  = transform.position;

                yield return(null);
            }
        }
        bool isCounter = false;

        if (isCanCounter && owner.master.team != target.team)
        {
            BattleUnit.Team team = owner.master.team;
            SkillBase       counterRangeSkill = target.counterSkillList.Find(x => x.skillData.effectType == "CounterRange");

            if (counterRangeSkill != null && counterRangeSkill.isCoolTime == false)
            {
                //Debug.Log(owner.master.heroData.heroName + "의 공격 카운터 !!");
                isCounter = true;

                counterRangeSkill.Execute();
                BattleUnit attacker = target;
                target = owner.master;

                //캐릭터 위치에 따라 뒤집기
                if (attacker is BattleHero)
                {
                    BattleHero h      = attacker as BattleHero;
                    bool       isFlip = h.flipX;
                    float      z      = isFlip ? 180f : 0f;
                    //transform.Rotate(new Vector3(0, 0, z));
                    Quaternion quaternion = new Quaternion(0, 0, z, 0);
                    transform.rotation = quaternion;
                }

                float distance = target.GetDistanceFrom(this);

                while (distance > 1)
                {
                    distance           = target.GetDistanceFrom(this);
                    transform.position = Vector3.MoveTowards(transform.position, target.collider.transform.position, 1);
                    //transform.position = Vector3.Lerp(transform.position,target.transform.position,t);
                    yield return(null);
                }

                //Debug.Log(owner.master.heroData.heroName + " 끝");

                //Debug.Log("팀 변경 " + owner.master.team + "->" + attacker.team);
                owner.master.team = attacker.team;
            }
        }



        for (int i = 0; i < skillList.Count; i++)
        {
            skillList[i].owner = owner;
            //master = owner;
            //skillList[i].canExecute = true;
            skillList[i].castTarget = target as BattleHero;
            skillList[i].CheckCastCondition();
            skillList[i].Execute();

            //ExecuteSkill(skillList[i]);
        }

        if (isCounter)
        {
            //Debug.Log("팀 변경 " + owner.master.team + "->" + team);
            owner.master.team = team;
        }

        //발사체 명중 시 파티클 재생
        if (hitParticle)
        {
            GameObject hitEffectObj = Battle.GetObjectInPool(hitParticle.name);

            //풀링 안되어 있으면 함.
            if (!hitEffectObj)
            {
                hitEffectObj      = Instantiate(hitParticle, target.transform.position, Quaternion.identity, owner.transform.parent) as GameObject;
                hitEffectObj.name = hitParticle.name;
                //if(!hitEffectObj.GetComponent<SelfDestroyParticle>())
                //    hitEffectObj.AddComponent<SelfDestroyParticle>();
                hitEffectObj.SetActive(false);
                hitEffectObj.AddComponent <BattleGroupElement>();

                Battle.AddObjectToPool(hitEffectObj);
            }

            if (hitEffectObj)
            {
                Vector3 hitPos = target.GetClosestPoint(transform.position);
                hitEffectObj.transform.position = hitPos;

                hitEffectObj.transform.localScale = Vector3.one;

                //발사체 오브젝트 활성
                hitEffectObj.SetActive(true);
                hitEffectObj.GetComponent <BattleGroupElement>().SetBattleGroup(owner.battleGroup);
                ParticleSystem p2 = hitEffectObj.GetComponentInChildren <ParticleSystem>();
                if (p2)
                {
                    p2.Play();
                }

                Animation a = hitEffectObj.GetComponentInChildren <Animation>();
                if (a)
                {
                    anim.Play();
                }
            }
        }

        //한 프레임 더 가서 발동. 너무 일찍 끊기는 것 같아서 임시방편
        //yield return new WaitForSeconds(0.1f);

        //쿨타임, idle상태 체크 이런건 안 함
        //SkillBase.ExecuteCondition ignoreCondition = SkillBase.ExecuteCondition.IsNotIdle | SkillBase.ExecuteCondition.IsCoolTime;



        //파티클 끄기. (뿅하고 끄면 이상함)
        if (particle)
        {
            particle.Stop();
        }

        //파티클 완전히 꺼질 때 까지 대기. 즉시 꺼지기 설정되어 있으면 이 과정 생략
        while (particle && !particle.isStopped && !stopImmediately)
        {
            yield return(null);
        }

        //그리고 디스폰
        Despawn();
        //gameObject.SetActive(false);
    }