일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 2022년
- 코딩 테스트
- 개인 프로젝트
- 프로그래머스
- 유니티
- todolist
- 4월
- 2024년
- 코딩 기초 트레이닝
- 입문
- 백준
- 기초
- 3월
- 단계별로 풀어보기
- 7월
- 2023년
- C/C++
- 5월
- 다이나믹 프로그래밍
- 수학
- 2월
- 1월
- c++
- 2025년
- 골드메탈
- 유니티 심화과정
- 게임 엔진 공부
- 개인 프로젝트 - 런앤건
- 자료 구조
- 10월
- Today
- Total
기록 보관소
[Unity/유니티] 기초-탑다운 2D RPG: 쯔꾸르식 액션 구현하기[B21] 본문
개요
유니티 입문과 독학을 위해서 아래 링크의 골드메탈님의 영상들을 보며 진행 상황 사진 또는 캡처를 올리고 배웠던 점을 요약해서 적는다.
현재는 영상들을 보고 따라하고 배우는 것에 집중할 것이며, 영상을 모두 보고 따라한 후에는 개인 프로젝트를 설계하고 직접 만드는 것이 목표다.
https://youtube.com/playlist?list=PLO-mt5Iu5TeYI4dbYwWP8JqZMC9iuUIW2
유니티 강좌 기초 채널 Basic
유니티 개발을 처음 시작하시는 입문자 분들을 위한 기초 채널. [ 프로젝트 ] B00 ~ B12 (BE1) : 유니티 필수 기초 B13 ~ B19 (BE2) : 2D 플랫포머 B20 ~ B26 (BE3) : 2D 탑다운 대화형 RPG B27 ~ B37 (BE4) : 2D 종스크롤
www.youtube.com
탑다운 2D RPG: 쯔꾸르식 액션 구현하기[B21]
1. 플레이어 십자 이동
//PlayerAction 스크립트 파일
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerAction : MonoBehaviour {
public float Speed;
Rigidbody2D rigid;
float h;
float v;
bool isHorizonMove;
void Awake () {
rigid = GetComponent<Rigidbody2D>();
}
void Update () {
//이동 값 설정
h = Input.GetAxisRaw("Horizontal");
v = Input.GetAxisRaw("Vertical");
//이동 버튼 확인
bool hDown = Input.GetButtonDown("Horizontal");
bool vDown = Input.GetButtonDown("Vertical");
bool hUp = Input.GetButtonUp("Horizontal");
bool vUp = Input.GetButtonUp("Vertical");
//이동 방향 체크
if (hDown || vUp) //수평
isHorizonMove = true;
else if (vDown || hUp) //수직
isHorizonMove = false;
}
void FixedUpdate() {
//수평, 수직 이동 결정
Vector2 moveVec = isHorizonMove ? new Vector2(h, 0) : new Vector2(0, v);
rigid.velocity = moveVec * Speed;
}
}
- 이전 글에서 대략적으로 만들어두었던 플레이어 이동은 일반적인 탑다운 2D RPG와는 달리 대각선 이동도 가능하다. 그래서 bool형 변수를 사용해서 입력받는 키에 따라 수직 또는 수평 이동만 가능하도록 했고, 만약 두 키가 동시에 눌러질 경우를 생각해서 GetButtonUp, 즉 반대 방향 버튼을 땠을 때의 경우에도 bool형 변수를 true 또는 false로 해준다.
2. 애니메이션 설정
- 다수의 애니메이션을 만들고, 이제는 Animator 창을 사용해서 애니메이션 전환을 설정해주어야한다
- 우선 방향 전환이 바로 되도록 Any State에 연결한다.
- 수직, 수평값을 받을 Int 형 매개변수 hAxisRaw와 vAxisRaw를 생성해서 각 Transition의 Conditions에서 사용한다. 만약 각 방향에 따라서 hAxisRaw와 vAxisRaw의 값이 0과 크거나/작거나 같다고 설정하면 된다.
- AnyState -> Player_Up_Walk : vAxisRaw Greater 0
- Player_Up_Walk -> Player_Up_Idle : vAxisRaw Equals 0
- AnyState -> Player_Down_Walk : vAxisRaw Less 0
- Player_Down_Walk -> Player_Down_Idle : vAxisRaw Equals 0
- AnyState -> Player_Right_Walk : hAxisRaw Greater 0
- Player_Right_Walk -> Player_Right_Idle : hAxisRaw Equals 0
- AnyState -> Player_Left_Walk : hAxisRaw Less 0
- Player_Left_Walk -> Player_Left_Idle : hAxisRaw Equals 0
- 추가로 이전에는 아래 애니메이션 전환 시간을 직접 조정했지만, 이는 경고를 발생시킬수도 있어서 그냥 간단하게 0을 입력하는 것이 좋다.
//PlayerAction 스크립트 파일
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerAction : MonoBehaviour {
public float Speed;
Rigidbody2D rigid;
Animator anim;
float h;
float v;
bool isHorizonMove;
void Awake () {
rigid = GetComponent<Rigidbody2D>();
anim = GetComponent<Animator>();
}
void Update () {
//이동 값 설정
h = Input.GetAxisRaw("Horizontal");
v = Input.GetAxisRaw("Vertical");
//이동 버튼 확인
bool hDown = Input.GetButtonDown("Horizontal");
bool vDown = Input.GetButtonDown("Vertical");
bool hUp = Input.GetButtonUp("Horizontal");
bool vUp = Input.GetButtonUp("Vertical");
//이동 방향 체크
if (hDown || vUp) //수평
isHorizonMove = true;
else if (vDown || hUp) //수직
isHorizonMove = false;
//애니메이션 전환
anim.SetInteger("hAxisRaw", (int)h);
anim.SetInteger("vAxisRaw", (int)v);
}
void FixedUpdate() {
//수평, 수직 이동 결정
Vector2 moveVec = isHorizonMove ? new Vector2(h, 0) : new Vector2(0, v);
rigid.velocity = moveVec * Speed;
}
}
- 설정이 끝나면 PlayerAction 스크립트 파일에 애니메이터 코드를 추가하고 테스트 해본다.
- Walk 애니메이션이 작동하지 않는 문제가 발생하는 이유는 매개변수 hAxisRaw와 vAxisRaw에 값이 계속해서 주어졌기 때문이다. 따라서 if문과 bool형 매개변수를 추가해서 해당 문제를 해결해야한다.
//PlayerAction 스크립트 파일
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerAction : MonoBehaviour {
public float Speed;
Rigidbody2D rigid;
Animator anim;
float h;
float v;
bool isHorizonMove;
void Awake () {
rigid = GetComponent<Rigidbody2D>();
anim = GetComponent<Animator>();
}
void Update () {
//이동 값 설정
h = Input.GetAxisRaw("Horizontal");
v = Input.GetAxisRaw("Vertical");
//이동 버튼 확인
bool hDown = Input.GetButtonDown("Horizontal");
bool vDown = Input.GetButtonDown("Vertical");
bool hUp = Input.GetButtonUp("Horizontal");
bool vUp = Input.GetButtonUp("Vertical");
//이동 방향 체크
if (hDown) //수평
isHorizonMove = true;
else if (vDown) //수직
isHorizonMove = false;
else if (hUp || vUp)
isHorizonMove = h != 0;
//애니메이션 전환
if (anim.GetInteger("hAxisRaw") != h) {
anim.SetBool("isChange", true);
anim.SetInteger("hAxisRaw", (int)h);
}
else if (anim.GetInteger("vAxisRaw") != v) {
anim.SetBool("isChange", true);
anim.SetInteger("vAxisRaw", (int)v);
}
else
anim.SetBool("isChange", false);
}
void FixedUpdate() {
//수평, 수직 이동 결정
Vector2 moveVec = isHorizonMove ? new Vector2(h, 0) : new Vector2(0, v);
rigid.velocity = moveVec * Speed;
}
}
- AnyState -> Player_****_Walk 방향의 Transition들은 모두 isChange = true일때로 설정한다. 그리고 위 코드처럼 스크립트 파일을 수정한다.
- 양쪽 버튼을 누른 상태로 하나만 때게되면 가만히 있는 상태로 걷는 문제가 발생해서 이동 방향 체크 항목도 조금 바뀌었다. 이전의 if문에서 hUp과 vUP을 따로 else if문으로 분리하고, 현재 AxisRaw 값에 따라 수평, 수직을 판단하여 해결하도록하였다.
3. 조사 액션
- 이전의 2D 플랫포머 게임처럼 플레이어를 중심으로한 Ray를 만들어조사/대화 등의 액션을 할 수 있도록 할 것이다.
- 그래서 NPC외에도 박스나 테이블같은 조사 가능한 오브젝트의 레이어를 다르게 설정하여 플레이어의 Ray가 닿았을때 구분할 수 있도록 한다.
//PlayerAction 스크립트 파일
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerAction : MonoBehaviour {
public float Speed;
Rigidbody2D rigid;
Animator anim;
Vector3 dirVec;
GameObject scanObject;
float h;
float v;
bool isHorizonMove;
void Awake () {
rigid = GetComponent<Rigidbody2D>();
anim = GetComponent<Animator>();
}
void Update () {
//이동 값 설정
h = Input.GetAxisRaw("Horizontal");
v = Input.GetAxisRaw("Vertical");
//이동 버튼 확인
bool hDown = Input.GetButtonDown("Horizontal");
bool vDown = Input.GetButtonDown("Vertical");
bool hUp = Input.GetButtonUp("Horizontal");
bool vUp = Input.GetButtonUp("Vertical");
//이동 방향 체크
if (hDown || vUp) //수평
isHorizonMove = true;
else if (vDown || hUp) //수직
isHorizonMove = false;
else if (hUp || vUp)
isHorizonMove = h != 0;
//애니메이션 전환
if (anim.GetInteger("hAxisRaw") != h) {
anim.SetBool("isChange", true);
anim.SetInteger("hAxisRaw", (int)h);
}
else if (anim.GetInteger("vAxisRaw") != v) {
anim.SetBool("isChange", true);
anim.SetInteger("vAxisRaw", (int)v);
}
else
anim.SetBool("isChange", false);
//레이 방향 판단하기
if (vDown && v == 1) //위쪽 방향
dirVec = Vector3.up;
else if (vDown && v == -1) //아래쪽 방향
dirVec = Vector3.down;
else if (hDown && h == -1) //왼쪽 방향
dirVec = Vector3.left;
else if (hDown && h == 1) //오른쪽 방향
dirVec = Vector3.right;
//오브젝트 스캔 출력
if (Input.GetButtonDown("Jump") && scanObject != null)
Debug.Log("this is : " + scanObject.name);
}
void FixedUpdate() {
//수평, 수직 이동 결정
Vector2 moveVec = isHorizonMove ? new Vector2(h, 0) : new Vector2(0, v);
rigid.velocity = moveVec * Speed;
//레이 사용하기
Debug.DrawRay(rigid.position, dirVec * 0.7f, new Color(0,1,0));
RaycastHit2D rayHit = Physics2D.Raycast(rigid.position, dirVec, 0.7f, LayerMask.GetMask("Object"));
if (rayHit.collider != null) {
scanObject = rayHit.collider.gameObject; //RayCast된 오브젝트를 변수로 저장
}
else
scanObject = null;
}
}
- Ray를 사용해서 Layer가 "Object"인 것에만 반응하도록 설정하고, 그 값을 변수에 저장해서 Ray가 닿고 있을때 Jump, 즉 스페이스바를 누르면 콘솔창에 출력되도록 설정했다.
'유니티 프로젝트 > 탑다운 2D RPG' 카테고리의 다른 글
[Unity/유니티] 기초-탑다운 2D RPG: 대화 애니메이션 느낌있게 만들기[B25] (0) | 2022.02.21 |
---|---|
[Unity/유니티] 기초-탑다운 2D RPG: 퀘스트 시스템 구현하기[B24] (0) | 2022.02.20 |
[Unity/유니티] 기초-탑다운 2D RPG: 대화 시스템 구현하기[B23] (0) | 2022.02.19 |
[Unity/유니티] 기초-탑다운 2D RPG: 대화창 UI 구축하기[B22] (0) | 2022.02.18 |
[Unity/유니티] 기초-탑다운 2D RPG: 도트 타일맵으로 쉽게 준비하기[B20] (0) | 2022.02.17 |