개발일지/Unity 6 [미제]

[Unity 6 - 프로젝트] 리듬 게임 4) Timing Hits에 따른 Score와 Effect

서니션 2024. 10. 27. 17:33

0. 들어가며

리듬 게임에는 타이밍에 얼마나 잘 맞추느냐에 따라 Good, Perfect .. 이런 Effect가 나온다.

타이밍 결과에 따른 점수와 이펙트 개발을 해 볼 것이다.


1. 타이밍에 따른 점수 계산

Good과 Perfect Note의 점수 변수를 만들어 준다.

public int scorePerGoodNote = 125;
public int scorePerPerfectNote = 150;

 

타이밍에 따른 점수 계산을 위해 각각에 해당하는 함수를 만들어준다.

    public void NormalHit()
    {
        currentScore += scorePerNote * currentMultiplier;
        NoteHit();
    }

    public void GoodHit()
    {
        currentScore += scorePerGoodNote * currentMultiplier;
        NoteHit();
    }

    public void PerfectHit()
    {
        currentScore += scorePerPerfectNote * currentMultiplier;
        NoteHit();
    }

2. Effect 생성

Particle System을 만들어서 Effect 파일 하위에 넣어준다.

Looping 해제 (입력 시 1번만 나오고 사라질거라), Duration, Shape 등 원하는 대로 조정해준다.

 

Effect는 호출 시에만 나오게 할거라서 Prefab으로 만들어준다.

Prefab의 주요 특징:
재사용 가능: 동일한 설정의 오브젝트를 여러 번 만들 때, 코드나 에디터에서 쉽게 생성 가능.
동적 생성: 런타임 중에 새 오브젝트를 생성할 수 있어 다양한 시나리오에 활용 가능.
유지 보수 편리: 원본 Prefab을 수정하면 게임 내 모든 인스턴스에 자동 반영.

 

Hierarchy 창에 있는 것들을 Assets의 Frefabs 폴더를 만들어 드래그하면 아래 사진처럼 파란색 박스로 표시된다.

NoteObject.cs에서 각 이펙트에 대한 선언 후

public GameObject hitEffect, goodEffect, perfectEffect, MissEffect;

 

Update문

// 버튼 안에 있는 콜라이더의 위치와 얼마나 떨어져 있느냐로 계산
                if(Mathf.Abs(transform.position.y) > 0.25f)
                {
                    Debug.Log("Hit");
                    GameManager.instance.NormalHit();
                    Instantiate(hitEffect, transform.position, hitEffect.transform.rotation); // 기존 저장되어 있는 것
                }
                else if(Mathf.Abs(transform.position.y) > 0.05f)
                {
                    Debug.Log("Good Hit");
                    GameManager.instance.GoodHit();
                    Instantiate(goodEffect, transform.position, goodEffect.transform.rotation);
                }
                else
                {
                    Debug.Log("Perfect Hit");
                    GameManager.instance.PerfectHit();
                    Instantiate(perfectEffect, transform.position, perfectEffect.transform.rotation);
                }

 

Miss시

private void OnTriggerExit2D(Collider2D other)
    {
        if (other.tag == "Activator")
        {
            // 노트가 이미 비활성화되었으면 미스 처리 안함
            if (gameObject.activeSelf)
            {
                canBePressed = false;
                GameManager.instance.NoteMissed();
                Instantiate(MissEffect, transform.position, MissEffect.transform.rotation);
            }
        }
    }

 

Instantiate로 Effect Prefab을 나타나게 해준다

유니티에서 Instantiate 함수는 새로운 게임 오브젝트를 동적으로 생성하는 데 사용됩니다.
주로 Prefab이나 다른 게임 오브젝트의 복제본을 만들기 위해 사용되며, 런타임 중에 오브젝트를 생성할 수 있습니다.

주요 특징:
객체 생성: 지정한 오브젝트(Prefab이나 씬의 기존 오브젝트)를 복제하여 새로 생성합니다.
위치와 회전 지정: 생성할 때 월드 좌표와 회전을 지정할 수 있습니다.
Instantiate(prefab, new Vector3(0, 0, 0), Quaternion.identity);
게임 오브젝트 연결: 생성된 오브젝트를 특정 부모 오브젝트에 자식으로 붙일 수 있습니다.

Instantiate는 적을 스폰하거나 아이템을 생성하는 등의 상황에서 유용하게 쓰입니다.

 

개인적으로 Effect의 lifetime을 스크립트로 조정하면 좋겠어서 EffecObject.cs를 생성하여 조절해주었다.

using UnityEngine;

public class EffectObject : MonoBehaviour
{
    public float lifeTime = 1f;
    void Update()
    {
        Destroy(gameObject, lifeTime);
    }
}

4. 결과