일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 멋쟁이사자처럼
- Pixelart
- 채색
- 반환원정대
- 장학팀
- 포토샵
- 애니메이션
- 노하우
- 드로잉
- 서포터즈
- photoshop
- 도트공부
- 픽셀 아트
- 자원순환보증금관리센터
- COSMO
- 스마일게이트
- 연습
- 개발
- 모작
- 도트
- 픽셀아트
- Aseprite
- 기초
- pixel art
- 에이세프라이트
- TOOL
- 인디게임 개발
- layer
- menu
- 드로잉 연습
- Today
- Total
소소한 나의 하루들
탑다운 2d RPG(2) - 쯔꾸르식 액션 구현하기 본문
출처: https://youtube.com/playlist?list=PLO-mt5Iu5TeYI4dbYwWP8JqZMC9iuUIW2&feature=shared
쯔꾸르 느낌으로 가려면, 대각선 이동을 제한해야한다.
#1. 십자 이동
플래그 변수 하나로 수평, 수직 이동을 결정한다. 수평, 수직 이동 버튼 이벤트를 변수로 저장한다.
이전에는 수평, 수직키를 같이 누르면 대각선으로 이동했었다.
public class PlayerAction : MonoBehaviour
{
public float Speed;
float h;
float v;
bool isHorizonMove;
Rigidbody2D rigid;
private void Awake()
{
rigid = GetComponent<Rigidbody2D>();
}
private void FixedUpdate()
{
//Move
Vector2 moveVec = isHorizonMove ? new Vector2(h, 0) : new Vector2(0, v);
rigid.velocity = moveVec * Speed;
}
// Update is called once per frame
void Update()
{
//Move Value
h = Input.GetAxisRaw("Horizontal");
v = Input.GetAxisRaw("Vertical");
//Check Button Down & Up
bool hDown = Input.GetButtonDown("Horizontal");
bool vDown = Input.GetButtonDown("Vertical");
bool hUp = Input.GetButtonUp("Horizontal");
bool vUp = Input.GetButtonUp("Vertical");
//Check Horizontal Move
if (hDown || vUp)
isHorizonMove = true;
else if (vDown || hUp)
isHorizonMove = false;
}
}
그런데 문제가 생긴다. 수평/수직 키를 같이 동시에 누르다가 한쪽을 떼면 그 자리에 정지하게 된다.
따라서 버튼 Up으로도 수평이동을 체크한다.
#2. 애니메이션
플레이어에게 들어가는 애니메이션도 넣어준다.
Any State는 현재 머물고 있는 State에 상관없이 조건에만 부합하면 상태전이를 발생시키는 State 이다.
상/하/좌/우 각각 하나의 방향에 대해 서있기, 걷기 총 2개의 State를 구성한다. (총 8개의 State)
기본 State는 플레이어가 아래방향으로 숨쉬는 Idle 모션이다. 상하좌우 어떤 키를 누르든지 애니메이션이 실행되어야한다.
따라서 Any State에 Player_Down_Walk 애니메이션을 연결시키고, 다시 Player_Down_Idle 애니메이션을 연결시킨다.
이렇게 상/하/좌/우 모두 애니메이션을 Any State → Walk → Idle로 연결시킨다.
그리고 수직, 수평 값을 받을 Int형 매개변수 hAxisRaw, vAxisRaw를 생성한다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerAction : MonoBehaviour
{
public float Speed;
float h;
float v;
bool isHorizonMove;
Rigidbody2D rigid;
Animator anime;
private void Awake()
{
rigid = GetComponent<Rigidbody2D>();
anime = GetComponent<Animator>();
}
private void FixedUpdate()
{
//Move
Vector2 moveVec = isHorizonMove ? new Vector2(h, 0) : new Vector2(0, v);
rigid.velocity = moveVec * Speed;
}
// Update is called once per frame
void Update()
{
//Move Value
h = Input.GetAxisRaw("Horizontal");
v = Input.GetAxisRaw("Vertical");
//Check Button Down & Up
bool hDown = Input.GetButtonDown("Horizontal");
bool vDown = Input.GetButtonDown("Vertical");
bool hUp = Input.GetButtonUp("Horizontal");
bool vUp = Input.GetButtonUp("Vertical");
//Check Horizontal Move
if (hDown || vUp)
isHorizonMove = true;
else if (vDown || hUp)
isHorizonMove = false;
//Animation
anime.SetInteger("hAxisRaw", (int)h);
anime.SetInteger("vAxisRaw", (int)v);
}
}
서로 타입이 다르면, 명시적 형 변환으로 처리한다. : 강제 형변환
※그런데 여기서 문제가, 여기서 걷는 모션을 재생해주지 않는다. 왜냐하면 -1값을 연속적으로 부여해서 Transition을 연속적으로 태우면 애니메이션이 작동되지 않는다.
그리고 Bool형 방향 변화 매개변수를 추가하여 확실히 한번만 실행되도록 변경한다. '만약 매개변수 hAxisRaw에 -1이 들어있다면 같은값을 다시 주지마' = 한번 값을 넣게되면 다른 값을 넣기 전까지는 변하지 않는다. / 계속 같은 값을 넣지 않는다.
만약 false라면 transition 전환이 안될 것이다. (값이 안들어가서 업데이트 안될것이다.)
//Check Horizontal Move
if (hDown || vUp)
isHorizonMove = true;
else if (vDown || hUp)
isHorizonMove = false;
//Check Horizontal Move
if (hDown)
isHorizonMove = true;
else if (vDown)
isHorizonMove = false;
else if (hUp || vUp)
isHorizonMove = h != 0;
양쪽 버튼 누른 상태에서 하나만 버튼 Up이면 문제가 발생한다. 따라서 현재 AxisRaw 값에 따라 수평/수직을 판단하여 해결한다. 확실하게 Down의 경우 isHorizonMove의 논리값을 결정해주고, Up의 경우 h가 0이 아니라면 true로 만들어준다.
#3. 조사 액션
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerAction : MonoBehaviour
{
public float Speed;
float h;
float v;
bool hDown;
bool vDown;
bool hUp;
bool vUp;
bool isHorizonMove;
Vector2 moveVec;
Rigidbody2D rigid;
Animator anime;
private void Awake()
{
rigid = GetComponent<Rigidbody2D>();
anime = GetComponent<Animator>();
}
private void FixedUpdate()
{
//Move
Vector2 moveVec = isHorizonMove ? new Vector2(h, 0) : new Vector2(0, v);
rigid.velocity = moveVec * Speed;
//Direction
if (vDown && v == 1)
moveVec = Vector2.up;
else if (vDown && v == -1)
moveVec = Vector2.down;
else if (hDown && h == 1)
moveVec = Vector2.right;
else if (hDown && h == -1)
moveVec = Vector2.left;
}
// Update is called once per frame
void Update()
{
//Move Value
h = Input.GetAxisRaw("Horizontal");
v = Input.GetAxisRaw("Vertical");
//Check Button Down & Up
hDown = Input.GetButtonDown("Horizontal");
vDown = Input.GetButtonDown("Vertical");
hUp = Input.GetButtonUp("Horizontal");
vUp = Input.GetButtonUp("Vertical");
//Check Horizontal Move
if (hDown)
isHorizonMove = true;
else if (vDown)
isHorizonMove = false;
else if (hUp || vUp)
isHorizonMove = h != 0;
//Animation
if (anime.GetInteger("hAxisRaw") != h)
{
anime.SetBool("IsChange", true);
anime.SetInteger("hAxisRaw", (int)h);
}
else if (anime.GetInteger("vAxisRaw") != v)
{
anime.SetBool("IsChange", true);
anime.SetInteger("vAxisRaw", (int)v);
}
else
anime.SetBool("IsChange", false);
//Ray
Debug.DrawRay(rigid.position, moveVec * 0.7f, new Color(0, 1, 0));
}
}
앞에 있는 사물을 스캔하는 것을 해본다.
이렇게 스캔하는 로직은 RayCast를 사용하는 것이 일반적이다. 현재 바라보고 있는 방향 값을 가진 변수가 필요하다. (방향 벡터 dirVec)
캐릭터가 바라보는 방향으로 Ray가 그려진다.
Debug.DrawRay(출발지점, 벡터(방향*힘(길이)), 색상);
RaycastHit2D rayHit = Physics2D.RayCast(출발지점, 방향벡터, 힘(길이), LayerMask.GetMask("레이어명"));
DrawRay로 미리보고, RayCast를 구현하면 쉽다.
RayCast를 구현할 때 플레이어의 'Collider(충돌박스)'는 무시해야한다. 따라서 레이어를 사용한다.
→레이어를 생성해서 '조사가능한 오브젝트'를 다른 Layer로 설정한다. (플레이어 제외 나머지)
RaycastHit2D rayHit = Physics2D.Raycast(rigid.positoin, dirVec, 0.7f, LayerMask.GetMask(”Object”));
if (rayHit.collider ≠ null)
빔이 충돌한 오브젝트가 null이 아니면 = 무엇인가 충돌하여 값 생성됨
RayCast된 오브젝트를 변수로 저장하여 활용한다. (변수 scanObject)
만약 충돌된 오브젝트가 없다면, null 값이다. 충돌한 오브젝트의 이름을 출력해본다.
'개발 > 유니티' 카테고리의 다른 글
탑다운 2d RPG(4) - 대화 시스템 구현하기 (0) | 2024.01.31 |
---|---|
탑다운 2d RPG(3) - 대화창 UI 구축하기 (0) | 2024.01.30 |
탑다운 2d RPG(1) - 도트 타일맵으로 쉽게 준비하기 (0) | 2024.01.29 |
2d 플랫포머(최종) - 피드백 추가 및 개선사항 (0) | 2024.01.27 |
유니티 코루틴(Coroutine) / 서브루틴(Sub Routine) +α (0) | 2024.01.27 |