[240227]TIL

응징·2024년 2월 27일
0

TIL

목록 보기
33/36
post-thumbnail

TutorialGame

[오늘 한 일]
보스1 패턴 로직 구현 완료
보스2 움직임까지 구현 완료

보스1

플레이어 바라보는 로직

public class LookBoss : MonoBehaviour
{
    [Header("look")]
    public Transform target; //플레이어
    public float LookSpeed = 5f;


    public void LookTarget()
    {
        //바라보는 방향만 가져오기
        Vector3 targetDirection = (target.position - transform.position).normalized;

        //바라볼 방향을 쿼터니온 변수에 저장 (Lerp을 사용하기 위해서 쿼터니온 변수 쓰는것도 있음)
        Quaternion SetRotation = Quaternion.LookRotation(targetDirection);
        transform.rotation = Quaternion.Lerp(transform.rotation, SetRotation, LookSpeed * Time.deltaTime);
    }
}

보스1, 보스2 둘다 플레이어를 따라 바라보기 때문에 위의 로직은 상속을 줄 예정이다.

Lerp를 이용해 플레이어를 바라보는 딜레이를 줌

이동후 공격

로직 - 지정된 타겟포지션으로 이동후 타겟 포지션에 도착하면 n갈래로 일정한 각도를 가지고 공격하는 로직

타겟 포스로 이동하는 로직은 딜레이를 주며 타겟포지션을 지정해야하기 때문에 코루틴을 반복문을 사용하여 구현

이동

IEnumerator Move()
    {
        while(true)
        {
            yield return new WaitForFixedUpdate();
            Vector3 targetPosition = targetPos[_index].transform.position;
            targetPosition.y = transform.position.y; 
            Vector3 direction = (targetPosition - transform.position).normalized;

            //Vector3.Distance는 두점사이의 거리를 나타내는 메소드
            float distance = Vector3.Distance(transform.position, targetPos[_index].transform.position);
            if (distance < 0.5f)
            {
                transform.position = new Vector3(targetPos[_index].position.x, transform.position.y, targetPos[_index].position.z);
                _index++;

                ProjectileManager.instance.AttackProjectiles(data,gameObject);

                if (_index >= targetPos.Length)
                {
                    _index = 0;
                }
                yield return new WaitForSeconds(1.3f);
            }
            else
            {
                transform.Translate(direction * speed * Time.deltaTime, Space.World);
            }
        }
    }

공격

이후에 시간이 남으면 오브젝트 pool의 가능성을 염두해두고 ProjectileManager에서 공격 생성을 관리한다.

public void AttackProjectiles(AttackSO attackData, GameObject cur)
    {
        Vector3 directionTarget = (attackData.targetTransform.position - cur.transform.position).normalized;
        int numProjectiles = Random.Range(attackData.minProjectiles, attackData.maxProjectiles + 1);

        for (int i = 0; i < numProjectiles; i++)
        {
            // 현재 공격의 각도 계산
            float projectileAngle = attackData.angleBetweenProjectiles * (i - (numProjectiles - 1) / 2f);

            //Quaternion.AngleAxis는 주어진 백터만큼 회전하는 메소드
            //Vector3.up은 y축을 기준으로 회전하라는 뜻
            Quaternion rotation = Quaternion.AngleAxis(projectileAngle, Vector3.up);

            //쿼터니언 회전값과 타겟을바라보는 방향을 곱하기
            Vector3 projectileDirection = rotation * directionTarget;

            GameObject projectile = Instantiate(attackData.AttackPrefab, cur.transform.position, Quaternion.identity);
            projectile.transform.position = new Vector3(cur.transform.position.x, attackData.targetTransform.position.y,
                cur.transform.position.z);

            projectile.transform.parent = attackPrefebParent.transform;
            projectile.transform.rotation = Quaternion.LookRotation(projectileDirection);
        }
    }

그리고 생성한 오브젝트 내 스크립트에서 바라보는 방향으로 이동시킨다.

void Update()
    {
        _currentDuration -= Time.deltaTime;

        if(_currentDuration<=0)
        {
            _currentDuration = 0;

            //시간남으면 오브젝트 pool할 예정
            Destroy(gameObject);
        }

        _rigidbody.velocity = transform.forward * data.speed;
    }

보스2

보스2 또한 LookBoss 클래스를 상속받는다.

움직임

보스가 바라보는 반대방향으로 뛰되, x,z 값에 약간의 변수값을 +해줘 동적인 움직임을 방지하였다.

또한 일정이상 거리가 멀어지면 보스가 바라보는 방향으로 뛰게끔 구현하였다.

void Jump()
    {
        Vector3 minusForward = SetForward();
        _rigidbody.AddForce(minusForward, ForceMode.Impulse);
        _rigidbody.AddForce(Vector3.up * moveForce, ForceMode.Impulse);

    }

    Vector3 SetForward()
    {
        //약간의 랜덤값 주기위한 처리
        float randomX = Random.Range(-1f, 1f);
        float randomZ = Random.Range(-1f, 1f);

        Vector3 randomSet = new Vector3(randomX, 0f, randomZ);

        float distance = Vector3.Distance(transform.position, target.transform.position);
        if (distance > targetDistanse)
        {
            return (transform.forward + randomSet).normalized * moveForce;
        }
        else
        {
            return (-transform.forward + randomSet).normalized * moveForce;
        }
    }

트러블 슈팅

문제: 보스를 움직일때 이동하는 거리에서 차이가 생김.

랜덤값을 준것이 원인이라고 판단하여

Vector3 randomSet = new Vector3(randomX, 0f, randomZ).normalized; 하였으나, 해결되지 않았다.

원인:

forward

방향을 나타내는 것인데, 이것을 정확하게 이해 못한 문제이다.

(transform.forward + randomSet) * moveForce;

방향에서 랜덤으로 +1에 가깝게 나올때 이동하는 거리가 커지는 것이었다. transform.forward + randomSet까지가 방향 세팅이었는데, 랜덤값만 nomalized해봤자 의미가 없었다.

해결:

return (transform.forward + randomSet).normalized * moveForce;

따라서 위와같이 문제 해결

profile
Unity 개발 위주로 정리합니다

0개의 댓글