여기저기 구글링을 해봤지만 뭔가 명료하게 부메랑로직을 알려주는 정보가 많이 없어서 직접 만들어 보게 되었다.
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;
}
먼저 이 코드를 보면
- 스페이스바를 누르고
- 부메랑을 쏘기 전이며
- 부메랑이 돌아오지 않을 때 실행된다.
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라면, 즉 돌아오는 중이라면 부메랑에서 플레이어까지의 벡터를 프레임마다 구하고 그 방향으로 부메랑이 프레임마다 계속해서 돌아오게 만든다.
중간중간 속도나 힘 등이 하드코딩 되어있지만 이 값들은 기호에 맞게 언제든지 변경이 가능하다.