하나고치면 다른데서 문제일어남
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을 막 계속 늘려주는데
이러면 안된다... => 관리 시발 어케 할꺼임??
그래서 상태를 관리를 할 때는 State로 관리를 해야한다.
Define에다가 State를 프로퍼티로 관리를 하도록 만들어준다.
그리고 _isMoving부분을 State = Createture.Idle, Moving 으로 수정한다.
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으로 설정 되니까!!