using System; using UnityEngine; namespace UVC.Core { #region Singleton /// /// MonoBehaviour가 아닌 일반 클래스를 위한 싱글톤 패턴 /// 지연 초기화(lazy initialization)를 사용하여 필요할 때만 인스턴스 생성 /// /// 싱글톤으로 구현할 클래스 타입(반드시 기본 생성자가 있어야 함) /// /// /// public class JournalClass /// { /// // 클래스 내용 /// } /// /// // 싱글톤 사용 예시 /// var journalSingleton = Singleton.Instance; /// /// public class Singleton where T : class, new() { /// /// 싱글톤 인스턴스를 지연 초기화 방식으로 생성 /// protected static readonly Lazy instance = new Lazy(() => new T()); /// /// 외부에서 생성자 직접 호출 방지 /// protected Singleton(){} /// /// 싱글톤 인스턴스에 접근하기 위한 전역 접근점 /// /// /// /// // 싱글톤 인스턴스 접근 방법 /// MyClass instance = Singleton.Instance; /// /// public static T Instance { get { return instance.Value; } } } #endregion #region SingletonApp /// /// 씬 전환 시에도 유지되는 MonoBehaviour 기반 싱글톤 /// DontDestroyOnLoad를 통해 씬 전환 시에도 객체가 파괴되지 않음 /// /// MonoBehaviour를 상속받는 컴포넌트 타입 /// /// /// // 사용 예시 /// public class AppMain : SingletonApp /// { /// protected override void Init() /// { /// // 초기화 코드 작성 /// ULog.Debug("AppMain 초기화 완료"); /// } /// } /// /// // 접근 방법 /// AppMain.Instance.SomeMethod(); /// /// public abstract class SingletonApp : UnityEngine.MonoBehaviour where T : UnityEngine.Component { /// /// 싱글톤 인스턴스 /// private static T instance; /// /// 싱글톤 인스턴스에 접근하기 위한 전역 접근점 /// 인스턴스가 없는 경우 자동으로 생성함 /// /// /// /// // 접근 방법 /// MyAppSingleton.Instance.DoSomething(); /// /// public static T Instance { get { if (instance == null) { instance = (T)GameObject.FindFirstObjectByType(typeof(T)); // Updated to use FindFirstObjectByType if (instance == null) { // 씬에 인스턴스가 없으면 새로 생성 instance = new GameObject(string.Format(typeof(T) + "")).AddComponent(); } } return instance; } } /// /// 컴포넌트가 활성화될 때 호출되는 Unity 메소드 /// 인스턴스 설정 및 씬 전환 시 객체 유지 설정 /// protected virtual void Awake() { if (instance == null) { instance = this as T; } // 인스턴스 초기화 호출 (instance as SingletonApp).Init(); //if (transform.parent != null && transform.root != null) //{ // DontDestroyOnLoad(transform.root.gameObject); //} //else { // 씬 전환 시에도 파괴되지 않도록 설정 DontDestroyOnLoad(gameObject); } } /// /// 인스턴스화될 때 호출되는 초기화 메소드 /// 자식 클래스에서 오버라이드하여 초기화 로직 구현 /// /// /// /// protected override void Init() /// { /// // 초기화 코드 작성 /// playerData = new PlayerData(); /// LoadSettings(); /// } /// /// protected virtual void Init() { } } #endregion #region SingletonScene /// /// 현재 씬 내에서만 유지되는 MonoBehaviour 기반 싱글톤 /// 씬 전환 시 인스턴스가 파괴됨 /// /// MonoBehaviour를 상속받는 컴포넌트 타입 /// /// /// // 사용 예시 /// public class SceneMain : SingletonScene /// { /// protected override void Init() /// { /// // 초기화 코드 작성 /// ULog.Debug("SceneMain 초기화 완료"); /// } /// } /// /// // 접근 방법 /// SceneMain.Instance.SomeMethod(); /// /// public abstract class SingletonScene : UnityEngine.MonoBehaviour where T : UnityEngine.Component { /// /// 싱글톤 인스턴스 /// private static T instance; /// /// 싱글톤 인스턴스에 접근하기 위한 전역 접근점 /// 인스턴스가 없는 경우 자동으로 생성함 /// /// /// /// // 접근 방법 /// MySceneSingleton.Instance.DoSomething(); /// /// public static T Instance { get { if (instance == null) { instance = (T)GameObject.FindFirstObjectByType(typeof(T)); // Updated to use FindFirstObjectByType if (instance == null) { // 씬에 인스턴스가 없으면 새로 생성 instance = new GameObject(string.Format(typeof(T) + "")).AddComponent(); } } return instance; } } /// /// 컴포넌트가 활성화될 때 호출되는 Unity 메소드 /// 인스턴스 설정 및 초기화 /// protected virtual void Awake() { if (instance == null) { instance = this as T; } // 인스턴스 초기화 호출 (instance as SingletonScene).Init(); } /// /// 인스턴스화될 때 호출되는 초기화 메소드 /// 자식 클래스에서 오버라이드하여 초기화 로직 구현 /// /// /// /// protected override void Init() /// { /// // 초기화 코드 작성 /// uiManager = GetComponent(); /// SetupEventListeners(); /// } /// /// protected virtual void Init() { } /// /// 컴포넌트가 파괴될 때 호출되는 Unity 메소드 /// 싱글톤 인스턴스 참조 해제 /// protected virtual void OnDestroy() { instance = null; } } #endregion }