// C#
public class ScoreManager : MonoBehaviour
{
public int score = 0;
public int GetScore()
{
return score;
}
public void AddScore(int newScore)
{
score = score + newScore;
}
}
public class ScoreAdder : MonoBehaviour
{
// ScoreManager를 사용하는 곳마다 선언해야 함.
public ScoreManager scoreManager;
void Update()
{
// 마우스 좌클릭하는 순간.
if (Input.GetMouseButtonDown(0))
{
// 사용할 객체를 링크하거나 Find해서 사용해야 함.
// score에 5점을 더한다.
scoreManager.AddScore(5);
// score 출력.
Debug.Log(scoreManager.GetScore());
}
}
}
// C#
// 요즘 추세는 싱글톤 클래스 안에
// 필요한 여러 객체들을 들고 있게 만든다.
// 당연한 이야기지만 프로젝트나 개발자 성향에 따라 다를 수 있음.
public class ScoreManager : MonoBehaviour
{
// 싱글톤.
// 자기 자신을 참조할 static 변수.
public static ScoreManager instance;
private int score = 0;
// 가장 먼저 호출되는 함수.
private void Awake()
{
// 자기 자신을 static 변수로 초기화.
instance = this;
}
public int GetScore()
{
return score;
}
public void AddScore(int newScore)
{
score = score + newScore;
}
}
public class ScoreAdder : MonoBehaviour
{
// 이 과정은 이제 필요하지 않음.
// public ScoreManager scoreManager;
void Update()
{
// 마우스 좌클릭하는 순간.
if (Input.GetMouseButtonDown(0))
{
// 이제 사용할 때 링크를 걸거나 찾을 필요가 없다.
// score에 5점을 더한다.
ScoreManager.instance.AddScore(5);
// score 출력.
Debug.Log(ScoreManager.instance.GetScore());
}
}
}
// C#
private static ScoreManager instance;
// 없으면 에러를 발생시킴.
public static ScoreManager GetInstance()
{
// ScoreManager 오브젝트를 만들어 놓고 이 스크립트를
// 안 붙였거나 or ScoreManager 오브젝트가 아예 없는 상태일 때.
if(instance == null)
{
instance = FindObjectOfType<ScoreManager>();
}
return instance;
}
// instance가 있다는 것을 보장하지만 뜻하지 않은 시점에 만들어질 수 있음.
private static ScoreManager instance;
public static ScoreManager GetInstance()
{
if (instance == null)
{
instance = FindObjectOfType<ScoreManager>();
// 못 찾았다면 만듦
if (instance == null)
{
// 빈 게임 오브젝트 생성할 때만 가능.
// 일반적으로는 Instantiate 사용.
GameObject container = new GameObject("Score Manager");
// ScoreManager 컴포넌트(스크립트)를 붙여줌
instance = container.AddComponent<ScoreManager>();
}
}
return instance;
}
// C#
// 제네릭 타입은 Component로 한정
public class SingletonMonobehaviour<T> : MonoBehaviour where T : Component
{
private static T m_instance;
public static T Instance => m_instance; // Auto Property
// m_instance가 있는 것을 보장.
public static T GetOrCreateInstance()
{
if(m_instance == null)
{
m_instance = (T)FindObjectOfType(typeof(T));
if (m_instance == null)
{
GameObject _newGameObject = new GameObject(typeof(T).Name, typeof(T));
m_instance = _newGameObject.GetComponent<T>();
}
}
return m_instance;
}
protected virtual void Awake()
{
// 자기 자신으로 초기화.
m_instance = this as T;
if (Application.isPlaying == true)
{
// scene과 scene이 전환될 때 특정 오브젝트가 계속 살아있어야 할 때 사용.
// scene이 전활될 때 scene안에 존재하는 모든 오브젝트는 사라지게 되는데,
// singleton은 scene이 전환되어도 살아있어야 하므로 DontDestroyOnLoad()가 필수적임.
DontDestroyOnLoad(gameObject);
}
}
}
// AceUtils은 singleton으로 동작.
// 매번 할 때마다 위의 다른 예제들과 같은 구문 작성이 필요 없어짐.
public class AceUtils : SingletonMonobehaviour<AceUtils>