Exemplo n.º 1
0
    override public void TriggerEffect()
    {
        if (skillListToExecute == null || skillListToExecute.Count == 0)
        {
            return;
        }

        int r = UnityEngine.Random.Range(0, totalExecWeight);

        int curWeight = 0;

        for (int i = 0; i < skillListToExecute.Count; i++)
        {
            curWeight += skillListToExecute[i].weight;
            if (r <= curWeight)
            {
                SkillBase s = skill.owner.skillList.Find(x => x.skillData.id == skillListToExecute[i].id);
                if (s)
                {
                    s.CheckCastCondition();
                    s.Execute();
                }

                break;
            }
        }


        if (skill.onTriggerEvent != null)
        {
            skill.onTriggerEvent(skill, skillEvent);
        }
    }
Exemplo n.º 2
0
    virtual public bool Damage(BattleUnit attacker, double finalAttackPower, SkillBase.DamageType damageType = SkillBase.DamageType.NotDefined, SkillBase skill = null, string tag = "")
    {
        if (isSuperArmor)
        {
            //Debug.Log(attacker.heroData.heroName +"의 공격 막아짐 데미지 :" + finalAttackPower);
            return(false);
        }

        if (skill != null && counterSkillList.Count > 0)
        {
            for (int i = 0; i < counterSkillList.Count; i++)
            {
                SkillBase counterSkill = counterSkillList[i];

                if (counterSkill.skillData.effectType == "CounterMeleePhysical")
                {
                    if (skill.skillData.damageType == SkillBase.DamageType.Physical &&
                        skill.skillData.rangeType == SkillBase.RangeType.Melee &&
                        skill.skillData.triggerType == SkillBase.TriggerType.None &&
                        skill.skillData.collectTargetType == SkillBase.CollectTargetType.Target)
                    {
                        BattleHero h = attacker as BattleHero;
                        counterSkill.castTarget = h;
                        counterSkill.CheckCastCondition();
                        if (!counterSkill.isCoolTime && counterSkill.IsCastTargetInSkillRange())
                        {
                            counterSkill.Execute();
                            return(false);
                        }
                    }
                }

                if (counterSkill.skillData.effectType == "CounterRangePhysical")
                {
                    if (skill.skillData.damageType == SkillBase.DamageType.Physical &&
                        skill.skillData.rangeType == SkillBase.RangeType.Range &&
                        skill.skillData.triggerType == SkillBase.TriggerType.None)
                    {
                        BattleHero h = attacker as BattleHero;
                        counterSkill.castTarget = h;
                        counterSkill.CheckCastCondition();
                        if (!counterSkill.isCoolTime && counterSkill.IsCastTargetInSkillRange())
                        {
                            counterSkill.Execute();

                            if (onHit != null)
                            {
                                onHit(finalAttackPower, "ImmuneDamage");
                            }
                            return(false);
                        }
                    }
                }

                if (counterSkill.skillData.triggerType == SkillBase.TriggerType.OnHit && counterSkill.skillData.effectType == "Ninja_CounterAttack")
                {
                    if (damageType != SkillBase.DamageType.Pure)
                    {
                        BattleHero h = attacker as BattleHero;
                        counterSkill.castTarget = h;
                        counterSkill.CheckCastCondition();
                        //Debug.Log(counterSkill.currentCoolTime + "/" + counterSkill.isCoolTime);
                        if (counterSkill.canCastSkill && !counterSkill.isCoolTime && counterSkill.IsCastTargetInSkillRange())
                        {
                            SkillData skillData = counterSkill.skillData;
                            if (!string.IsNullOrEmpty(skillData.coolTime1ID))
                            {
                                coolTimeController.ApplyCoolTime(skillData.coolTime1ID, skillData.coolTime1);
                            }

                            if (!string.IsNullOrEmpty(skillData.coolTime2ID))
                            {
                                coolTimeController.ApplyCoolTime(skillData.coolTime2ID, skillData.coolTime2);
                            }

                            //counterSkill.onStart += OnStartSkill;
                            //counterSkill.onFinish += OnFinishSkill;

                            //Debug.Log("반격!");
                            // 닌자 반격 스킬
                            counterSkill.Execute();
                            //캐릭터 위치에 따라 뒤집기
                            bool isFlip = false;
                            if (attacker is BattleHero)
                            {
                                isFlip = h.flipX;
                                float x = isFlip ? 1f : -1f;
                                transform.position = attacker.transform.position + (Vector3.right * 3 * x);
                            }

                            if (this is BattleHero)
                            {
                                BattleHero owner = this as BattleHero;
                                owner.flipX = isFlip;
                            }
                            return(false);
                        }
                    }
                }
                else if (counterSkill.skillData.triggerType == SkillBase.TriggerType.OnHit && counterSkill.skillData.effectType == "CounterDash")
                {
                    if (damageType != SkillBase.DamageType.Pure)
                    {
                        counterSkill.CheckCastCondition();
                        //Debug.Log(counterSkill.currentCoolTime + "/" + counterSkill.isCoolTime);
                        if (!counterSkill.isCoolTime)
                        {
                            SkillData skillData = counterSkill.skillData;
                            if (!string.IsNullOrEmpty(skillData.coolTime1ID))
                            {
                                coolTimeController.ApplyCoolTime(skillData.coolTime1ID, skillData.coolTime1);
                            }

                            if (!string.IsNullOrEmpty(skillData.coolTime2ID))
                            {
                                coolTimeController.ApplyCoolTime(skillData.coolTime2ID, skillData.coolTime2);
                            }

                            //Debug.Log("뱀파이어 회피");

                            BattleHero hero   = this as BattleHero;
                            bool       isFlip = hero.flipX;
                            float      x      = isFlip ? 1f : -1f;

                            //카운터 대쉬 이기에 무적처리함
                            isSuperArmor = true;

                            counterSkill.Execute();
                            return(false);
                        }
                    }
                }
                else if (counterSkill.skillData.triggerType == SkillBase.TriggerType.OnHit && counterSkill.skillData.effectType == "Saladin_TimeReverse")
                {
                    if (damageType != SkillBase.DamageType.Pure && finalAttackPower > counterSkill.owner.curHP)
                    {
                        counterSkill.CheckCastCondition();
                        //Debug.Log(counterSkill.currentCoolTime + "/" + counterSkill.isCoolTime);
                        if (!counterSkill.isCoolTime)
                        {
                            if (beforeHP[order] == 0)
                            {
                                curHP = maxHP;
                            }
                            else
                            {
                                curHP = beforeHP[order];
                            }

                            counterSkill.Execute();
                            return(false);
                        }
                    }
                }
            }
        }

        //공격력 식 재계산..

        //전체 피해감소
        double atk             = attacker.stats.GetValueOf(StatType.AttackPower);
        double penetrateRatio  = System.Math.Min(attacker.stats.GetValueOf(StatType.PenetrateRatio) * 0.0001, 0.99);
        double def             = stats.GetValueOf(StatType.DefensePower) * (1 - penetrateRatio);
        double damageReduction = atk / def;


        //데미지 감소 적용
        if (damageType == SkillBase.DamageType.Magical || damageType == SkillBase.DamageType.Physical)
        {
            float resist = 0f;
            if (damageType == SkillBase.DamageType.Magical)
            {
                resist = (float)stats.GetValueOf(StatType.ReduceMagicalDamageRate) * 0.0001f;
            }
            else if (damageType == SkillBase.DamageType.Physical)
            {
                resist = (float)stats.GetValueOf(StatType.ReducePhysicalDamageRate) * 0.0001f;
            }

            float reduceDamageRate = (float)stats.GetValueOf(StatType.ReduceDamageRate) * 0.0001f;


            finalAttackPower = finalAttackPower * damageReduction * Mathf.Max(1f - reduceDamageRate, 0f) * Mathf.Max(1f - resist, 0f);


            //Debug.Log(attacker.heroData.baseData.name + ", " + heroData.baseData.name + ", " + atk + ", " + def + ", " + finalAttackPower);
        }

        //보스 피해량 증가
        if (isBoss)
        {
            double increaseDamageRate = attacker.stats.GetValueOf(StatType.IncreaseDamageRateBoss) * 0.0001f;
            finalAttackPower = finalAttackPower * (1d + increaseDamageRate);
        }

        //무적 버프 처리를 위해 먼저 한 번 검색
        if (curHP < finalAttackPower)
        {
            for (int a = 0; a < buffController.buffList.Count; a++)
            {
                Buff buff = buffController.buffList[a];
                if (buff.baseData.trigger != "OnTakeDeadlyDamage")
                {
                    continue;
                }

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

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

                if (target && !target.isDie)
                {
                    target.buffController.AttachBuff(target, buff.baseData.triggerBuff, 1, buff);
                }
            }


            SkillBase skillBase = counterSkillList.Find(x => x.skillData.triggerType == SkillBase.TriggerType.OnDie);
            if (skillBase)
            {
                Buff buff = buffController.buffList.Find(x => x.id == "Buff_Shaman_Passive");
                if (buff != null && buff.isActive /* && buff.stack > 0*/)
                {
                    //Debug.Log("회생");
                    skillBase.Execute();
                    buffController.DetachBuff(buff);// .stack--;
                    return(false);
                }
            }
        }

        // 공중 영웅 추가 데미지 버프 처리
        Buff buffAirHero = attacker.buffController.buffList.Find(x => x.baseData.linkerType == "airHero" && x.isActive);

        if (buffAirHero != null && heroData.heroBattleType == HeroData.HeroBattleType.Air)
        {
            finalAttackPower *= (1 + (buffAirHero.statModifier.value * 0.0001d));
        }

        Buff buffDis = attacker.buffController.buffList.Find(x => x.baseData.linkerType == "distance" && x.isActive);

        if (buffDis != null)
        {
            float maxDis = 20f;
            float dis    = Vector2.Distance(attacker.transform.position, this.transform.position);
            dis = Mathf.Min(dis, maxDis);

            finalAttackPower *= (1 + (buffDis.statModifier.value * 0.0001d) * (maxDis - dis));
            //Debug.Log("거리 : " + dis + "/ " + (buffDis.statModifier.value * 0.0001d) * ((1 + maxDis - dis)));
        }



        //무적 버프
        Buff buffImmuneDamage = buffController.buffList.Find(x => x.baseData.effect == "ImmuneDamage" && x.isActive);

        if (buffImmuneDamage != null)
        {
            buffImmuneDamage.stack--;
            //Debug.Log(heroData.heroName + ") 공격 막음");
            finalAttackPower = 0;
            if (onHit != null)
            {
                onHit(finalAttackPower, "ImmuneDamage");
            }

            if (buffImmuneDamage.stack <= 0)
            {
                //Debug.Log("제거됨");
                buffController.DetachBuff(buffImmuneDamage.id);
            }
        }
        else
        {
            //얻어 맞았다는 콜백 호출
            if (onHit != null)
            {
                onHit(finalAttackPower, tag);
            }
        }

        //Stat dodgeStat = stats.GetParam(StatType.Dodge);
        Buff buffDodge = buffController.buffList.Find(x => x.baseData.stat == StatType.Dodge);

        if (buffDodge != null)
        {
            //Debug.Log(heroData.heroName + " / "+ buffDodge.id + " / " + buffDodge.baseData.triggerProbability);
            double prbability = buffDodge.GetPower(buffDodge, buffDodge.baseData.triggerProbability);
            //Debug.Log("회피성공률 : " + prbability);
            if (prbability >= UnityEngine.Random.Range(1, 10001))
            {
                //Debug.Log("성공");
                if (buffDodge.baseData.effect == "Miss")
                {
                    finalAttackPower = 0;
                    if (onHit != null)
                    {
                        onHit(finalAttackPower, "Miss");
                    }
                }
                else
                {
                    //얻어 맞았다는 콜백 호출
                    if (onHit != null)
                    {
                        onHit(finalAttackPower, tag);
                    }
                }
            }
        }


        //흡혈, 데미지 반사는 공격자가 살아있을 때만
        if (finalAttackPower > 1 && attacker && attacker.master && !attacker.master.isDie)
        {
            if (!attacker.master.isDie)
            {
                //공격자는 준 피해에 비례해서 흡혈 함
                Stat statLifeDrain = attacker.master.stats.GetParam(StatType.LifeDrainRate);
                if (statLifeDrain != null)
                {
                    double lifeDrain = statLifeDrain.value * 0.0001f;// attacker.master.lifeDrainRate;

                    if (lifeDrain > 0f)
                    {
                        attacker.master.LifeDrain(finalAttackPower * lifeDrain);
                    }
                }

                //얻어 맞은 애는 공격자 한테 데미지 반사 시킴
                Stat statReflect = attacker.master.stats.GetParam(StatType.ReflectDamageRate);
                if (statReflect != null)
                {
                    double reflect = statReflect.value * 0.0001f;// finalAttackPower * reflectDamageRate;
                    if (reflect > 0f)
                    {
                        attacker.master.ReflectDamage(this, reflect);
                    }
                }
            }

            //공격자의 OnHit 설정되어 있는 버프 trigger 발동
            for (int a = 0; a < attacker.master.buffController.buffList.Count; a++)
            {
                Buff buff = attacker.master.buffController.buffList[a];
                if (buff.baseData.trigger != "OnHit")
                {
                    continue;
                }

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

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

                if (target && !target.isDie)
                {
                    target.buffController.AttachBuff(attacker.master, buff.baseData.triggerBuff, 1, buff);
                }
            }

            //뚜까맞은애의 OnTakeDamage 설정되어 있는 버프 trigger 발동
            for (int a = 0; a < buffController.buffList.Count; a++)
            {
                Buff buff = buffController.buffList[a];
                if (buff.baseData.trigger != "OnTakeDamage")
                {
                    continue;
                }

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

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

                if (target && !target.isDie)
                {
                    target.buffController.AttachBuff(this, buff.baseData.triggerBuff, 1, buff);
                }
            }

            if (skill && skill.skillData != null && skill.skillData.rangeType == SkillBase.RangeType.Range)
            {
                //뚜까맞은애의 OnTakeDamage 설정되어 있는 버프 trigger 발동
                for (int a = 0; a < attacker.master.buffController.buffList.Count; a++)
                {
                    Buff buff = attacker.master.buffController.buffList[a];
                    if (buff.baseData.trigger != "OnHitRange")
                    {
                        continue;
                    }

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

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

                    if (target && !target.isDie)
                    {
                        target.buffController.AttachBuff(attacker.master, buff.baseData.triggerBuff, 1, buff);
                    }
                }
            }
        }



        //Todo: 방어력 등에 의한 실제 받아야 할 피해 계산


        //데미지가 사망에 이르는 정도인지 체크. 공격자의 OnKill 설정되어 있는 버프 trigger 발동
        if (finalAttackPower >= maxHP)
        {
            for (int a = 0; a < attacker.master.buffController.buffList.Count; a++)
            {
                Buff buff = attacker.master.buffController.buffList[a];
                if (buff.baseData.trigger != "OnInstantKill")
                {
                    continue;
                }

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


                if (buff.baseData.triggerTarget == "OwnerTeam")
                {
                    CustomList <BattleHero> targetList = attacker.master.team == Team.Red ? battleGroup.redTeamList : battleGroup.blueTeamList;
                    for (int b = 0; b < targetList.Count; b++)
                    {
                        BattleUnit target = targetList[b];

                        if (target && !target.isDie)
                        {
                            target.buffController.AttachBuff(attacker.master, buff.baseData.triggerBuff, 1, buff);
                        }
                    }
                }
                else
                {
                    BattleUnit target = null;
                    if (buff.baseData.triggerTarget == "SkillTarget")
                    {
                        target = this;
                    }
                    else if (buff.baseData.triggerTarget == "BuffTarget")
                    {
                        target = attacker.master;
                    }

                    target = attacker.master;

                    if (target && !target.isDie)
                    {
                        target.buffController.AttachBuff(attacker.master, buff.baseData.triggerBuff, 1, buff);
                    }
                }
            }
        }
        if (curHP < finalAttackPower)
        {
            for (int a = 0; a < attacker.master.buffController.buffList.Count; a++)
            {
                Buff buff = attacker.master.buffController.buffList[a];
                if (buff.baseData.trigger != "OnKill")
                {
                    continue;
                }

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

                BattleUnit target = null;
                if (buff.baseData.triggerTarget == "SkillTarget")
                {
                    target = this;
                }
                else if (buff.baseData.triggerTarget == "BuffTarget")
                {
                    target = attacker.master;
                }
                else if (buff.baseData.triggerTarget == "OwnerTeam")
                {
                    CustomList <BattleHero> targetList = attacker.master.team == Team.Red ? battleGroup.redTeamList : battleGroup.blueTeamList;
                    for (int b = 0; b < targetList.Count; b++)
                    {
                        BattleUnit _target = targetList[b];

                        if (_target && !_target.isDie)
                        {
                            _target.buffController.AttachBuff(attacker.master, buff.baseData.triggerBuff, 1, buff);
                        }
                    }
                }

                if (target != null)
                {
                    if (target && !target.isDie)
                    {
                        target.buffController.AttachBuff(attacker.master, buff.baseData.triggerBuff, 1, buff);
                    }
                }


                //Debug.Log("공격력 : " + attacker.master.stats.GetValueOf(StatType.AttackPower) + " / 방어력 : " + attacker.master.stats.GetValueOf(StatType.DefensePower));
            }
        }



        //체력 감소
        curHP -= finalAttackPower;
        if (damageType == SkillBase.DamageType.Physical || damageType == SkillBase.DamageType.Magical)
        {
            attacker.master.cumulativeDamage += finalAttackPower;
        }

        return(true);
    }
Exemplo n.º 3
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();
    }