패링 게임 - 7 (몬스터 위치)

Labin·2025년 4월 20일

패링 게임

목록 보기
9/14

몬스터의 위치 해결

몬스터의 위치를 처음에는 raycast로 앞에 ray 쏴서 체크하는 방법으로 해결하려고 하다가, 오히려 화면에 짤리면서 나타나는 적이 생길 것 같아서 위치로 바꿈. 정확한 위치에 서 있는 게 오히려 보기 좋을 듯.

    public enum Position { 
        Left_5 = 0, Left_4 = 1, Left_3 = 2, Left_2 = 3, Left_1 = 4, 
        Right_1 = 5, Right_2 = 6, Right_3 = 7, Right_4 = 8, Right_5 = 9 
    }
    

그냥 이런 식으로 최대 10마리 몬스터가 있다고 만들고

 private static bool initialized = false;
    
    void Awake()
    {
        m_stats = GetComponent<Monster_Stats>();
        m_animator = GetComponent<Animator>();
        m_weaponCollider = GetComponentInChildren<WeaponCollider>();
        
        // 첫 번째로 생성된 몬스터가 위치 포인트들을 초기화
        if (!initialized)
        {
            InitializePositionPoints();
            initialized = true;
        }
    }
    
    // 모든 위치 포인트를 찾아서 초기화
    private void InitializePositionPoints()
    {
        positionPoints = new List<Transform>();
        GameObject positionsParent = GameObject.Find("MonsterPositions");
        
        if (positionsParent != null)
        {
            // "Left_5", "Left_4", ... 등의 이름을 가진 자식 오브젝트들을 찾아 순서대로 추가
            for (int i = 0; i < 10; i++)
            {
                string pointName = "";
                if (i < 5)
                    pointName = "Left_" + (5 - i);
                else
                    pointName = "Right_" + (i - 4);
                
                Transform point = positionsParent.transform.Find(pointName);
                if (point != null)
                    positionPoints.Add(point);
                else
                    Debug.LogError("Position point not found: " + pointName);
            }
        }
        else
        {
            Debug.LogError("MonsterPositions parent object not found!");
        }
    }

몬스터를 다 초기화 해버림 위치 따라서

    void Update()
    {
        if (isMoving || m_stats.IsDead())
            return;
            
        attackCooldown = Mathf.Max(0f, attackCooldown - Time.deltaTime);
        
        // 히어로와 가까운 포지션(Left_1, Right_1)에서만 공격
        if (currentPosition == Position.Left_1 || currentPosition == Position.Right_1)
        {
            if (!IsAttacking && attackCooldown <= 0f)
            {
                int attackIndex = Random.Range(0, AttackNum);
                StartCoroutine(PlayAttackAnimation(attackIndex + 1));
                attackCooldown = Random.Range(4.0f, 6.0f);
            }
        }
        else
        {
            // 앞쪽 위치 계산
            Position frontPosition = GetFrontPosition(currentPosition);
            
            // 앞에 몬스터가 없으면 전진
            if (!IsMonsterAtPosition(frontPosition))
            {
                StartCoroutine(MoveToPosition(frontPosition));
            }
        }
    }

Hero 앞에 도달하면 공격하지만 그 외에는 앞에 몬스터가 있나 체크, 없으면 전진이 목표

private bool IsMonsterAtPosition(Position pos)
   {
       Monster[] monsters = FindObjectsOfType<Monster>();
       foreach (Monster monster in monsters)
       {
           if (monster != this && monster.currentPosition == pos && !monster.m_stats.IsDead())
               return true;
       }
       return false;
   }

몬스터 다 체크하고

 private IEnumerator MoveToPosition(Position newPos)
   {
       isMoving = true;

       // 목표 위치
       Vector3 targetPos = positionPoints[(int)newPos].position;

       // DOTween을 사용한 이동
       float moveSpeed = 0.5f;
       float duration = Vector3.Distance(transform.position, targetPos) / moveSpeed;

       // DOMove 트윈 생성 및 실행
       Tween moveTween = transform.DOMove(targetPos, duration)
           .SetEase(Ease.Linear).SetUpdate(UpdateType.Fixed);  // 선형 이동 (원하는 다른 이징 함수로 변경 가능)

       m_animator.SetBool("Run", true);  // 이동 애니메이션 시작

       // 트윈이 완료될 때까지 대기
       yield return moveTween.WaitForCompletion();
       m_animator.SetBool("Run", false);  // 이동 애니메이션 종료

       // 최종 위치 설정 및 상태 업데이트
       transform.position = targetPos;  // 정확한 위치 보장
       currentPosition = newPos;
       UpdateFacingDirection();

       isMoving = false;
   }

전진하며 된다.

몬스터 추가

애니메이션 오버라이드 컨트롤러로 만들고 나머지 애니메이션 덧씌우기만 하면 됨

해결한 문제

생각해보니 어차피 프레임 단위로 체크하면 몬스터의 공격 collider가 많을 필요가 없음. 타이밍에 맞게 collider만 켰다 끄면 되니 collider를 하나로 통일

profile
공부를 기록하는 공간

0개의 댓글