Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
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
Archives
Today
Total
관리 메뉴

인텔리킴의 Unity Studying & Game Analysis

10. 유니티 2D 게임 제작 - 이동 본문

게임 개발 일지/유니티 엔진 공부

10. 유니티 2D 게임 제작 - 이동

인텔리킴 2024. 4. 19. 16:29

물리 이동

 

 

먼저 플레이어가 쓰러지지 않도록 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을 적용해야함

 

마찰력 0으로 설정
Box Collider 2D 에 적용

하지만 이 방법을 쓰면 플레이어가 빙판길처럼 쭈욱 지나가는 문제점이 있음

플레이어의 저항력을 수정해서 해결

 

저항 수치 설정 

저항 수치

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(변수) : 변수에 절댓값을 적용