- 총알
지금까지 플레이어의 기본 이동 로직을 짜봤다.
이제 간단하게 플레이어가 총알을 쏴보게 하겠다.
먼저 간단하게 플레이어의 자식 오브젝트로 총을 든것처럼 만들자.

※ 총의 SpriteRenderer에서 order값을 1로 해야한다.
그리고 총알 오브젝트도 만들어주겠다.


※ CircleCollider는 삭제해주길 바란다.
총알을 만들고 나면 Bullet 스크립트를 만들어서 총알 오브젝트에다 붙이도록 하겠다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bullet : MonoBehaviour
{
public float speed;
public Vector2 dir; // 1)
private void Start()
{
Destroy(gameObject, 3); // 2)
}
private void Update()
{
transform.Translate(dir.normalized * speed * Time.deltaTime); // 3)
}
}
총알이 나갈 방향을 정하는 변수이다. dir은 direction의 약자이며, 나중에 총알을 생성할때 초기화 해줄것이다.
유니티의 MonoBehaviour에 있는 Destory 함수이다. 매개변수가 총 두개들어가는데 첫번째는 없애버릴 오브젝트 또는 스크립트, 두번째는 몇초후에 없앨지 결정한다.
스크립트에서는 Bullet 컴포넌트가 부착된 오브젝트를 없앴다. 총알이 생성되고나서 없어지지 않으면 성능상으로 큰 문제가 발생하기에 시작하고 나서 3초후에 총알을 없앤다.
transform.Translate 함수는 오브젝트를 특정한 위치만큼 움직여준다.
예를들어 함수의 파라미터로 new Vector2(0, 1)을 넣으면 총알은 위로 올라갈것이다.
normalized는 특정한 Vector를 총 길이가 1인 Vector로 변환해준다.
예를들어 만약 dir을 (1,1)로 설정했다 가정하자. 그럼 총알은 오른쪽 위 대각선 방향으로 날라갈것이다.
dir을 normalize 하지 않고 그대로 쓸경우, 총알의 속도는 dir이 (0, 1)일 때보다 더 빠르게 날라갈 것이다.

또한 dir을 (30, 30) 같은 큰수로 설정할 경우 더욱 빠르게 움직일것이다.
dir을 normalize한다면 저 Vector의 길이가 1인 새로운 Vector로 변환해준다.

normalize를 할 경우 dir값이 얼마든 총 길이는 1이므로 오직 speed 변수로만 속도를 결정 할 수 있다.
Time.deltaTime은 이전 프레임과 현재 프레임이 실행된 시간의 차이이다. 왜 Time.deltaTime을 곱하는지는 다음 포스트에서 자세하게 설명하겠다.
- 프리펩(Prefeb)
총알 오브젝트를 만들었다면 Inspector창에서 speed값을 적절히 조절하자. (난 5로 설정했다)
Hierarchy창에서 bullet 오브젝트를 Project창으로 드래그하면 오브젝트의 아이콘이 파란색으로 변하고, Project 창에 bullet 오브젝트와 동일한 것이 생길것이다.

이것을 프리펩(Prefeb)이라고 부르며, Scene에서 만들어진 오브젝트 등을 생성하고 싶을때 만든다. 우리는 총알을 플레이어가 직접 쏘게 하고싶기에 프리펩을 만들었다.
프리펩을 만들었다면 Scene에 있는 총알은 삭제하자.
- Instantiate
이제 플레이어 스크립트를 조금 수정하겠다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public float moveSpeed;
public float jumpScale;
public Vector2 groundCastOffset;
public Vector2 groundCastSize;
public GameObject bulletPrefeb; // 1)
private Rigidbody2D rb;
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
var h = Input.GetAxisRaw("Horizontal");
var dir = new Vector2(h * moveSpeed, rb.velocity.y);
if(Input.GetKeyDown(KeyCode.Space) && Physics2D.OverlapBox((Vector2)transform.position + groundCastOffset, groundCastSize, 0f, LayerMask.GetMask("Ground")))
dir.y = jumpScale;
if(h != 0) transform.localScale = new Vector3(h, 1, 1); // 2)
rb.velocity = dir;
if(Input.GetKeyDown(KeyCode.K))
{
var bullet = Instantiate(bulletPrefeb, transform.position, Quaternion.identity); // 3)
bullet.GetComponent<Bullet>().dir = new Vector2(transform.localScale.x, 0); // 4)
}
}
private void OnDrawGizmos()
{
Gizmos.color = Color.red;
Gizmos.DrawWireCube((Vector2)transform.position + groundCastOffset, groundCastSize);
}
}
총알 프리펩을 넣을 변수이다.
h값을 가져와서 h값이 0이 아닐때(가로축 키를 눌렀을때) scale 값을 변경해주었다.
scale의 x값이 음수가 된다면 오브젝트가 뒤집힌다.
Instantiate 함수는 특정한 게임 오브젝트를 복사해서 생성시켜준다.
첫번째 파라미터는 복사할 게임오브젝트, 두번째는 위치, 세번째는 Quaternion값이 들어간다.
Quaternion은 회전 관련 클래스이다. 우리가 일반적으로 사용하는 회전축의 문제점을 보완하기 위해서 만들었다. 나중에 자세하게 설명하겠다.
총알의 Bullet 클래스를 가져와서 dir을 초기화해줬다. dir은 플레이어가 바라보는 방향을 감지하여 바라보는 방향쪽으로 나가게 설정한다.