Development/Unity Engine

[Retro유니티] BulletSpawner - Update() 함수로 실행반복

사이바 미도리 2024. 11. 17. 13:13

Update() 메서드로 탄알을 만들것이다.

그런데 Update() 메서드는 1초에 수십번 실행된다. (정확히는, 화면이 갱신될 때마다 실행된다.)

따라서 무지성으로 넣으면 1초에 수십개씩 탄알이 쏟아질 것이다.

따라서, timeAfterSpawn을 체크 후 탄알을 발사하는 로직을 작성해야 한다.

 

Time.deltatime

아까,

Update() 메서드는 1초에 수십번 실행된다. (정확히는, 화면이 갱신될 때마다 실행된다.)

라고 했다.

즉, 컴퓨터 성능에 따라 초당 프레임은 가변이라는 것이다.

따라서 직전 Update() 실행과 현재 Update 실행사이의 시간간격은 일정하지 않다.

 

 Update() 사이의 물리적 시간간격을 알기위해 내장변수 Time.deltaTime을 사용한다.

 

Instantiate(원본)

런타임에 오브젝트를 생성하기 위해 사용하는 메서드이다.

Instantiate(bulletPrefab);

하지만 이렇게 사용하면, 복제생성된 Game Object의 위치/회전이 임의결정된다.

 

따라서

Instantiate(bulletPrefab, transform.position, transform.rotation);

을 사용한다.

 

최종 BulletSpawner스크립트

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

public class BulletSpawner: MonoBehaviour
{
    public GameObject bulletPrefab; // 총알 프리팹
    public float spawnRateMin = 0.5f; // 총알 생성 최소주기
    public float spawnRateMax = 3f; // 총알 생성 최대주기

    private Transform target; // 총알을 발사할 대상
    private float spawnRate; // 총알 생성 주기
    private float timeAfterSpawn; // 최근 총알 생성 시점에서 지난 시간

    void Start()
    {
        timeAfterSpawn = 0f;
        spawnRate = Random.Range(spawnRateMin, spawnRateMax);
        target = FindObjectOfType<PlayerController>().transform;
    }

    void Update()
    {
        timeAfterSpawn += Time.deltaTime;
        if (timeAfterSpawn >= spawnRate)
        {
            timeAfterSpawn = 0f;
            GameObject bullet = Instantiate(bulletPrefab, transform.position, transform.rotation);
            bullet.transform.LookAt(target);
            spawnRate = Random.Range(spawnRateMin, spawnRateMax);
        }
    }

}

 

스크립트적용

 

Player를 향해 총알을 발사하는것을 확인가능하다.

 

 

이제, BulletSpawner를 여러개 배치하자. Prefab으로 만들고 드래그&드롭을 쓰면 된다.