[Unity] 기본적인 부메랑 로직만들기

조팽이·2024년 3월 29일

Unity

목록 보기
5/13

여기저기 구글링을 해봤지만 뭔가 명료하게 부메랑로직을 알려주는 정보가 많이 없어서 직접 만들어 보게 되었다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Boomerang : MonoBehaviour
{
    Rigidbody2D rb;
    public Player player;
    float timer = 0f;
    bool isShoot = false;
    bool isComing = false;
    Vector2 pp;
    void Awake() {
        rb = GetComponent<Rigidbody2D>();
    }

    void FixedUpdate() {
        Vector2 curVec = player.inputVec.normalized;
        if (isShoot) {
            timer += Time.fixedDeltaTime;
        }

        if (Input.GetKey(KeyCode.Space) && !isShoot && !isComing) {
            pp = curVec;
            rb.AddForce(pp * 5f, ForceMode2D.Impulse);
            isShoot = true;
            
        }

        if (timer >= 0.5f && isShoot) {
            rb.AddForce(-pp * 3f, ForceMode2D.Impulse);
            timer = 0f;
        }

        if(rb.velocity.magnitude <= 0.3f && isShoot) {
            isComing = true;
            isShoot = false;
            rb.velocity = Vector2.zero;
        }

        if (isComing) {
            Vector3 dir = player.transform.position - transform.position;
            dir = dir.normalized;
            rb.MovePosition(transform.position + dir * Time.fixedDeltaTime * 8f);
        }
    }

    void OnTriggerEnter2D(Collider2D collision) {
        if (!collision.CompareTag("Player")) return;
        gameObject.SetActive(false);
    }
    void OnEnable() {
        isShoot = false;
        isComing = false;
    }
}

위는 전체 코드이다. isShoot변수는 부메랑이 나간 상황인지를 나타내고 isComing변수는 부메랑이 돌아오고 있는지를 나타내는 변수이다. rigidbody를 이용했다.

if (Input.GetKey(KeyCode.Space) && !isShoot && !isComing) {
            pp = curVec;
            rb.AddForce(pp * 5f, ForceMode2D.Impulse);
            isShoot = true;
            
   }

먼저 이 코드를 보면

  1. 스페이스바를 누르고
  2. 부메랑을 쏘기 전이며
  3. 부메랑이 돌아오지 않을 때 실행된다.

pp 에 현재 플레이어의 진행방향을 담고, 부메랑에 그 방향으로 5f만큼의 힘을 가한다. 그리고 발사되었으므로 isShoot을 true로 만든다.

if (timer >= 0.5f && isShoot) {
            rb.AddForce(-pp * 3f, ForceMode2D.Impulse);
            timer = 0f;
        }

이 코드를 보면 발사 후 0.5초가 될 때마다 pp의 반대 방향 즉 -pp방향으로 3f만큼의 힘을 계속 가하게 된다. 이렇게 되면 0.5초마다 자연스럽게 부메랑의 속도가 줄어들게 된다.

if(rb.velocity.magnitude <= 0.3f && isShoot) {
           isComing = true;
           isShoot = false;
           rb.velocity = Vector2.zero;
       }

부메랑의 속도의 크기가 0.3f보다 줄어들고 isShoot중이라면 부메랑이 돌아오게 만든다. 그러기 위해선 isComing을 true로 바꾸고 부메랑의 순간 속도를 0으로 만든다.

if (isComing) {
           Vector3 dir = player.transform.position - transform.position;
           dir = dir.normalized;
           rb.MovePosition(transform.position + dir * Time.fixedDeltaTime * 8f);
       }

isComing이 true라면, 즉 돌아오는 중이라면 부메랑에서 플레이어까지의 벡터를 프레임마다 구하고 그 방향으로 부메랑이 프레임마다 계속해서 돌아오게 만든다.

중간중간 속도나 힘 등이 하드코딩 되어있지만 이 값들은 기호에 맞게 언제든지 변경이 가능하다.

profile
게임개발자

0개의 댓글