EntityManager

EntityManager에서는 entity들을 관리한다. entity들의 움직임, 공격, 소환되는 것을 관리

1.EntityAlignment

Entity가 죽거나, 소환될 때 호출되며 entity를 정렬한다.

    public void EntityAlignment(bool isMine) //내 것이면 내 entity 정렬, 상대 것이면 상대 entity 정렬
    {
        float targetY = isMine ? -6.0f : 6.0f;
        var targetEntities = isMine ? myEntities : otherEntities;
        for (int i = 0; i < targetEntities.Count; i++)
        {
            float targetX = (targetEntities.Count - 1) * -2.5f + i * 5.0f;
            var targetEntity = targetEntities[i];
            targetEntity.originPos = new Vector3(targetX, targetY, 0);
            targetEntity.MoveTransform(targetEntity.originPos, true, 0.5f);
            targetEntity.GetComponent<Order>()?.SetOriginOrder(i);
        }
    }

2.SpawnEntity

카드 상태에서 entity로 소환했을 때 호출되며, 호출되면 필드에 entity prefebs를 통해 생성된다.

    public bool SpawnEntity(bool isMine, Item item, Vector3 spawnPos) //카드의 아이템을 바탕을 생성
    {
        if (isMine)
        {
            if (IsFullMyEntities || !ExitMyEmptyEntity)
                return false;
        }
        else
        {
            if (IsFullOtherEntities)
                return false;
        }
        var entityObject = Instantiate(entityPrefab, spawnPos, Utils.QI);
        var entity = entityObject.GetComponent<Entity>();

        if (isMine)
        {
            myEntities[myEmptyEntityIndex] = entity;
            entity.name = SetEntityNum(isMine);
        }
        else
        {
            otherEntities.Insert(UnityEngine.Random.Range(0, otherEntities.Count), entity);
            entity.name = SetEntityNum(isMine);
        }
        entity.isMine = isMine;
        entity.Setup(item);
        EntityAlignment(isMine);
        return true;
    }

3.Attack & AttackCallback

공격과 공격 이후의 데미지에 따른 결과를 호출한다.

    public void Attack(Entity attacker, Entity defender)
    {
        if (defender.canBeAttacked == false && attacker.ablcode1 !=21)
        {
            return;
        }
        attacker.attackable = false; //턴당 1회 공격이기에 bool 값을 false로 만들어 공격을 한번만 할 수 있다.
        attacker.GetComponent<Order>().SetMostFrontOrder(true);
        if (attacker.isMine)
        {
            if (defender.isBossOrEmpty)
            {
                byte[] send = new byte[3] { 0x00, Convert.ToByte(attacker.gameObject.name), Convert.ToByte("0") };
                BackEndMatch.SendMessage(send);
            }
            else
            {
                byte[] send = new byte[3] { 0x00, Convert.ToByte(attacker.gameObject.name), Convert.ToByte(defender.gameObject.name) };
                BackEndMatch.SendMessage(send);
            }
            AbilityManager.Inst.eTurnState = AbilityManager.ETurnState.attacking;
            AbilityManager.Inst.stateTrigger = true;
            if (AbilityManager.Inst.abilityNum[attacker.ablcode1].state == (int)AbilityManager.ETurnState.attacking || AbilityManager.Inst.abilityNum[defender.ablcode1].state == (int)AbilityManager.ETurnState.beAttacked)
            {
                castEntity = attacker;
                return;
            }
        }
        Sequence sequence = DOTween.Sequence() // 공격에 따른 DOTween 모션
            .Append(attacker.transform.DOMove(defender.transform.position, 0.4f)).SetEase(Ease.InSine)
            .AppendCallback(() =>
            {
                attacker.Damaged(defender.attack);
                defender.Damaged(attacker.attack);
                SpawnDamage(defender.attack, attacker.transform);
                SpawnDamage(attacker.attack, defender.transform); //공격 시 공격자와 방어자 모두 데미지를 서로의 공격력만큼 입는다.
            })
            .Append(attacker.transform.DOMove(attacker.originPos, 0.4f)).SetEase(Ease.OutSine)
            .OnComplete(() => AttackCallback(attacker, defender)); //공격 후 entity가 죽었는지 확인하기 위해
        StartCoroutine(cursor.Inst.Attack());
    }

공격 시 데미지를 호출한다.

    public void SpawnDamage(int damage, Transform tr)
    {
        if (damage <= 0)
            return;

        var damageComponent = Instantiate(damagePrefab).GetComponent<Damage>();
        damageComponent.SetupTransform(tr);
        damageComponent.Damaged(damage);
    }
    public void Damaged(int damage)
    {
        if(damage <=0)
            return;
        GetComponent<Order>().SetOrder(1000,"Entity");
        damageTMP.text =$"-{damage}";

        Sequence sequence =DOTween.Sequence()
            .Append(transform.DOScale(Vector3.one * 4.0f,0.5f).SetEase(Ease.InOutBack))
            .AppendInterval(1.0f)
            .Append(transform.DOScale(Vector3.zero, 0.5f).SetEase(Ease.InOutBack))
            .OnComplete(() => Destroy(gameObject));
    }

공격 이후에 호출되며, 호출된 entity들의 사망 정보를 확인하고, 플레이어의 entity의 죽음을 확인하여, 만약 플레이어가 죽었으면 게임을 종료하는 코루틴을 호출

public void AttackCallback(params Entity[] entities)
    {
        entities[0].GetComponent<Order>().SetMostFrontOrder(false);

        foreach (var entity in entities)
        {
            if (!entity.isDie || entity.isBossOrEmpty)
                continue;
            if (entity.isMine)
            {
                AbilityManager.Inst.eTurnState = AbilityManager.ETurnState.myMonDie;
                AbilityManager.Inst.stateTrigger = true;
                if(AbilityManager.Inst.abilityNum[entity.ablcode1].state == (int)AbilityManager.ETurnState.myMonDie)
                {
                    castEntity = entity;
                }
                myEntities.Remove(entity);
            }
            else
                otherEntities.Remove(entity);

            Sequence sequence = DOTween.Sequence()
                .Append(entity.transform.DOShakePosition(1.0f))
                .Append(entity.transform.DOScale(Vector3.zero, 0.3f)).SetEase(Ease.OutCirc)
                .OnComplete(() =>
                {
                    EntityAlignment(entity.isMine);
                    Destroy(entity.gameObject);
                });
        }
        StartCoroutine(CheckBossDie());
    }

4.Entity 움직임

1)EntityMouseUp

마우스가 entity 클릭을 멈출 때 호출된다.

    public void EntityMouseUp()
    {
        if (!CanMouseInput) 
            return;

        if (selectEntity && targetPickEntity && selectEntity.attackable) //클릭해서 움직인 entity가 있고, 공격할 entity위에서 마우스 클릭을 멈췄을 때
            Attack(selectEntity, targetPickEntity);

        selectEntity = null;
        targetPickEntity = null;
    }

2)EntityMouseDown

마우스가 entity를 클릭할 때 호출한다.

    public void EntityMouseDown(Entity entity)
    {
        if (!CanMouseInput)
            return;

        selectEntity = entity;
        AbilityManager.Inst.eTurnState = AbilityManager.ETurnState.drag;
        AbilityManager.Inst.stateTrigger = true;
    }

3)EntityMouseDrag

마우스로 entity를 선택하고 드래그할 때 호출된다. 공격 대상을 찾는다. 공격 대상을 찾으면 멈춘다.

    public void EntityMouseDrag()
    {
        if (!CanMouseInput || selectEntity == null)
            return;

        bool existTarget = false;
        foreach (var hit in Physics2D.RaycastAll(Utils.MousePos, Vector3.forward))
        {
            Entity entity = hit.collider?.GetComponent<Entity>();
            if (entity != null && !entity.isMine && selectEntity.attackable)
            {
                targetPickEntity = entity;
                targetEntity = entity;
                existTarget = true;
                break;
            }
        }
        if (!existTarget)
            targetPickEntity = null;
    }