크래프톤 정글 TIL : 1122

lazyArtisan·2024년 11월 22일
0

정글 TIL

목록 보기
145/147

📚 Journal


어제부로 수료하긴 했는데
3주간 더 남아있을 수 있다.

근데 오늘 집으로 갈거임.
그리고 일요일까지만 정글 TIL로 쓰기.
이후엔 시리즈 따로 파기.



📝 배운 것들


🏷️ Unity :: 자식->부모 충돌 이벤트 전달

자식 오브젝트에 Collider만 있고 Rigidbody가 없는 경우, 부모의 Rigidbody가 충돌 이벤트를 받습니다.
자식에 Rigidbody가 있으면, 이벤트는 자식으로 전달됩니다.

+) 혀의 Collider에서 직접 이벤트를 처리하려면 혀에 스크립트를 추가하고, 이벤트 발생 시 부모(개구리)의 함수를 호출하면 됩니다. >> 이건 너무 비효율적인듯.

🏷️ 싱글톤 패턴

싱글톤 패턴의 주요 특징

  • 단일 인스턴스: 클래스의 인스턴스가 프로그램 전체에서 오직 하나만 존재합니다.
  • 전역 접근점: 이 유일한 인스턴스에 대한 전역 접근점을 제공합니다.
  • 지연 초기화: 대부분의 구현에서 인스턴스는 처음 요청될 때 생성됩니다.
  • 상태 공유: 애플리케이션 전체에서 상태를 공유할 수 있습니다.

싱글톤 패턴의 장점

  • 메모리 효율성: 하나의 인스턴스만 생성되므로 메모리 사용이 효율적입니다.
  • 전역 상태 관리: 애플리케이션 전체에서 일관된 상태를 유지할 수 있습니다.
  • 리소스 공유: 데이터베이스 연결, 파일 시스템 등의 리소스를 효과적으로 공유할 수 있습니다.

싱글톤 패턴의 단점

  • 테스트 어려움: 전역 상태로 인해 단위 테스트가 어려워질 수 있습니다.
  • 강한 결합: 코드 전체가 싱글톤 인스턴스에 의존하게 되어 결합도가 높아집니다.
  • 동시성 문제: 멀티스레드 환경에서 동기화 문제가 발생할 수 있습니다.
  • 유연성 부족: 클래스의 책임이 늘어나 단일 책임 원칙을 위반할 수 있습니다.

🏷️ DontDestroyOnLoad

씬(Scene) 전환 시 특정 게임 오브젝트를 파괴하지 않고 유지하도록 하는 메서드

🏷️ 싱글톤 예제

from namanmu repo

using UnityEngine;

public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
    private static T Instance;

    public static T instance
    {
        get
        {
            if (Instance == null)
            {
                Instance = FindObjectOfType<T>();
            }
            return Instance;
        }
    }
}

perplexity pro

public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
    private static T _instance;
    public static T Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = FindObjectOfType<T>();
                if (_instance == null)
                {
                    GameObject singletonObject = new GameObject();
                    _instance = singletonObject.AddComponent<T>();
                    singletonObject.name = typeof(T).ToString() + " (Singleton)";
                    DontDestroyOnLoad(singletonObject);
                }
            }
            return _instance;
        }
    }

    protected virtual void Awake()
    {
        if (_instance == null)
        {
            _instance = this as T;
            DontDestroyOnLoad(gameObject);
        }
        else if (_instance != this)
        {
            Destroy(gameObject);
        }
    }
}

gpt-preview

public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
    private static T _instance;
    private static readonly object _lock = new object();
    public static bool IsApplicationQuitting { get; private set; }

    public static T Instance
    {
        get
        {
            if (IsApplicationQuitting)
            {
                Debug.LogWarning($"[Singleton] Instance '{typeof(T)}' already destroyed. Returning null.");
                return null;
            }

            lock (_lock)
            {
                if (_instance == null)
                {
                    _instance = (T)FindObjectOfType(typeof(T));

                    if (FindObjectsOfType(typeof(T)).Length > 1)
                    {
                        Debug.LogError($"[Singleton] Multiple instances of '{typeof(T)}' detected.");
                        return _instance;
                    }

                    if (_instance == null)
                    {
                        GameObject singletonObject = new GameObject();
                        _instance = singletonObject.AddComponent<T>();
                        singletonObject.name = $"{typeof(T)} (Singleton)";
                        DontDestroyOnLoad(singletonObject);
                    }
                }

                return _instance;
            }
        }
    }

    protected virtual void OnApplicationQuit()
    {
        IsApplicationQuitting = true;
    }

    protected virtual void OnDestroy()
    {
        IsApplicationQuitting = true;
    }
}


🎮 Frog on Lotus


혀 끝에 닿으면 파리 갖고 옴

어제 왜 콜라이더가 충돌을 안하지? 할 수 있는거 전부 확인해봤는데? 이러다가 멘탈 터졌는데
다시 와서 생각해보니까 혀에 OnTriggerEnter2D를 넣은게 아니라 개구리에 OnTriggerEnter2D를 넣었으니 당연히 작동을 안 하는 거였음. 이런 바보를 봤나

파리 잡는거 완성

    private void OnTriggerEnter2D(Collider2D other)
    {
        Debug.Log("Trigger entered by: " + other.gameObject.name);
        arrivedPoint = true;
        catchedBug = other.gameObject;
    }
    private void ShrinkTongue()
    {
        if (tongueSR.size.x <= 0)
        {
            isAttacking = false;
            animator.SetBool("isAttacking", false);
            tongueSR.size = new Vector2(0, tongueSR.size.y);
            tongueCollider.radius = 0f; // 콜라이더 크기 0으로 돌려놓기
            tongueCollider.offset = new Vector2(0, 0);

            if (catchedBug != null)
                Destroy(catchedBug);

            return;
        }

        tongueSR.size = new Vector2(tongueSR.size.x - tongueSpeed * targetLength * Time.deltaTime, tongueSR.size.y);
        tongueCollider.offset = new Vector2(tongueCollider.offset.x - tongueSpeed * targetLength * Time.deltaTime, 0);
    }

슬슬 바꾼것들 전부 옮기기 어렵.

대충 느낌만 가질 수 있는 정도로만 가져옴.

끌려갈 때 transform도 동기화되는데 혀 돌아가는 속도가 너무 빨라서 잘 안보인다. 아쉽.

기획 고민

이제 기본적인 게임 로직은 대충 다 완성했고,
나머지는 적이나 게임 시스템에 관한 기획이 필요함.

스테이지 형식으로 할 것인지,
시간 내에 먹은 파리의 개수로 할 것인지.

일단 시간 없으니까 (협력사 제출용 이력서에 한 줄이라도 더 적고 싶음)
시간 제한 있는 간단한 점수 내기 게임으로.

파리들이 막 날아다니는데
마리수도 로그 스케일, 속도도 로그 스케일로 증가시키면 될듯?
너무 어려워지지 않게 마리수를 늘리거나 속도 로그 밑을 높게 하거나...
게임적으로는 마리수 늘리고 속도 높이는게 히트 랜덤성 높이고 정신 없고 재밌어서 좋을듯?

처음엔 게임 매니저니까 그냥 싱글톤 써서 하면 되겠지? 했는데
다시 생각해보니까 어차피 스폰만 시키면 되는데 뭐하러 싱글톤을 씀? 이랬다가
파리의 개수는 전역 변수 느낌으로 언제든지 접근할 수 있게 하려면 싱글톤 필요할듯. 까지 생각.
근데 씬 넘어가면서 유지할 것도 아닌데 싱글톤까지 쓸 이유가 있나? 닭 잡는데 소 잡는 칼 쓰는 느낌?

내일 더 고민해보기.

0개의 댓글