인텔리킴의 Unity Studying & Game Analysis
10. 유니티 2D 게임 제작 - 이동 본문
물리 이동
먼저 플레이어가 쓰러지지 않도록 Z방향으로의 회전을 멈춤
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMove : MonoBehaviour
{
Rigidbody2D rigid;
void Start()
{
rigid = GetComponent<Rigidbody2D>();
}
void Update()
{
float h = Input.GetAxisRaw("Horizontal");
rigid.AddForce(new Vector2(h, 0), ForceMode2D.Impulse );
}
}
위 코드로 이동을 구현하면 플레이어가 가속을 무한으로 받는다는 문제점이 생김
void FixedUpdate()
{
//물리 이동
float h = Input.GetAxisRaw("Horizontal");
rigid.AddForce(Vector2.right * h, ForceMode2D.Impulse );
//오른쪽 최대 속도
if(rigid.velocity.x > maxSpeed)
{
rigid.velocity = new Vector2(maxSpeed, rigid.velocity.y);
}
//왼쪽 최대 속도
if(rigid.velocity.x < maxSpeed * -1)
{
rigid.velocity = new Vector2((maxSpeed * -1), rigid.velocity.y);
}
}
rigid.velocity : 리지드바디의 현재 속도
오브젝트 이동 코드를 다음과 같이 if 문을 통해 구현하면 이동속도에 제약을 줄 수 있음
마찰력 제거
오브젝트엔 기본적으로 마찰력이 있음
2D 오브젝트는 2D material을 적용해야함
하지만 이 방법을 쓰면 플레이어가 빙판길처럼 쭈욱 지나가는 문제점이 있음
플레이어의 저항력을 수정해서 해결
저항 수치 설정
Linear Drag : 공기 저항
*공기 저항을 너무 크게 잡으면 플레이어가 떨어질때 문제가 생김
하지만 위 마찰력 계수를 추가해도 약간의 밀림 현상은 남아있음
코드를 통해 해결 가능
//이동 멈출때 속도
void Update()
{
if (Input.GetButtonUp("Horizontal"))
{
rigid.velocity = new Vector2((0.5f * rigid.velocity.normalized.x), rigid.velocity.y);
}
}
Update는 단발적인 키 입력에 좋음
FixedUpdate는 지속적인 키 입력에 좋음
*단발적인 키 입력에 FixedUpdate를 사용하면 가끔 키가 씹히는 현상이 발생
nomalized : 벡터 크기가 1인 상태(단위 백터)
단위 벡터를 멈출때 속도에 곱함으로써 가는 방향으로 멈춤 속도 조절 가능
이동에 애니메이션 적용
플레이어가 움직일떄 방향 변환
플레이어가 왼쪽을 바라볼땐 스프라이트가 반대로 돌아가게 해야함
//방향 전환
if (Input.GetButtonDown("Horizontal")) {
spriteRenderer.flipX = Input.GetAxisRaw("Horizontal") == -1;
}
Update 함수에 스프라이트 랜더러 이동시 방향에 따라 flipX 가 적용되게 함
플레이어 움직일때 애니메이션 적용
1. 플레이어의 기본 애니메이션과 다른 애니메이션 사이에 Transition을 연결 해줌
Transition : 애니메이션 상태를 옮겨가는 통로
2. Parameters에서 애니메이터 매개변수 추가
애니메이터 매개변수 : 상태를 변경할 떄 필요한 변수
3. Condition에서 매개변수를 조건으로 추가해줌
4. 애니메이션 타임라인을 조절해서 애니메이션 겹구간 조절
2D 게임에선 거의 없는것으로 설정
5. Has Exit Time 설정
Has Exit Time : 애니메이션이 끝날때까지 상태를 유지함
if (rigid.velocity.normalized.x == 0)
{
animator.SetBool("isWalking", false);
}
else
{
animator.SetBool("isWalking", true);
}
6. Update 문에 조건문으로 애니메이션 매개변수의 값을 변경 할 수 있도록 Animator 변수를 삽입
animator.SetBool("변수", false); : 컴포넌트의 변수 값을 변경
하지만 위 코드를 적용하면 플레이어의 속도가 완전히 0이 되어야만 멈춤 애니메이션으로 변환하는 문제가 생김
Mathf : C#에서 수학 관련 함수를 제공하는 클래스
Mathf.Abs(변수) : 변수에 절댓값을 적용
정리
플레이어 움직임 애니메이션 전체 코드
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMove : MonoBehaviour
{
public float maxSpeed;
Rigidbody2D rigid;
SpriteRenderer spriteRenderer;
Animator animator;
void Start()
{
rigid = GetComponent<Rigidbody2D>();
spriteRenderer = GetComponent<SpriteRenderer>();
animator = GetComponent<Animator>();
}
void Update()
{
//정지할 때 속도
if (Input.GetButtonUp("Horizontal"))
{
rigid.velocity = new Vector2((0.5f * rigid.velocity.normalized.x), rigid.velocity.y);
}
//방향 전환
if (Input.GetButtonDown("Horizontal")) {
spriteRenderer.flipX = Input.GetAxisRaw("Horizontal") == -1;
}
//애니메이션 전환
if (Mathf.Abs(rigid.velocity.x) < 0.5f)
{
animator.SetBool("isWalking", false);
}
else
{
animator.SetBool("isWalking", true);
}
}
void FixedUpdate()
{
//물리 이동
float h = Input.GetAxisRaw("Horizontal");
rigid.AddForce(Vector2.right * h, ForceMode2D.Impulse );
//오른쪽 최대 속도
if(rigid.velocity.x > maxSpeed)
{
rigid.velocity = new Vector2(maxSpeed, rigid.velocity.y);
}
//왼쪽 최대 속도
else if(rigid.velocity.x < maxSpeed * -1)
{
rigid.velocity = new Vector2((maxSpeed * -1), rigid.velocity.y);
}
}
}
rigid.velocity : 리지드바디의 현재 속도
2D 오브젝트는 2D 머테리얼을 적용해야함
또한 머테리얼과 리지드바디에서 오브젝트의 마찰력 설정 가능
nomalized : 벡터 크기가 1인 상태(단위 백터)
애니메이션 정리 : Has Exit Time 설정, 겹구간 설정, 매개변수 설정
animator.SetBool("변수", false); : 컴포넌트의 변수 값을 변경
Mathf : C#에서 수학 관련 함수를 제공하는 클래스
Mathf.Abs(변수) : 변수에 절댓값을 적용
'게임 개발 일지 > 유니티 엔진 공부' 카테고리의 다른 글
12. 유니티 2D 게임 제작 - 타일맵으로 지형 만들기 (0) | 2024.04.19 |
---|---|
11. 유니티 2D 게임 제작 - 점프 구현 (0) | 2024.04.19 |
9. 유니티 2D 게임 제작-애니메이션 (0) | 2024.04.19 |
8. 유니티 2D 게임 제작-프로젝트 준비 (0) | 2024.04.19 |
7. 공 굴리기 게임 만들기 (0) | 2024.04.19 |