Controller 정리

CJB_ny·2022년 5월 12일
0

2D_Project

목록 보기
9/23
post-thumbnail

프로그래밍은 두더지 게임

하나고치면 다른데서 문제일어남

Break Point잡으면서 어디서 에러? (핵심)


컨트롤러 분리

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static Define;

public class CreatureController : MonoBehaviour
{
    public float _speed = 5.0f;

    protected Vector3Int _cellPos = Vector3Int.zero;
    protected bool _isMoving = false;
    protected Animator _animator;

    MoveDir _dir = MoveDir.Right;
     
    public MoveDir Dir
    {
        get { return _dir; }
        set
        {
            if (_dir == value)
                return;

            switch (value)
            {
                case MoveDir.Up:
                    _animator.Play("WALK_BACK");
                    transform.localScale = new Vector3(1.0f, 1.0f, 1.0f);
                    break;
                case MoveDir.Down:
                    _animator.Play("WALK_FRONT");
                    transform.localScale = new Vector3(1.0f, 1.0f, 1.0f);
                    break;
                case MoveDir.Left:
                    _animator.Play("WALK_RIGHT");
                    transform.localScale = new Vector3(-1.0f, 1.0f, 1.0f);
                    break;
                case MoveDir.Right:
                    _animator.Play("WALK_RIGHT");
                    transform.localScale = new Vector3(1.0f, 1.0f, 1.0f);
                    break;
                case MoveDir.None:
                    if (_dir == MoveDir.Up)
                    {
                        _animator.Play("IDLE_BACK");
                        transform.localScale = new Vector3(1.0f, 1.0f, 1.0f);
                    }
                    else if (_dir == MoveDir.Down)
                    {
                        _animator.Play("IDLE_FRONT");
                        transform.localScale = new Vector3(1.0f, 1.0f, 1.0f);
                    }
                    else if (_dir == MoveDir.Left)
                    {
                        _animator.Play("IDLE_RIGHT");
                        transform.localScale = new Vector3(-1.0f, 1.0f, 1.0f);
                    }
                    else
                    {
                        _animator.Play("IDLE_RIGHT");
                        transform.localScale = new Vector3(1.0f, 1.0f, 1.0f);
                    }
                    break;
            }

            _dir = value;
        }
    }

    void Start()
    {
        Init();
    }
    void Update()
    {
        UpdateController();
    }
    protected virtual void Init()
    {
        _animator = GetComponent<Animator>();
        Vector3 pos = Managers.Map.CurrentGrid.CellToWorld(_cellPos) + new Vector3(0.5f, 0.5f, 0);
        transform.position = pos;
    }

    protected virtual void UpdateController()
    {
        UpdatePosition();
        UpdateIsMoving();
    }

    // 스르륵 이동하는 것을 처리
    void UpdatePosition()
    {
        if (_isMoving == false)
            return;

        Vector3 destPos = Managers.Map.CurrentGrid.CellToWorld(_cellPos) + new Vector3(0.5f, 0.5f, 0);
        Vector3 moveDir = destPos - transform.position;

        // 도착여부 체크
        float dist = moveDir.magnitude; // 목적지 까지의 거리 
        if (dist < _speed * Time.deltaTime) // 한번에 이동할 수 있는 _speed * Time.deltaTime 이 크기보다 dist가 작다고 하면은 도착한것임
        {
            transform.position = destPos;
            _isMoving = false;
        }
        else //아직 도착안함.
        {
            transform.position += moveDir.normalized * _speed * Time.deltaTime;
            _isMoving = true;
        }
    }

    // 이동가능한 상태일 떄, 실제 좌표를 이동 시킴.
    void UpdateIsMoving()
    {
        if (_isMoving == false && _dir != MoveDir.None)
        {
            Vector3Int destPos = _cellPos;

            switch (_dir)
            {
                case MoveDir.Up:
                    destPos += Vector3Int.up;
                    break;
                case MoveDir.Down:
                    destPos += Vector3Int.down;
                    break;
                case MoveDir.Left:
                    destPos += Vector3Int.left;
                    break;
                case MoveDir.Right:
                    destPos += Vector3Int.right;
                    break;
            }

            if (Managers.Map.CanGo(destPos))
            {
                _cellPos = destPos;
                _isMoving = true;
            }
        }
    }
}

이렇게 CreatureController라고 공용 부분 만들어서

공유성 있도록 사용하도록 하자.

각각의 컨트롤러 부분에서 공통되는거 삭제하고

해서

컨트롤러를 분리하는데 까지는 ㅇㅋ.

기획적인 부분

우리도

움직이지 못할 때 스킬을 쓰거나 평타를 때리는 식으로 기획을 할 것이다.

상태관리

그런데

뭐 하고있을 때는 뭐 하면 안되고 공격을 할 때는 다른것을 하면 안되니까

bool _isSkill;
bool _isCinematic;

이런식으로 boolean을 막 계속 늘려주는데

이러면 안된다... => 관리 시발 어케 할꺼임??

Boolean 늘리기 금지!

그래서 상태를 관리를 할 때는 State로 관리를 해야한다.

Define에다가 State를 프로퍼티로 관리를 하도록 만들어준다.

그리고 _isMoving부분을 State = Createture.Idle, Moving 으로 수정한다.

애니매이션 수정 작업

Idle 수정

public MoveDir Dir
    {
        get { return _dir; }
        set
        {
            if (_dir == value)
                return;

            switch (value)
            {
                case MoveDir.Up:
                    _animator.Play("WALK_BACK");
                    transform.localScale = new Vector3(1.0f, 1.0f, 1.0f);
                    break;
                case MoveDir.Down:
                    _animator.Play("WALK_FRONT");
                    transform.localScale = new Vector3(1.0f, 1.0f, 1.0f);
                    break;
                case MoveDir.Left:
                    _animator.Play("WALK_RIGHT");
                    transform.localScale = new Vector3(-1.0f, 1.0f, 1.0f);
                    break;
                case MoveDir.Right:
                    _animator.Play("WALK_RIGHT");
                    transform.localScale = new Vector3(1.0f, 1.0f, 1.0f);
                    break;
                case MoveDir.None:
                    if (_dir == MoveDir.Up)
                    {
                        _animator.Play("IDLE_BACK");
                        transform.localScale = new Vector3(1.0f, 1.0f, 1.0f);
                    }
                    else if (_dir == MoveDir.Down)
                    {
                        _animator.Play("IDLE_FRONT");
                        transform.localScale = new Vector3(1.0f, 1.0f, 1.0f);
                    }
                    else if (_dir == MoveDir.Left)
                    {
                        _animator.Play("IDLE_RIGHT");
                        transform.localScale = new Vector3(-1.0f, 1.0f, 1.0f);
                    }
                    else
                    {
                        _animator.Play("IDLE_RIGHT");
                        transform.localScale = new Vector3(1.0f, 1.0f, 1.0f);
                    }
                    break;
            }

            _dir = value;
        }
    }

이렇게 애니매이션을 관리를 하고있었는데..

State에 넣어서 관리를 할지 아니면 그대로 둘지.. 고민이 되면

=> 공용부분에 넣고 관리를 하는게 좋다.

공용 부분이 뭐노??

이렇게 공용으로 만들어주고 상속받는 애들중에서 수정하고 싶은 애들은 수정을 할 수 있게끔 만들어 준다.

이중 if문 안에 switch들어갈 꺼라 이중 switch안씀 (가독성 때문에)

그래서 Idle일 경우 이렇게 해주고

localScale이라는 것을 사용하여 이렇게 해주고있는데

이게 방법이 하나 더 있기는 하다.


LocalScale
https://ssabi.tistory.com/25


여기 Flip이라는 기능을 이용해서

Right, Left를 관리를 해도 무방하다.

그래서 SpriteRenderer받아와서 이렇게 해주도록 하자

-> 가독성!

걷는 부분 수정

최초의 상태 이렇게 해주고

UpdatePosition에서

_state = Creature.Idle로 강제로 셋팅 해준 상태로

유니티 실행해보면

애니매이션 부분을 업뎃 안해주어서

가는 방향대로 그대로 뛰는 애니매이션이 재생이된다.

따라서 우리가 강제적으로 애니매이션 업데이트를 해주어야함

-> 언제? -> _dir이 None일때 == 아무것도 입력을 받지 않고 있을 경우

왜냐하면

PlayerController에서 아무것도 입력 안 받으면

Dir = None으로 설정 되니까!!

profile
공부 일기장으로 변해버린 블로그 (https://cjbworld.tistory.com/ <- 이사중)

0개의 댓글