Object가 DestroyZone에 빠지면 Particle입자가 작동하는 기능을 구현했다. 그런데 아무리 동작해봐도 Particle이 코털만큼도 보이지 않기에,, 정말 골머리 앓았는데, Delta Time 문제였다. 해당 문제에 대한 내용과 함께 Particle을 적용하는 방법을 작성하겠다.
1. Particle 오브젝트 생성
2. 스크립트 작성 및 적용
부록. Delta Time
1. Particle 오브젝트 생성
Hierarchy창에서 Empty Object를 만든다.
그리고 만들거나 import한 Particle Prefab을 드래그 앤 드롭으로 하위 오브젝트에 넣어준다.
2. 스크립트 작성 및 적용
나는 DestroyZone에 Object가 닿으면 Particle을 실행하는 조건을 작성 할 것이다.
우선 ParticleManager.cs를 만들어준다.
그리고 아래와같이 코드를 작성한다.
using JetBrains.Annotations;
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
public class ParticleManager : MonoBehaviour
{
public static ParticleManager instance;
private void Awake()
{
if (instance == null)
{
instance = this;
}
}
public ParticleSystem particleSystem;
public bool particleState = false;
public void StartParticle()
{
particleState = true;
particleSystem = GetComponent<ParticleSystem>();
particleSystem.Play();
}
}
해당 코드에서 Instance를 생성해서 Awake로 초기화 해줬고, Particle을 실행하는 함수를 작성해줬다.
Particl은 ParticleSystem형으로 변수를 생성해준 뒤 해당 변수에 object를 담아서 사용하면 된다.
이제 DestroyZone에서 ParticleSystem의 인스턴스를 활용하여 변수 위치를 재정의하고 함수를 사용하도록 하겠다.
public class DestroyZone : MonoBehaviour
{
public void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag("CutePenguin"))
{
ParticleManager.instance.particleState = true;
ParticleManager.instance.particleSystem.transform.position = other.transform.position;
ParticleManager.instance.StartParticle();
Destroy(other.gameObject);
GameManager.Instance.OpenGameOverUI();
MusicManager.instance.DiePenguin();
Debug.Log("플레이어의 사망으로 게임이 종료되었습니다.");
}
else
{
Destroy(other.gameObject);
Debug.Log("에너미가 감지되었습니다.");
}
```생략```
}
ParticleManager.instance로 particleState를 true로 변경, particle 위치를 트리거에 닿은 object의 위치로 변경, particle 실행해주는 함수 실행해주면 된다.
이제 유니티로 돌아가서 만들어둔 particle game object에 ParticleManager.cs를 드래그 앤 드롭, 스크립트의 오브젝트에 오브젝트 자신을 넣어준다.
부록. Delta Time
자,, 위 과정을 거치면 작동을 해야하는데, 안한다 ^.^
그 이유를 강사님께서 찾아주셨는데,
// 게임 오버
public void OpenGameOverUI()
{
// 게임오버 창 활성화
gameOverUI.SetActive(true);
// 게임 속도 0배속
Time.timeScale = 0f;
// 게임 상태 = '멈춤'
gState = GameState.Pause;
MusicManager.instance.audio.volume = 0.5f;
}
바로 GameManager.cs에 있던 위 코드 때문이다.
게임오버 함수를 보면, (플레이어가 죽으면) 게임 속도를 0f로 변경하는 코드. 저 친구가 문제였다.
Time.timeScale을 0으로 만들어주면 게임 상태가 멈추게 되는데, 이때 모든 동작이 멈추면서 Particle도 동작을 멈추게 되는 것이다. 그래서 이때 해결방법이 여러개 있는데, 나는 Inspector창의 Delta Time을 조정했다.
Scaled : 게임 속도와 맞춤
UnScaled : 게임 속도와 맞추지 않음
UnScaled로 해주면, Time.timeScle로 게임의 시간을 0으로 만들어줘도, Particle을 이에 영향을 받지 않고 실행이 된다(게임이 멈추던 말던 난 실행 될거라는 느낌)
이렇게 해주면
FPS라고 아시는가들? 게임을 하다보면 쉽게 접할 수 있는 단어인데(하지만 나는 마인크래프트를 하는데도 전혀 몰랐지) frames per second라고합니다. 말 그대로 '초 당 프레임 수'인데, 1초에 프레임을 얼마나 찍어내는가?는 의미다.
이제 잘 작동된다 ㅎ.ㅎ
FPS란?
예를 들어서, 500FPS는 1초당 500개의 프레임을 찍어낸다는 뜻이다. 그런데 여기서 100FPS를 가진 유저 VS 500FPS를 가진 유저가 오버워치를 한다고 생각해보자. 500FPS를 가진 유저가 총을 500번을 쏜다고 했을 때 100FPS를 가진 유저는 500번은 커녕 100번의 총만 발사할 수 있다. (진짜 큰일)
그래서 DeltaTime이 필요합니다. 성능에 따라서 한 프레임에 나오는 결과 값을 보장하여 유저가 같은 결과를 얻도록 하는 것. (게임 제작에서는 다른 성능의 컴퓨터가 작동할 때 같은 결과를 보장하는 것이 중요한 요소인 거 같다)
DELTA TIME이란?
Time.deltaTime은 '한 프레임이 완료되기에 걸리는 시간'을 말한다고 한다.
1초당 1M를 가는 총알이 있다고 했을 때, 100FPS에 적용해보면 1/100 * 1(1초당 이동 거리) = 0.01
'동식이 취업시키기 작전 > FPS - Penguin party(feat. unity)' 카테고리의 다른 글
[Unity] 씬 분리하기(== 씬 만들기), 씬 전환하기(feat. 기존 씬으로 돌아가기) (0) | 2023.07.29 |
---|---|
[Unity] 플레이어가 죽으면 게임 종료, 다시 시작하는 옵션 창 만들고 적용하기 (1) | 2023.07.28 |
[Unity] Enemy 랜덤으로 생성하기 (4) | 2023.07.28 |