개발일지/TIL(Today I Learned)

24-10-22

프린스 알리 2024. 10. 22.

내일배움캠프 Node.js 사전캠프 14일차

1. ZEP에서 이루어진 팀단위 JavaScript 스터디

(1) 스터디 계획

팀장님의 도움을 받아 아주 기본적인 수준의 유니티 구문들을 살펴보기로 했다. 오늘 학습의 바탕이 되는 내용들은 아래 블로그(팀장님의 블로그)에 자세히 정리가 되어 있다.

 

Unity 2D 유용한 구문 :: Notfound404
Unity 2D 유용한 기능들 :: Notfound404

 

Unity 2D 유용한 기능들

2D 회전```Vector2 targetPosition = target.position;Vector2 myPosition = transform.position;Vector2 direction = (targetPosition - myPosition).nomalizefloat angle = Mathf.Atan2(direction.y,direction.x) * Mathf.Rad2Deg;Quaternion rotation 

explosion149.tistory.com

 

 

Unity 2D 유용한 구문

//해당 기능은 Rendering 되는 Sprite 혹은 MeshRenderer등이 있어야 작동을 한다.OnBecameInvisible(){} //화면에서 사라졌을경우 실행//화면에서 사라졌을때 Editor환경에서는 Scene view 와 Game view 를 //동시에 볼

explosion149.tistory.com

 

오늘 우리는 유니티에서 널리 쓰이는 구문을 이용하여 테스트용 게임을 만들었고 그 사용법을 익혀보는 시간을 가졌다.

 

(2) 스터디 진행 과정

크게 세 가지 주요한 기능들을 구현하는 법을 알아봤다. 
(1) 캐릭터의 이동
(2) 캐릭터와 다른 오브젝트와의 상호작용(충돌 등…)
(3) 캐릭터의 점프

 

1) 캐릭터의 이동

캐릭터를 이동시키는 방법에는 여러가지가 있다. 아주 기본적인 방법은 아래와 같이 위치(transform.position)에 속도(방향과 크기를 가진 벡터값)와 시간을 곱한 값을 더해주는 것이다.(거리 = 속도 * 시간)

transform.position = transform.position + direction * Time.deltaTime;

// 비슷한 형태  
transform.transform.Translate(direction * Time.deltaTime,Space.World);  
//Space.Self or Space.World 등으로 자신 또는 월드 좌표를 기준으로 이동이 가능하다.

→ 단점 가끔 벽을 뚫거나 떨림 현상이 심하다.
→ 장점 비용이 가장 저렴하다.

 

그러나 유니티에서 제공하는 RigidBody 컴포넌트를 사용하는 방식도 존재한다.

RigidBody2D rb = GetComponent<Rigidbody2D>();

rb.MovePosition(rb.position + direction * moveSpeed * Time.fixedDeltaTime);  

 

혹은 Get.Axis와 Input.GetKeyDown을 이용해 키보드로부터 좌표 변화를 입력 받고 RigidBody2D 컴포넌트와 Update 함수를 통해 캐릭터를 직접 조종하여 움직일 수도 있다.

public Vector2 direction;
public Rigidbody2D rb;
public Transform camTrnsform;
public Vector3 camOffset;

private void inputAndMove()
{
    // WASD, 방향키 등의 입력 시간을 방향에 따라 입력해주는 함수
    float x = Input.GetAxis("Horizontal");
    direction = new Vector2(x, 0);
}

private void FixedUpdate()
{
    rb.velocity = new Vector2(direction.x * moveSpeed, rb.velocity.y);
    var myPos = transform.position;
    camTrnsform.position = new Vector3(myPos.x, myPos.y, camTrnsform.position.z) + camOffset; // 카메라가 플레이어를 찍을 수 있게 + 카메라의 오프셋 설정
}

 

2) 캐릭터와 다른 오브젝트와의 상호작용(충돌 등…)

오브젝트의 상호작용에는 크게 두 종류가 있다. Trigger와 Collision.
Trigger와 Collision의 차이는 직접적인 충돌의 유무이다.
Trigger는 기본적으로 관통을 한다. Collision은 충돌체와 물리적 상호작용을한다.

Collision과 Trigger는 각각 2D 와 3D가 있는데 3D 가 기본이며 3D는 따로 적지 않는다. 2D 는 적어줘야 한다. 차이점은 Rigidbody와 Collider 모두 2D 붙은 별도의 컴포넌트를 사용한다.

A Object 와 B Object 가 서로 Trigger상태가 아니라면 충돌시 A와 B는 서로를 밀어낼것이다.
A Object와 B Object 가 어느 하나라도 Trigger상태라면 충돌시 A와 B는 서로를 관통한다.
Trigger2D를 인식 하려면 Collider2D 가 필요하고 해당 콜라이더의 isTrigger = true 상태여야 한다.

// Trigger 진입 
void OnTriggerEnter2D(Collider2D other){} 

// Trigger 빠져나감 
void OnTriggerExit2D(Collider2D other) {} 

// Trigger 상태 유지 
void OnTriggerStay2D(Collider2D other) {} 

// 물리적 충돌 시작 
void OnCollisionEnter2D(Collision2D other) {} 

// 물리적 충돌 끝 
void OnCollisionExit2D(Collision2D other) {} 

// 물리적 충돌 진행중 
void OnCollisionStay2D(Collision2D other) {}
 

3) 캐릭터의 점프

위에서 배운 내용을 이용하면 캐릭터가 지면 위에서 점프를 할 수 있도록 구현이 가능하다.

public bool IsJump;
public bool IsGround;
public float JumpInterval = 0.5f; // 0.5의 딜레이를 가지고 점프가 가능했으면 좋겠다.
public float currentJumpTime = 0f; // 점프한 시각을 저장해주는 변수
public float JumpPower = 7f;

void Update()
{
    inputAndMove();
    if (IsJump && IsGround)
    {
        if (currentJumpTime <= Time.time) // Time.time : 게임 엔진상에서 흐른 시간
        {
            currentJumpTime = Time.time + JumpInterval;
            rb.velocity = new Vector2(rb.velocity.x, JumpPower);
        }
    }
}
private void inputAndMove()
{
    // WASD, 방향키 등의 입력 시간을 방향에 따라 입력해주는 함수
    float x = Input.GetAxis("Horizontal");

    direction = new Vector2(x, 0);

    IsJump = Input.GetKeyDown(KeyCode.Space);
}
private void FixedUpdate()
{
    rb.velocity = new Vector2(direction.x * moveSpeed, rb.velocity.y);
    var myPos = transform.position;
    camTrnsform.position = new Vector3(myPos.x, myPos.y, camTrnsform.position.z) + camOffset; // 카메라가 플레이어를 찍을 수 있게 + 카메라의 오프셋 설정
}
private void SetGround(Collision2D other, bool _isGround)
{
    if (!other.gameObject.CompareTag("Ground")) return;
    IsGround = _isGround;
}
private void OnCollisionStay2D(Collision2D other) // stay 상태일 때만(이벤트 발생) 진행되는 함수
{
    SetGround(other, true);
}
private void OnCollisionExit2D(Collision2D other) // Collision이 끝난 뒤에 진행되는 함수
{
    SetGround(other, false);
}
private void OnTriggerEnter(Collider other) 
// 아이템을 먹는다 = 통과한다. = trigger
{
    if(!other.CompareTag("Item"))
    {
        return;
    }
    Destroy(other.gameObject);
}

 

(3) 인사이트

오늘은 앞서 정리했듯 (1) 캐릭터의 이동 (2)오브젝트와의 상호작용 (3) 점프 기능을 유니티와 C#을 통해 구현하는 방법에 대해 공부했다. 하지만 위에서 작성한 코드에는 치명적인 맹점이 있다. 아래 사진처럼 캐릭터에게 Circle Collider 2D 컴포넌트를 부여해주었기 때문에 발이 아닌 곳이 닿아도 점프가 되어버린다.

 

 

지금처럼 평평한 그라운드를 달린다면 상관 없겠지만 그라운드 오브젝트가 다른 형태로 나타난다면 그에 닿았을 때 원치 않게 튕겨져 나올 가능성이 크다. 따라서 지금의 방식을 개선할 필요가 있다. 그 방법에 대해선 내일 이루어질 스터디에서 다뤄보도록 하겠다.

'개발일지 > TIL(Today I Learned)' 카테고리의 다른 글

24-10-24  (2) 2024.10.24
24-10-23  (1) 2024.10.23
24-10-21  (1) 2024.10.21
24-10-18  (1) 2024.10.18
24-10-17  (3) 2024.10.17

댓글