경고 전문 Parent of RectTransform is being set with parent property. Consider using the SetParent method instead, with the worldPositionStays argument set to false. This will retain local orientation and scale rather than world orientation and scale, which can prevent common UI scaling issues.
→ 번역 RectTransform 의 부모는 부모 속성으로 설정됩니다. 대신 setParent 메서드를 사용하고 worldPositionStays 인수를 false로 설정하는 것이 좋습니다. 이렇게 하면 월드 방향과 스케일이 아닌 로컬 방향과 스케일이 유지되어 일반적인 UI 스케일 문제를 방지할 수 있습니다.
위의 경고문은 transform.parent 대신 transform.SetParent() 메서드를 사용을 권고하는 경고이다.
RectTransform에서 parent 사용 시 UI에 스케일링 관련 이슈가 있어 SetParent를 사용하는것을 권하고있다.
transform.parent = parent_panel; //경고의 원인
transform.SetParent(parent_panel); //이와 같이 SetParent()메서드로 변경해서 사용
static과 const은 변수나 메서드(=함수) 앞에 사용되는 키워드로, 각각의 특성에 따라 다르게 작동한다. 이 두 키워드는 코드에서 데이터를 공유하고 관리하는 데 사용 됨
이론적인 부분을 앞에 기술하였고, 간단하게 알 수 있도록 예시를 든 부분은 각 키워드의 마지막부분에 기술하였으니, 바쁘다면 각 키워드에서 마지막 부분인 쉽게 예를 들어보자 부분을 확인
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개의 오브젝트가 있다고 가정하자.
int myLv 변수는 오브젝트(인스턴스)가 각각 개별적으로 소유하고있어,
1번 오브젝트 myLv = 3;
2번 오브젝트 myLv = 2;
3번 오브젝트 myLv = 99;
...
하지만 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는 프로그램이 실행~종료 할때까지 처음 그 값에서 변경이 불가능하다.
즉, 언제든지 변할 수 있는 변수의 의미가 아닌 항상 그대로 변하지 않는 상수의 개념이기때문
게임 개발은 객체 생성과 관리가 핵심적인 역할을 합니다. 이를 효율적으로 다루기 위해 Factory 패턴은 유니티(Unity)에서 강력한 디자인 패턴 중 하나로 사용됩니다. Factory 패턴은 게임 오브젝트나 컴포넌트 등의 생성과 관리를 추상화하여 코드의 가독성, 유지보수성, 그리고 재사용성을 향상시키는 데 도움을 주는 패턴입니다.
Factory 패턴이란?
Factory 패턴은 객체 생성 로직을 별도의 클래스로 분리하는 디자인 패턴입니다. 이를 통해 개체 생성에 대한 세부 사항을 숨기고, 클라이언트 코드가 생성 프로세스를 알 필요 없이 객체를 생성할 수 있게 됩니다. Factory 패턴은 크게 두 가지 형태로 나뉩니다.
단순 팩토리(Simple Factory) 객체 생성을 위한 인터페이스를 제공하고, 클라이언트에게 어떤 클래스를 생성할 것인지 선택하는 책임을 지게 합니다. 유니티에서는 이 패턴을 자주 사용합니다.
추상 팩토리(Abstract Factory) 여러 종류의 관련된 객체를 생성하며, 이러한 객체들이 함께 작동할 수 있도록 보장합니다. 일반적으로 복잡한 시스템에서 사용됩니다.
햄버거 가게를 상상해보세요. 햄버거 가게는 다양한 종류의 햄버거를 만듭니다. 이 가게에서는 각 햄버거를 주문할 때마다 주문한 종류에 따라 조리과정이 달라집니다. Factory 패턴을 사용하여 이 가게의 동작을 설명해보겠습니다.
햄버거 공장 (Hamburger Factory) 이 공장은 다양한 종류의 햄버거를 만들어내는 곳입니다. 이 팩토리는 주문받은 햄버거의 종류에 따라 다른 햄버거를 생성합니다. 햄버거 (Hamburger) 각각의 햄버거는 고유한 레시피와 재료를 가지고 있습니다. 팩토리는 이 햄버거를 만들 때 필요한 재료와 조리 방법을 알고 있습니다. 주문 (Order) 고객이 원하는 햄버거 종류를 주문합니다. 예를 들어, "치즈버거 주세요" 라고 주문하면, 팩토리는 치즈버거를 만들어 제공합니다. 서비스 (Service) 팩토리는 주문을 받고, 그에 맞는 햄버거를 만들어내며, 최종적으로 손님에게 제공합니다.
Factory 패턴을 사용하면 고객은 어떤 햄버거가 만들어지는지, 어떤 재료와 레시피가 사용되는지 신경 쓸 필요 없이 주문만 하면 됩니다. 팩토리가 주문에 따라 올바른 햄버거를 만들어주기 때문입니다.
이런 방식으로 Factory 패턴은 객체를 생성하고 초기화하는 복잡한 작업을 추상화하며, 클라이언트가 생성 과정을 신경 쓰지 않고 필요한 객체를 얻을 수 있도록 도와줍니다.
Factory 패턴의 장점
유연성: 객체 생성 방법을 중앙에서 관리하므로 생성 로직 변경 시 코드 수정이 최소화됩니다.
유지보수성: 객체 생성 코드가 중앙 집중화되므로 유지보수가 쉬워집니다.
재사용성: 객체 생성 로직을 재사용 가능한 컴포넌트로 만들어 코드의 재사용성을 향상시킵니다.
Factory 패턴 간단한 실 예제
게임에서 캐릭터를 생성해야 한다고 가정해봅시다. 캐릭터의 생성은 다양한 속성과 초기화 과정이 포함될 수 있습니다.
using UnityEngine;
public class CharacterFactory : MonoBehaviour
{
public GameObject playerPrefab; // 플레이어 프리팹을 할당할 변수
public GameObject enemyPrefab; // 적 캐릭터 프리팹을 할당할 변수
// 플레이어 캐릭터를 생성하는 메서드
public GameObject CreatePlayer(Vector3 position)
{
GameObject player = Instantiate(playerPrefab, position, Quaternion.identity);
return player;
}
// 적 캐릭터를 생성하는 메서드
public GameObject CreateEnemy(Vector3 position)
{
GameObject enemy = Instantiate(enemyPrefab, position, Quaternion.identity);
return enemy;
}
}
위의 코드에서 CharacterFactory 클래스는 플레이어와 적 캐릭터를 생성하는 두 가지 메서드를 제공합니다. 클라이언트는 이 팩토리 클래스를 사용하여 필요한 캐릭터를 생성하고 초기화할 수 있습니다.
using UnityEngine;
public class CharacterSpawner : MonoBehaviour
{
public CharacterFactory characterFactory; // 팩토리 클래스를 할당할 변수
void Start()
{
// 플레이어 생성
GameObject player = characterFactory.CreatePlayer(new Vector3(0, 0, 0));
// 적 생성
GameObject enemy = characterFactory.CreateEnemy(new Vector3(5, 0, 0));
}
}
위의 CharacterSpawner 스크립트에서 CharacterFactory 클래스를 사용하여 플레이어와 적을 생성할 수 있습니다.
이 예제 외에도
총알을 발사하는 과정에서 총알마다 각기 다른 사거리, 속도, 데미지 등을 설정하고
필요한 상황에 맞게 어떤 총알을 생성하여 어떻게 발사할지 관리하게 만들 수도 있겠죠.
마치며
Factory 패턴을 이용하면 게임 오브젝트 생성과 관리를 효율적으로 다룰 수 있으며, 복잡한 게임에서 객체 생성과 초기화를 효과적으로 관리할 수 있습니다. Factory 패턴은 유니티 프로젝트에서 객체 생성과 관리에 있어서 필수적인 디자인 패턴 중 하나입니다.
이런 Factroy 패턴으로 코드를 작성한다면 생성하는 부분과 관리하는 부분을 별도로 가지고있기에 오류가 생길 확률이 적어집니다.
또한, 오브젝트 풀링과도 많은 연관이 있기에 잘 이용한다면 관리가 쉬운 코드를 짤수있습니다.