[Unity Project] <ShootOut2D> 2D 슈팅 게임 만들기(4) 미사일 발사

2023. 8. 28. 16:24Unity

728x90
반응형

미사일 스프라이트를 Hierarchy 창에 올린 후 Rigidbody 2D, Box Collider 2D를 추가한다. Rigidbody 2D의 [Body Type]은 [Kinematic]으로 설정한다.

 

 

이후 미사일을 prefab으로 만들어준다. 이후 플레이어 스크립트에 public GameObject shoot; 코드를 추가하여 만든 프리팹을 사용할 것이다.

public GameObject shoot;

 

 


 

 

방법1) 좌표를 직접 지정

void Start() 함수 안에 Instantiate 기능으로 프리팹을 불러올 수 있다.

Instantiate(shoot, transform.position, Quaternion.identity);

 

 

이제 미사일 발사 위치를 지정해야 한다.

void Start()
{
    spr = gameObject.GetComponent<SpriteRenderer>();
    player1Sprites = Resources.LoadAll<Sprite>("Sprites/player/player1");
    player2Sprites = Resources.LoadAll<Sprite>("Sprites/player/player2");
    player3Sprites = Resources.LoadAll<Sprite>("Sprites/player/player3");

    Vector3 vecshoot = new Vector3(transform.position.x + 1.0f, transform.position.y, transform.position.z);
    Instantiate(shoot, vecshoot, Quaternion.identity);

    min = new Vector3(-8, -4.5f, 0);
    max = new Vector3(8, 4.5f, 0);

    colsize = GetComponent<BoxCollider2D>().size;
    chrsize = new Vector2(colsize.x / 2, colsize.y / 2);
}

Instantiate으로 프리팹을 불러왔고, 불러올 좌표를 약간 수정하기 위해(미사일이 플레이어 앞에 오도록) 위와 같은 코드를 사용했다.

 

 


 

 

방법2) 발사 포인트 추가

플레이어 계층 하위에 포인트를 만들어서 해당 위치에 미사일이 나오게 하는 방법이 있다.

 

 

빈 오브젝트를 만들어서 플레이어 앞에 위치시킨다.

 

 

public Transform shootPointTransform;

코드에 한 줄을 추가한 후 해당 오브젝트를 끌어다 놓는다.

 

 

void Start()
{
    spr = gameObject.GetComponent<SpriteRenderer>();
    player1Sprites = Resources.LoadAll<Sprite>("Sprites/player/player1");
    player2Sprites = Resources.LoadAll<Sprite>("Sprites/player/player2");
    player3Sprites = Resources.LoadAll<Sprite>("Sprites/player/player3");

    Instantiate(shoot, shootPointTransform.position, Quaternion.identity);

    min = new Vector3(-8, -4.5f, 0);
    max = new Vector3(8, 4.5f, 0);

    colsize = GetComponent<BoxCollider2D>().size;
    chrsize = new Vector2(colsize.x / 2, colsize.y / 2);
}

Instantiate에 shootPointTransform.position으로 위치를 부여한다.

 

 


 

 

이제 키를 입력할 때 미사일이 발사되게 만들 것이다.

void Update()
{
    Move();
    PlayerShoot();

}

public float shotMax = 0.5f;
public float shotDelay = 0;
void PlayerShoot()
{
    shotDelay += Time.deltaTime;
    if (Input.GetKeyDown(KeyCode.Space))
    {
        if(shotDelay > shotMax)
        {
            shotDelay = 0;
            Instantiate(shoot, shootPointTransform.position, Quaternion.identity);
        }
    }

}

void Move()
{
    float x = Input.GetAxisRaw("Horizontal");
    float y = Input.GetAxisRaw("Vertical");


    Vector3 dir = new Vector3(x, y, 0).normalized;


    transform.Translate(dir * Time.deltaTime * speed);

    if (Input.GetKey(KeyCode.UpArrow))
    {
        spr.sprite = player3Sprites[0];
    }
    else if (Input.GetKey(KeyCode.DownArrow))
    {
        spr.sprite = player2Sprites[0];
    }
    else
    {
        spr.sprite = player1Sprites[0];
    }

    float nowX = transform.position.x;
    float nowY = transform.position.y;

    nowX = Mathf.Clamp(nowX, min.x + chrsize.x, max.x - chrsize.x);
    nowY = Mathf.Clamp(nowY, min.y + chrsize.y, max.y - chrsize.y);

    transform.position = new Vector3(nowX, nowY, transform.position.z);
}

일단 코드를 정리해서, Move 함수와 PlayerShoot 함수를 만들었다. Move 함수 안에는 이전에 이동에 대한 코드를 그대로 복사했고, PlayerShoot에는 0.5초의 딜레이로 발사되게 하였다. 스페이스바를 눌렀을 때 0.5초가 넘은 이후라면 프리팹을 설정한 위치에 불러온다. 아직 발사는 되지 않는다.

 

 


 

 

public class ShootScript : MonoBehaviour
{
    public float speed = 10;

    void Update()
    {
        transform.position += Vector3.right * Time.deltaTime * speed;
    }
}

미사일의 프리팹에 위의 스크립트를 추가하면 오른쪽으로 나아가게 된다. 하지만 생성된 프리팹은 무한히 날아가게 된다. 화면 밖으로 나간 오브젝트는 지워야 한다.

 

 

방법 1) 오브젝트 좌표로 오브젝트 삭제

public class ShootScript : MonoBehaviour
{
    public float speed = 10;

    void Update()
    {
        transform.position += Vector3.right * Time.deltaTime * speed;

        Vector3 shootposition = transform.position;

        if(shootposition.x > 9)
        {
            GameObject.Destroy(gameObject);
        }
    }
}

Destroy로 오브젝트가 화면 밖 좌표로 나가면 지울 수 있다.

 

 

방법 2) OnBecameInvisible로 오브젝트 삭제

public class ShootScript : MonoBehaviour
{
    public float speed = 10;

    void Update()
    {
        transform.position += Vector3.right * Time.deltaTime * speed;
    }
    void OnBecameInvisible()
    {
        Destroy(gameObject);
    }
}

마찬가지로 화면에 보이지 않게 되면 Destory 함수로 오브젝트를 지우게 된다.

 

 

화면 밖으로 나간 미사일은 왼쪽 Hierarchy 창에서 보이듯 없어진다.

728x90
반응형