반응형

 

staticconst은 변수나 메서드(=함수) 앞에 사용되는 키워드로,
각각의 특성에 따라 다르게 작동한다.
이 두 키워드는 코드에서 데이터를 공유하고 관리하는 데 사용 됨

이론적인 부분을 앞에 기술하였고,
간단하게 알 수 있도록 예시를 든 부분은 각 키워드의 마지막부분에 기술하였으니,
바쁘다면 각 키워드에서 마지막 부분인 쉽게 예를 들어보자 부분을 확인

 

static (정적)

1. 변수에서의 Static (Static Variables):

  • 특징: 클래스의 모든 인스턴스가 해당 변수를 공유한다.
  • 활용: 모든 인스턴스에서 공통으로 사용되어야 하는 데이터, 예를 들면 게임에서의 점수 카운트 등에 유용
public class GameManager : MonoBehaviour {
    public static int score = 0;
}

 

2. 메서드(함수)에서의 Static (Static Methods):

  • 특징: 인스턴스를 생성하지 않고도 클래스 자체에서 직접 호출할 수 있는 메서드이다.
  • 활용: 인스턴스의 생성 없이 사용 가능한 유틸리티 메서드 등에 유용
public class MathUtility {
    public static int Add(int a, int b) {
        return a + b;
    }
}

 

3. 정말로 쉽게 예를 들어보자

public class Character : MonoBehaviour {
    public static int accountLv = 1; //계정의 레벨을 표시
    
    public static AccountLevelUp(){ //계정 레벨업
    	accountLv++;
    }
    
    public int myLv = 1; //해당 클래스를 가진 캐릭터의 레벨
    
    public void LevelUp(){
    	myLv++; //캐릭터의 레벨업
    }
    
}

위와 같은 클래스가 있고,

하이어라키에는 아래처럼 3개의 오브젝트가 있다고 가정하자.

Character.cs 컴포넌트를 보유하고있는 3개의 오브젝트(혹은 그 이상)

 

int myLv 변수는 오브젝트(인스턴스)가 각각 개별적으로 소유하고있어,

1번 오브젝트 myLv = 3;

2번 오브젝트 myLv = 2;

3번 오브젝트 myLv = 99;

...

이렇게 오브젝트 별로 개별적으로 myLv 값을 다르게 가질 수 있다.

 

 

하지만 int accountLv 변수는 static 이기에 이 세상에 단 하나밖에 없다.

(Character.cs 를 아무리 많이 생성을 한다고 해도, accountLv는 오브젝트 별로 보유하고있는게 아닌 딱 1개의 공간만 가지고있다)

1번오브젝트에서 accountLv = 3; 이라고 지정한다면

2번오브젝트, 3번오브젝트, 10000번 오브젝트 어디서든 accountLv를 불러오면 전부 3이라는 값을 출력한다.

정확히는 Character 클래스 자체에서 값을 관리한다고 보면 된다.

(static은 특정 인스턴스가 아닌 클래스 자체에 속해서 관리하라고 선언하는 것)

 

각 오브젝트들이 자신의 레벨업하기위해서는 myLv 값을

계정 레벨을 레벨업하기 위해서는 (계정은 1개이므로) accountLv 값을 사용한다.

 

그러한 특징으로

주로 클래스 수준에서 공통으로 사용되는 작업이나 데이터를 처리하는 데 활용된다.

그러므로 외부(다른 클래스)에서 불러 올때도 간편하다

Character.accountLv;

어디서든 위처럼 사용하면 된다.

 

반대로 x번째 오브젝트의 'myLv'를 가져와야 할 경우는..

x번째 오브젝트의 Character를 캐싱을 해서 'myLv'를 불러와야될 것이다.

public int GetCharacterLv(Character obj){
 return obj.myLv;
}

뭐 이런식으로 말이다..

(상황에 따라 방법에 따라 개별 오브젝트의 변수를 가져올 수 있는 방법이 너무 다양하고 다르기에 적절하게 코딩해야한다)

 

const (상수)

static은 정적형태로 사용하지만 const는 상수의 개념이라 논리적으로 값이 바뀌는 메서드(함수) 형태로의 표현은 불가능하다.

변수 (Constants):

  • 특징: 값을 변경할 수 없는 상수를 정의합함.
  • 활용: 변하지 않는 값들을 선언할 때 사용되며, 런타임 중(실행 중)에 변경할 수 없다.
public class Constants {
    public const float PI = 3.14f;
}

2. 사용 방법:

  • const 변수는 반드시 선언과 동시에 초기화되어야 한다.
  • const 변수는 런타임 중에 값이 변경될 수 없다.
public class Example {
    public const int MAX_VALUE = 100;
}

 

3. 정말로 쉽게 예를 들어보자

public class Example {
    public const int MAX_VALUE = 100;
    public const int MIN_VALUE = 1;
}
public class GameManager {
    void Start(){
    	int a = Example.MIN_VALUE + Example.MAX_VALUE;
    }
}

 

예상하겠지만 Example 클래스에서 MIN_VALUE, MAX_VALUE 둘을 더하므로 a의 값은 101일 것이다.

 

정말 알기 쉽게 얘기한다면

실행이 되는 시점에서 모든 코드에서 MIN_VALUE를 쓰고있는 부분은 전부 1

MAX_VALUE를 쓰고있는 부분은 전부 100 으로 교체되어서 실행이 된다고 생각하면 가장 빠르게 이해할 수 있다.

즉 실행이 되는 순간, 위 GameManager 코드가  아래처럼 변경 된 다음에 실행이 된다고 생각하면 쉽다.

public class GameManager {
    void Start(){
    	int a = 1 + 100; //실행되는 순간 const는 값이 이렇게 변경되어서 시작된다고 생각 :)
    }
}

어차피 const는 프로그램이 실행~종료 할때까지 처음 그 값에서 변경이 불가능하다.

즉, 언제든지 변할 수 있는 변수의 의미가 아닌 항상 그대로 변하지 않는 상수의 개념이기때문

 

※ 참고 ※

 

 

[유니티] DateTime & TimeSpan ToString() 표기방법

DateTime과 TimeSpan 클래스에 대한 설명과 텍스트(string)으로 변환시 원하는 형식으로 표기하는 방법 우선 TimeSpan은 '시간'값 DateTime은 '시각'값을 가진다. 처음에 많이들 혼동하고 왜 다른 클래스로

art-life.tistory.com

 

반응형
반응형

오랜만의 포스팅을 싱글톤으로 하게 되었네요.

 

 

일단 제 기준으로 유니티에서 사용하기 편하고 관리하기 쉬운 방법의 싱글톤 예제를 가지고 왔습니다.

 

싱글톤의 역할

싱글톤은 프로그래밍 디자인 패턴 중 추상 객체 인스턴스 생성 패턴 중의 하나로

유니티에서 싱글톤의 역할은

 

1. 게임 시스템에서 전체를 관장하는 스크립트(단일 시스템 자원 관리 차원)

2. 게임 시스템상 전역 변수의 역할을 하는 스크립트

3. 씬 로드시 데이터가 파괴되지 않고 유지

4. 여러 오브젝트가 접근을 해야 하는 스크립트의 역할

5. 단 한개의 객체만 존재(게임 전체를 관장하는 스크립트가 둘 이상 있으면 꼬이겠죠?)

 

등등 많겠지만 결론은 다 같은 말이죠? 네 이 모든 역할을 할 수 있는게 Singleton Pattern입니다.

 

 

아마 새로운 씬을 로드를 하게 되면 앞에 있던 변수들은 전부 파괴되고 새로운 씬이 로드가 될 거예요.

하지만 싱글톤은 씬 이동시 자신을 파괴하지 않으면서 자신이 가진 데이터들 또한 함께 유지한답니다.

 

실습 예제 및 스크립트

씬이 이동되면서 내 골드의 정보가 초기화 되는 것을 알 수 있습니다.

 

위 그림과 같은 경우로

유니티 내에서 씬과 씬 사이를 넘어갈 때 앞의 씬에서 데이터를 받아와서 다음 씬에서 받고 싶을 때 사용할 수 있어요.

 

그럼 MyGold 가 씬이 이동이 되어도 계속해서 유지할 수 있는 방법을 알아볼게요

 

저는 우선 "GameManager"라는 이름의 스크립트를 만들었습니다.

많은 사람들이 GameManager라는 이름으로 스크립트를 사용 하다보니 유니티에서 아이콘을 바꿔주네요.

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameManager : MonoBehaviour
{
    /* // 싱글톤 //
     * instance라는 변수를 static으로 선언을 하여 다른 오브젝트 안의 스크립트에서도 instance를 불러올 수 있게 합니다 
     */
    public static GameManager instance = null; 

    private void Awake()
    {
        if (instance == null) //instance가 null. 즉, 시스템상에 존재하고 있지 않을때
        {
            instance = this; //내자신을 instance로 넣어줍니다.
            DontDestroyOnLoad(gameObject); //OnLoad(씬이 로드 되었을때) 자신을 파괴하지 않고 유지
        }
        else
        {
            if (instance != this) //instance가 내가 아니라면 이미 instance가 하나 존재하고 있다는 의미
                Destroy(this.gameObject); //둘 이상 존재하면 안되는 객체이니 방금 AWake된 자신을 삭제
        }
    }

    //게임 내에서 씬이동시 유지하고 픈 골드 값(변수)
    public int myGold = 0;
}

 위와 같이 스크립트를 짜주시고, 각 씬의 하이라키창에 빈 오브젝트(Empty Object)를 생성해줍니다.

 

이러면 준비 끝!

이제 어디서든

GameManager.instance.(변수 혹은 함수명)

으로 불러 줄 수 가 있게 되었습니다!

 

지금 의 예제로는

GameManager.instance.myGold 라고 불러 줄 수 가 있겠네요.

 

그럼 Main 씬에서 '돈 벌기' 버튼을 눌렀을때 아래가 작동이 되는 스크립트를 만들어주고,

GameManager.instance.myGold += 2;

씬을 이동(상점) 후, 아이템 구매마다 해당하는 가격만큼 myGold가 줄어들게 설정을 하고 테스트를 해보면..

GameManager.instance.myGold -= (아이템가격);

 

씬 이동을 했음에도 'GameManager'가 파괴되지 않아, 'MyGold' 변수 값이 유지가 되는 모습 
플레이 중에 하이라키에서도 씬 이동이 계속 되어짐에도 GameObject(GameManager Componenet가 들어있는)가 지워지지 않고 유지되고 있다.

주의할 점

쉽게 사용이 가능하다보니 되나 가나 모든 데이터,

객체 등을 이곳에 마구잡이로 때려 넣으면 안 된다는 것!!

 

접근이 쉽다보니 막 갖다쓰다보면 비대칭적인 크기로 게임이 만들어지게되고,

나중에 다시 재정리 하려면 이미 꼬일대로 꼬인 상황이 올거에요.

장담합니다 막 갖다쓰다보면 봅니다.

반응형

+ Recent posts