extern

extern 키워드를 사용하면 플랫폼 간 상호 운용성, 성능 최적화, 코드의 안전성과 에러 처리를 모색할 수 있다.

 

플랫폼 간 상호 운용성

C# 언어를 사용하는 프로젝트에서 이외의 언어로 작성된 라이브러리 함수를 호출하는 경우는 아주 흔하게 발생하는 상황이다. 예를 들어서 C#에서 Windows API를 호출하려면 DllImport 속성을 사용해서 C# 코드에서 네이티브 코드 함수를 선언해야 한다. 이를 통해 C# 프로그램에서 운영 체제 수준의 다양한 기능을 직접적으로 사용할 수 있다.

 

Windows API 중 몇 가지 간단한 함수를 사용해 본다.

namespace Test
{
    using System;
    using System.Text;
    using System.Runtime.InteropServices;

    internal class Program
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct SYSTEMTIME
        {
            public ushort Year;
            public ushort Month;
            public ushort DayOfWeek;
            public ushort Day;
            public ushort Hour;
            public ushort Minute;
            public ushort Second;
            public ushort Milliseconds;
        }

        [DllImport("Kernel32.dll")]
        public static extern bool SetConsoleTitle(string title);
        

        [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        public static extern uint GetConsoleTitle(StringBuilder buffer, uint size);

        [DllImport("Kernel32.dll")]
        public static extern void GetSystemTime(out SYSTEMTIME st);

        static void Main(string[] args)
        {
            SetConsoleTitle("Bak's Console");
            Console.WriteLine("Hello, World!");

            StringBuilder buffer = new StringBuilder(256); // Define buffer size according to your need
            GetConsoleTitle(buffer, (uint)buffer.Capacity);
            Console.WriteLine("Console Title: " + buffer.ToString());

            SYSTEMTIME st;
            GetSystemTime(out st);
            Console.WriteLine("Current System Time: {0}-{1}-{2} {3}:{4}:{5}.{6}",
                st.Year, st.Month, st.Day, st.Hour, st.Minute, st.Second, st.Milliseconds);

            Console.ReadLine();
        }
    }
}

 

실행 결과

C# - extern kernel32.dll

 

외부 함수 SetConsoleTitle을 사용해서 실행되는 콘솔의 타이틀을 변경하고 GetConsoleTitle을 사용해서 변경한 콘솔의 타이틀을 가지고 와서 콘솔에 찍어본다. 그리고 GetSystemTime을 사용해서 현재 실행 중인 장치의 시간을 가지고 온다.

 

코드를 보면 알 수 있듯이 필요한 기능을 사용하기 위해서는 어트리뷰트를 선언할 때 추가로 필요한 값들이나 사용하고자 하는 함수의 반환값, 필요한 파라미터 등에 대한 정보들이 필요하다.

 

이러한 정보들은 마이크로소프트 공식 문서나 또는 이를 주제로 하는 커뮤니티에서 확인할 수 있고 이외 라이브러리들도 제공하는 곳에서 API 문서를 확인할 수 있다.

 

성능 최적화

C# 코드 내에서 수학 계산이나 이미지 처리와 같은 고성능의 연산을 요구하는 네이티브 라이브러리 함수를 호출하는 방법이 있다. 이러한 방식은 매니지드 코드(Managed Code)에 비해 실행 속도가 빠른 네이티브 코드의 이점을 활용할 수 있게 해 준다.

 

네이티브 코드를 사용하는 것이 언제나 성능적으로 이점이 있다고 할 수는 없으므로 해당 목적을 위해서 외부 라이브러리를 사용한다고 했을 때에는 .Net 환경에서 이미 최적화된 상태인 C# 라이브러리의 성능과 비교해서 네이티브 코드를 사용했을 때에 성능적인 이점이 있을 때 사용하는 것이 좋다.

 

 

728x90
반응형

new

new 키워드의 사용을 최소화하여 객체 생성의 통제를 개선하고 코드의 유연성과 재사용성을 높여 의존성 관리를 용이하게 할 수 있다. 이를 통해서 메모리 사용을 최적화하고 객체의 생명주기를 효과적으로 관리할 수 있다.

 

디자인 패턴(Design Pattern)

주로 사용되는 방식들은 패턴으로 정형화된 구조를 만들 수 있다. 

자주 그리고 반복적으로 사용되는 코드의 디자인을 정형화된 패턴으로 만들 수 있는데 이를 디자인 패턴이라고 한다.

 

디자인 패턴은 다양한 종류들이 존재하는데 이번에는 그중 객체의 생성과 할당과 관련된 패턴들 중 대표적인 몇 가지만 살펴본다.

 

싱글턴 패턴(Singleton Pattern)

싱글턴 패턴은 클래스의 인스턴스가 하나만 존재하도록 보장하는 패턴이다.

이 패턴은 객체를 전역적으로 접근할 수 있게 하여 리소스에 대한 중복 접근을 방지하고 메모리 사용을 효율적으로 관리할 수 있도록 한다. 시스템 전체에 걸쳐 일관된 상태를 유지할 수 있으며 객체의 생성과 생명주기를 통제할 수 있다.

 

public class Singleton
{
    private static Singleton instance;
    private Singleton() {}
    
    public static Singleton GetInstance()
    {
        if (instance == null)
        {
            instance = new Singleton();
        }
        return instance;
    }
}

 

생성자를 private으로 선언하여 클래스 외부에서는 새 객체를 생성할 수 없도록 하며 GetInstance()를 통해서 유일하게 존재하는 클래스의 인스턴스에 접근할 수 있도록 한다.

 

팩토리 메서드 패턴(Factory Method Pattern)

객체 생성을 처리하는 인터페이스를 제공하면서 서브 클래스가 생성할 객체의 클래스를 지정할 수 있게 한다.

이 패턴을 통해서 객체 생성을 추상화할 수 있으며 시스템의 확장성과 유연성을 향상할 수 있다.

 

팩토리 패턴의 방법은 다음과 같다.

 

1. 생성할 객체들이 공통적으로 구현할 인터페이스를 정의한다. 

2. 인터페이스를 구현하는 클래스들을 생성한다. 각 클래스에서는 인터페이스의 메서드를 구체적으로 구현한다.

3. 객체 생성을 담당할 메서드를 포함하는 인터페이스를 정의한다. 이 메서드는 인터페이스 타입의 객체를 반환한다.

4. 생성자 인터페이스를 구현하는 클래스를 생성하고 팩토리 메서드를 오버라이드하여 인스턴스를 생성하고 반환한다.

5. 외부에서는 팩토리 메서드를 통해 객체를 생성하여 의존성 없이 동작할 수 있게 된다.

 

예시로 여러 종류의 몬스터를 만드는 팩토리 패턴을 활용하여 작성해 본다.

 

// 몬스터 인터페이스 정의
public interface IMonster
{
    void Attack();
}

// 구체적인 몬스터 클래스
public class Zombie : IMonster
{
    public void Attack()
    {
        Console.WriteLine("Zombie attacks!");
    }
}

public class Vampire : IMonster
{
    public void Attack()
    {
        Console.WriteLine("Vampire attacks!");
    }
}

// 몬스터 생성을 위한 팩토리 클래스
public abstract class MonsterFactory
{
    public abstract IMonster CreateMonster();
}

public class ZombieFactory : MonsterFactory
{
    public override IMonster CreateMonster()
    {
        return new Zombie();
    }
}

public class VampireFactory : MonsterFactory
{
    public override IMonster CreateMonster()
    {
        return new Vampire();
    }
}

class Program
{
    static void Main(string[] args)
    {
        MonsterFactory factory = new ZombieFactory();
        IMonster monster = factory.CreateMonster();
        monster.Attack();

        factory = new VampireFactory();
        monster = factory.CreateMonster();
        monster.Attack();
    }
}

 

 

특히 다양한 객체가 동일한 인터페이스를 공유하거나 시스템 구성 요소 간의 결합도를 낮추기 원할 때 유용하며 객체의 생성과 클래스의 구현을 분리함으로써 모듈화 된 코드 구조를 가능하게 한다.

 

빌더 패턴 (Builder Pattern)

빌더 패턴은 복잡한 객체의 생성과정을 단계별로 나누어 구축하는 디자인 패턴으로 객체의 생성 과정과 표현 방법을 분리하여 동일한 생성 절차에서 다양한 표현 결과를 얻을 수 있도록 한다. 주로 복잡한 객체를 조립해야 할 때 사용되며 각 부분의 조립 순서를 외부에서 지정할 수 있다.

 

// 캐릭터의 인터페이스 정의
public interface ICharacter
{
    void EquipWeapon(string weapon);
    void EquipArmor(string armor);
    void AddAbility(string ability);
}

// 캐릭터 빌더 인터페이스
public interface ICharacterBuilder
{
    ICharacterBuilder BuildWeapon(string weapon);
    ICharacterBuilder BuildArmor(string armor);
    ICharacterBuilder BuildAbility(string ability);
    Character Build();
}

// 구체적인 캐릭터 빌더
public class HeroBuilder : ICharacterBuilder
{
    private Character _character = new Character();

    public ICharacterBuilder BuildWeapon(string weapon)
    {
        _character.EquipWeapon(weapon);
        return this;
    }

    public ICharacterBuilder BuildArmor(string armor)
    {
        _character.EquipArmor(armor);
        return this;
    }

    public ICharacterBuilder BuildAbility(string ability)
    {
        _character.AddAbility(ability);
        return this;
    }

    public Character Build()
    {
        return _character;
    }
}

// 사용 예
public class Game
{
    public void CreateHero()
    {
        HeroBuilder builder = new HeroBuilder();
        Character hero = builder.BuildWeapon("Sword")
                                 .BuildArmor("Shield")
                                 .BuildAbility("Invisibility")
                                 .Build();
    }
}

 

 

캐릭터가 가지는 공통적인 기능을 인터페이스로 구현한 다음 구체적인 캐릭터 클래스에서 원하는 옵션으로 조립할 수 있도록 단계를 구분한다.

728x90
반응형

new

메모리 할당

new 키워드를 사용하면 CLR은 관리되는 힙에 객체를 위한 메모리를 할당한다. 

할당된 메모리는 해당 객체에 대한 모든 참조가 없어질 때까지 메모리에 존재하고 더 이상 참조되지 않을 때 GC에 의해 관리된다.

public class MyClass
{
    public int Number { get; set; }
}

public class Program
{
    public static void Main()
    {
        MyClass myObject = new MyClass();
        myObject.Number = 1;
        Console.WriteLine(myObject.Number);
    }
}

 

 

생성자

생성자는 객체가 할당될 때 호출되는 생명주기 메서드(Lifecycle Methods)이다.

클래스의 객체를 생성하는 방식을 생각해 보면 new 키워드 뒤에 클래스명의 함수를 쓰는데 이 함수는 클래스에서 따로 작성하지 않았는데도 문제없이 컴파일된다.

 

MyClass myObject = new MyClass();

 

그 이유는 클래스에 별도로 생성자에 대한 작성을 하지 않아도 컴파일 단계에서 자동으로 기본 생성자를 만들어서 사용하기 때문에 컴파일 에러가 발생하지 않게 된다.

 

기본 생성자의 형태는 클래스 명의 메서드로 함수 내부에는 비어있는 형태로 볼 수 있다.

 

public class MyClass
{
    public int Number { get; set; }
    // 기본 생성자 형태
    public Number(){}
}

public class Program
{
    public static void Main()
    {
        MyClass myObject = new MyClass();
        myObject.Number = 1;
        Console.WriteLine(myObject.Number);
    }
}


생성자의 접근제한자를 private 등을 사용해서 클래스의 인스턴스 생성을 제한할 수 있다.

 

생성자는 파라미터를 추가한 형태로 선언이 가능하며 클래스의 인스턴스가 생성될 때 필드나 프로퍼티를 초기화하는 방법으로 사용할 수 있다.

 

public class MyClass
{
    public int Number { get; set; }
    private string _id;
    private string _pw;
    private int _age;
    private bool _isAgree;
    
    // 기본 생성자 형태
    public Number(string id, string pw, int age, bool isAgree)
    {
    	_id = id;
        _pw = pw;
        _age = age;
        _isAgree = isAgree;
    }
}

public class Program
{
    public static void Main()
    {
        MyClass myObject = new MyClass("bak", "****", 19, true);
        // 에러 발생
        MyClass myObject = new MyClass();
    }
}

 

이렇게 하면 인스턴스를 생성과 동시에 필드값을 초기화할 수 있다.

주의할 점은 이렇게 파라미터를 받는 생성자를 작성하게 되면 컴파일러에서는 더 이상 기본 생성자는 만들어 주지 않기 때문에 기본 생성자를 사용하려고 하면 컴파일 에러가 발생하게 되므로 기본 생성자도 사용하기를 원하면 추가로 작성해야 한다. 즉 생성자도 오버로딩이 가능하기 때문에 다양한 매개변수를 받는 생성자의 선언이 가능하다.

 

소멸자

생성자와는 호출 시점에만 차이가 있는 생명주기 메서드이다. (파괴자라고도 한다.)

소멸자는 객체가 소멸되는 시점에 호출되며 C#에서는 더 이상 객체가 참조되는 곳이 없을 때 GC에 의해서 관리되어 소멸될 때 소멸자가 호출된다.

 

따라서 소멸자의 호출 시점이 명확하지 않으므로 소멸자 내부에서 어떠한 기능을 수행시키게 한다면 동작에 대한 기대가 힘들기 때문에 C#에서는 이를 활용하는 경우는 드물다. 

 

public class MyClass
{
    public Number(){}
    // 소멸자 선언
    ~Number(){}
}

 

소멸자는 직접 호출도 불가능하기 때문에 별도의 접근 제한자를 지정할 필요도 없다.

728x90
반응형

일반 - 글로벌

Unreal Engine - Editor Settings General Global

 

모든 에디터에 영향을 끼치는 글로벌 설정이다.

이 설정 내용은 익스포터 하여 저장할 수 있으며 또한 저장된 파일을 임포트 하여 설정값을 불러올 수 있다.

변경된 설정은 프로젝트 폴더의 Saved > Config 폴더에 저장된다.

 

파생 데이터 캐시

Unreal Engine - Editor Settings > DDC

 

파생 데이터 캐시(Derived Data Cache, DDC)는 개발 과정에서 생성되는 파생 데이터를 저장하는 시스템이다.

파생 데이터에는 텍스처의 압축된 버전, 셰이더의 컴파일된 버전 등을 말하여 이 캐시는 데이터의 재계산이나 재생성 없이 빠르게 로드할 수 있도록 도와줌으로 에디터 및 게임의 런타임 성능을 향상하고 전반적인 컴파일 시간을 단축하는 역할을 한다.

 

즉 에셋을 처음 처리할 때 필요한 계산을 수행하고 결과를 DDC에 저장하는데 이후 동일한 에셋을 다시 로드할 필요가 있을때 DDC에 저장된 경우 미리 계산된 이 데이터를 즉시 사용할 수 있어 시간을 단축할 수 있다.

 

빌드 시 재사용 가능한 데이터가 DDC에 존재하면 셰이더 컴파일이나 에셋 변환과 같은 시간 소모적인 작업을 생략할 수 있기 때문에 규모가 큰 프로젝트 같은 경우 작업 시간을 절약할 수 있다.

 

또한 DDC는 로컬뿐만 아니라 네트워크 상에서도 위치할 수 있기 때문에 이를 통해서 동일한 DDC를 공유할 수 있어 협업에서 모든 팀원이 동일한 파생 데이터에 접근이 가능하며 데이터의 일관성을 유지할 수 있다.

 

따라서 글로벌 로컬 DDC 패스, 글로벌 공유 DCC 경로 설정을 통해서 필요한 데이터를 더 빠르게 재구성할 수 있기 때문에 프로젝트의 이전 및 이식성의 효율성을 높일 수 있다.

 

글로벌로 설정하면 모든 에디터에서 공통적으로 적용되며 고급 설정을 확장하여 현재 프로젝트에서만 적용되는 설정을 할 수 있다.

 

파생 데이터 캐시 알림

Unreal Engine - Editor Settings > DDC Notification

 

DDC와 관련된 작업이 수행될 때 알림을 받을 수 있도록 하는 기능으로 이 설정을 통해서 개발자가 DDC의 상태를 더 잘 파악하고 이해할 수 있도록 하여 관리를 돕는다.

 

이 기능은 수로 DDC 작업의 시작과 완료 과정에서 발생하는 에러 등을 실시간으로 알려주기 때문에 캐시가 올바르게 작동하고 있는지 또는 문제가 발생했는지를 즉시 파악할 수 있도록 모니터링할 수 있다.

 

DDC 작업의 모니터링을 통해서 성능에 미치는 영향을 파악하고 캐시된 데이터의 손상여부 확인이나 진단을 할 수 있어 문제의 원인을 빠르게 파악할 수 있기 때문에 성능 최적화와 작업의 효율성을 향상할 수 있다.

 

파생 데이터 캐시 S3

Unreal Engine - Editor Settings > DDC S3

 

DDC를 Amazon S3와 함께 사용하는 설정으로 대규모 게임 개발 프로젝트에서 주로 사용되는 설정이다.

S3는 Amazon Simple Storage Services로 AWS에서 제공하는 객체 스토리지 서비스로 인터넷을 통해 데이터를 저장하고 검색할 수 잇는 확장 가능한 스토리지 솔루션이다.

 

이 기능을 사용하면 어느 위치에서나 접근 가능한 중앙 집중식 DDC를 구축할 수 있기 때문에 전 세계에 분산된 팀원들이 동일한 파생 데이터에 액세스 하고 공유할 수 있다.

 

이 서비스는 높은 확정성을 제공하고 사용량에 따라 자동으로 저장 용량이 조정되기 때문에 대규모 데이터를 처리하는 상황에서도 안정적인 성능을 유지할 수 있다. 또한 데이터의 내구성과 가용성을 보장하기 위해 여러 지리적 위치에 데이터를 자동으로 복제하여 관리하기 때문에 게임 자산의 안전을 보장하며 데이터 손실의 위험을 최소화할 수 있다.

 

실제로 사용한 만큼의 비용을 지불하는 요금제를 제공하기 때문에 초기 투자 비용 없이 필요에 따라 스토리지를 조정할 수 있게 하여 비용의 효율성과 아마존의 네트워크 최적화와 캐싱 전략을 통해 빠른 데이터 액세스 속도를 제공한다.

 

이 설정을 사용하기 위해서는 우선 AWS 계정의 설정이 필요하다.

 

AWS S3

AWS 3S

 

AWS S3에서 계정을 생성하고 언리얼에서 설정을 통해서 필요한 데이터를 3S 버킷에 저장하여 사용할 수 있다.

 

글로벌 로컬 S3DDC 패스에서 다운로드 패키지 번들의 로컬 캐시 위치를 설정할 수 있다. 이 설정은 컴퓨터의 전체 프로젝트에 영향을 미친다.

728x90
반응형

편집

편집 메뉴에는 현재 프로젝트에서 수정과 관련된 작업을 할 수 있다.

Unreal Engine - Edit

 

실행 취소

최근에 실행된 작업을 취소한다.

 

다시 실행

실행 취소한 작업을 다시 실행한다.

 

실행 취소 히스토리 

최근에 실행된 항목들을 리스트로 볼 수 있고 선택하여 되돌릴 수 있다.

Unreal Engine - Redo History

실행 취소하거나 다시 실행하거나 선택하여 진행할 수 있다.

 

그 외에도 잘라내기, 붙여 넣기, 복사하기, 삭제하기 등 일반적인 에디터들에서의 동작들을 사용할 수 있고 단축키도 동일하다. 

 

에디터 개인설정

현재 에디터의 전체적인 설정을 다룰 수 있다.

개인설정 창에서는 다양한 설정들을 할 수 있으며 다음 포스팅에서 자세히 살펴본다.

Unreal Engine - Edit > Preference Settings

 

프로젝트 세팅

현재 프로젝트의 전체적인 설정을 다룰 수 있다.

 

마찬가지로 각 설정들에 대한 내용은 추가 포스팅으로 자세히 살펴본다.

 

플러그인

Unreal Engine - Edit > Plugin

 

플러그인에서는 현재 프로젝트의 플러그인에 대해서 다룰 수 있다.

기본적으로 필요한 플러그인들은 설치된 상태이며 추가로 필요 여부에 따라서 선택하여 추가 설치가 가능하다.

다양한 플러그인들이 있기 때문에 이 부분에 대해서도 따로 포스팅을 통해 자세히 다루도록 한다.

 

 

 

728x90
반응형

Editor

언리얼 프로젝트를 생성하게 되면 에디터가 열리게 되는데 우선 에디터가 어떤 기능들로 구성되어 있는지 살펴본다.

 

Menu Bar

에디터 상단에는 여러 메뉴들을 선택할 수 있는 메뉴 바가 있다.

Unreal Engine - Menu Bar

 

File

'파일' 메뉴에는 프로젝트 파일과 관련된 기능들이 있다.

Unreal Engine - File

 

새 레벨

새 레벨을 선택하면 '새 레벨'을 선택하는 팝업창이 뜬다. 

Unreal Engine - File > New Level

 

언리얼에서 '레벨'은 게임 내의 오브젝트, 환경, 조명, 카메라 등의 요소를 포함하는 컨테이너 역할을 한다. 

유니티로 치면 '씬'으로 볼 수 있다.

 

새로 생성된 레벨은 현재 레벨 저장(Ctrl + S)으로 저장하거나 다른 이름으로 저장(Ctrl + Alt + S)으로 저장할 수 있다.

 

레벨 열기

'레벨 열기'는 저장된 레벨을 선택하여 열 수 있다.

 

에셋 열기

현재 프로젝트에 설치된 에셋을 열 수 있다.

 

에셋은 언리얼 엔진 마켓플레이스에서 추가로 다운로드할 수 있다.

 

 

모두 저장

작업 중이던 내용 중 저장되지 않은 부분들을 모두 저장하는 기능이다.

 

저장할 파일 선택

저장되지 않은 변경 사항 중 선택해서 저장할 수 있는 기능이다. 클릭 시 저장할 콘텐츠의 목록 창이 팝업 된다.

Unreal Engine - File > Contents Save

 

 

레벨로 임포트

fbx 또는 obj 확장자 파일을 현재 레벨로 임포트 할 수 있다. 

언리얼에서는 프로젝트에 사용되는 리소스들이 Content 폴더에 저장되고 콘텐츠들을 fbx 또는 obj 확장자 파일로 내보내기 할 수 있으며 이를 다시 프로젝트에 임포트 할 수 있다.

 

언리얼 엔진에서 파일과 에셋들은 크게 콘텐츠 폴더와 엔진 폴더에 구분되어서 저장된다.

 

콘텐츠 폴더에는 특정 프로젝트에 특화된 자산을 저장하는 데 사용되며 게임 플레이와 직접적으로 관련된 모든 콘텐츠가 포함된다. 개발자가 직접 생성하고 관리하는 파일들이 대부분이며 프로젝트별로 독립적이다.

 

엔진 폴더에는 언리얼 엔진 자체에 필요한 핵심 파일과 자산을 저장하는 데 사용된다. 엔진 코드, 표준 플러그인, 필수 라이브러리, 시스템 설정 파일 등이 포함되어 있다. 이 폴더에 저장된 파일들은 언리얼 엔진을 설치한 모든 프로젝트에서 공통적으로 사용되기 때문에 이 폴더의 내용이 수정되면 모든 프로젝트에 영향을 미칠 수 있다. 일반적으로 엔진 업그레이드 시 업데이트되는 파일들이다.

 

유니티로 비교하면 Assets, Packages 폴더와 유사하다.

 

Unreal Engine - File > Import/Export

 

모두 익스포트

전체 레벨을 파일로 내보낸다.

 

선택 익스포트

선택된 오브젝트를 파일로 내보낸다.

 

새 프로젝트

새로운 프로젝트를 연다.

Unreal Engine - File > Project

 

프로젝트 열기

프로젝트를 선택하여 연다.

 

프로젝트 압축

현재 프로젝트를 압축하여 저장한다.

 

최근 프로젝트

최근에 연 프로젝트 목록이 리스트로 나타나며 선택하여 열 수 있다.

 

종료

현재 프로젝트를 종료한다.

728x90
반응형

Epic Games

에픽게임즈는 미국의 게임 개발회사로 게임 유통도 함께 서비스하고 있다.

1998년에 출시한 1인칭 슈팅 게임 <언리얼>을 개발할 때 사용한 자체 개발 게임엔진인 '언리얼 엔진'을 타사에 제공 및 판매하기 시작했으며 이 엔진을 사용하여 다양한 게임들이 출시되었으며 현재는 에픽게임즈를 대표하는 수준의 중요한 서비스 중에 하나가 되었다.

 

Unreal Engine

이름은 비현실적인 엔진이지만 현재 배포되는 엔진 중에서 가장 현실적으로 그래픽을 표현할 수 있는 엔진 중 하나이다. 따라서 게임뿐만 아니라 영화나 건축 등 고퀄리티의 작업을 위해서 사용되기도 한다.

 

흔히 말하는 AAA급 게임을 개발하는데 주로 사용되는 엔진으로 또 다른 대표적인 게임 엔진인 유니티와 비교했을 때 상당히 무거운 편이다. 따라서 개발하고자 하는 게임의 수준에 맞춰 엔진을 선택하는 것이 필요하다. 

 

 

Project Create 

언리얼 엔진을 설치하고 실행하게 되면 먼저 프로젝트를 생성하게 된다. 참고로 언리얼 엔진은 컴파일러를 비주얼스튜디오를 사용하고 있다.

 

포스팅에서 사용할 버전은 글을 작성하는 시점에서는 가장 최근에 출시된 5.4 버전을 사용한다.

 

프로젝트 생성 단계에서는 어떤 프로젝트를 만들 것인지에 따라서 몇 가지 기본 템플릿이 제공된다. 

 

Unreal Engine - Create Project

 

프로젝트 기본 설정에서는 몇 가지 설정을 선택하여 프로젝트를 초기화할 수 있는데 이 부분은 생성 이후에도 변경이 가능하다.

블루프린트 / C++

언리얼 하면 가장 대표적인 기능이 블루프린트이다. 

블루프린트는 구분하자면 언리얼 엔진으로 개발할 때 사용할 수 있는 프로그래밍 언어 중 한 종류로 볼 수 있다. 이러한 기능을 비주얼 스크립팅이라고도 하는데 유니티에서는 해당 기능은 기본기능으로 제공되지 않지만 스토어에서 구매하여 사용할 수 있다. 대부분 코딩 없이 개발이 가능한 기능으로 표현되는데 이 기능을 사용하기 위해서는 그래도 최소한의 언어적 이해도가 필요하다. 

 

또 다른 선택 가능한 언어는 C++이다.

이 부분에서 개발자들이 더 선호하기도 한다. 또 다른 대표적인 상용엔진인 유니티의 경우 C#을 프로그래밍 언어로 사용하고 있는데 C#에서는 메모리 관리를 위한 GC가 사용된다. 이는 사용자가 메모리 관리에 대한 신경을 쓸 필요를 덜어주지만 반대로 제어할 수 없다는 점도 있다.

 

언리얼의 경우에도 자동으로 관리를 해주는 GC나 스마트 포인터가 존재한다. 유니티와의 차이점은 사용자가 이 관리되는 메모리를 직접 제어할 수 있다는 점에서 차이가 있어 게임의 성능을 최적화하는 데에는 언리얼이 더 유리한 측면이 있다고 보인다.

 

 

 

 

 

 

728x90
반응형

 

네트워크

네트워크를 간단히 설명하자면, 우리가 일상적으로 인터넷에 접속하여 SNS, 뉴스, 동영상 등의 서비스를 사용하는 것과 같은 막연한 것들만 떠오르는데요. 간단하게 네트워크의 개념에 대해서 설명하자면 그물처럼 서로 연결된 노드들의 집합으로 정보와 자원을 공유하며 데이터를 교환하는 것입니다. 

 

 

먼저 네트워크란 개념이 어떻게 시작되었는지 과거로 돌아가봅니다.

1960년대 컴퓨터의 성능은 어느정도 발전을 이루었지만 여전히 비싼 가격대로 아무나 사용할 수 없는 장치였습니다. 이 당시 하나의 컴퓨터를 여러 사용자가 공유할 수 있는 시스템이 제안됩니다. 이때 제안된 게 시분할 시스템(TSS, Time Sharing System)으로 한 명의 사람의 입력만 받고 처리하기에는 컴퓨터에게는 너무나 쉬운 작업이었기 때문에 이를 활용하여 여러 사람의 입력을 받고 처리하도록 최대한 컴퓨터의 능력을 활용하기 위해서 제안되었습니다. 여기서 각 사용자들에게 컴퓨터 자원을 시간적으로 분할하고 사용하게 하며 대화식 인터페이스를 통해서 출력이 사용자에게 표시되고 키보드를 통해 입력된 정보를 처리합니다. 그러나 이 아이디어는 시연까지는 되었지만 구축이 어렵고 비용이 많이 들었기 때문에 보편화되지 못했으나 아이디어를 활용해서 현재의 컴퓨터에서 동작하는 여러 가지의 시스템이 이러한 방식을 따르고 있습니다.

시분할 시스템 (TSS, Time Share System)

 

TSS는 보급에는 실패했지만 현대에서도 사용되는 중요한 개념들을 정립하는 계기가 되었습니다.

- 자원공유 : 하나의 컴퓨터에 여러 사용자가 작업 할 수 있도록 하드웨어 자원의 효율적 사용

- 동시접근 : 여러 사용자가 동시에 컴퓨터에 접근 하고 데이터를 교환하는 상호작용할 수 있는 환경

- 분산처리 : 데이터와 처리 작업을 여러 컴퓨터 사이에서 나누어 처리

- 통신 프로토콜 : 여러 터미널과 중앙 컴퓨터 간의 효율적인 데이터 전송을 위한 규칙

 

이러한 개념들은 네트워크의 초석이 되기도했습니다.

 

ARPANET(Advanced  Research Projects Agency Network)

알파넷은 냉전 시대의 군사적 요구와 과학 연구의 필요성에 의해 만들어졌습니다.

개발 당시 미국 정부는 소련과의 기술 경쟁에서 우위를 점하기 위해 정보 기술의 발전을 꾀했으며 여러 연구 기관 간의 효율적인 정보 교류가 필요했습니다. 이 알파넷의 주요 혁신 기술은 패킷 스위칭 기술입니다. 이는 대용량 데이터를 작은 패킷으로 나누어 각각을 다른 경로로 전송하고 목적지에서 재조립하는 방식입니다. 이 기술은 데이터 전송의 신뢰성과 효율성을 크게 향상하게 되었습니다.

 

알파넷은 처음에는 UCLA, 스탠퍼드 연구소(SRI), UC 샌타바버라, 유타 대학교 네 개의 노드를 연결하여 운영을 시작했습니다. 이 초기 네트워크는 매우 기본적인 구조로 컴퓨터 과학자들에게 네트워킹 기술을 실험하고 개발할 수 있는 플랫폼을 제공하는 역할을 했습니다. 

 

그리고 네트워크 통신의 기본인 TCP/IP 프로토콜이 처음 개발되기도 했습니다. 이는 이후 인터넷 표준 프로토콜로 채택되어 현재까지도 전 세계적으로 사용되고 있습니다. 이 프로토콜은 복잡한 네트워크 구조를 상호 간의 연결을 가능하게 하는 기본적인 규칙에 대한 정의입니다. 

 

이외에도 최초의 전자 메일 시스템의 도입과 같은 다양한 혁신을 가져왔습니다. 네트워크를 통한 정보의 자유로운 교환은 학문적 공동체와 연구의 방식을 변화시켰고 현대의 인터넷 문화와 디지털 통신의 기반이 되는 등 ARPANET 그 자체로 사회적, 기술적으로 막대한 변화를 촉진하는데 기여하였습니다. 

 

Telenet

텔레넷은 알파넷의 주요 설계자 중 한 명인 Lawrence Roberts가 창립한 것으로 1970년대에 설립된 미국 최초의 상업적 패킷 스위칭 네트워크입니다. 알파넷이 군사적인 용도로 개발되었다면 텔레넷은 알파넷의 기술을 기반으로 하여 개발되었으며 일반 기업 및 개인 사용자들에게 네트워크 서비스를 상업적으로 제공하는 것을 목표로 하였습니다. 

 

 

텔레넷에서도 패킷 스위칭 기술이 사용되었으며 당시 사용되는 여러 프로토콜들을 계층구조의 개념을 도입하여 체계화시킨 x.25 표준을 도입하여 다양한 네트워크와의 호환성을 보장했습니다. 

 

특히 금융기관, 대학, 그리고 대기업들 사이에서 인기를 끌었으며 사용자들에게 원격으로 데이터베이스에 접근하고 파일을 전송하며 다른 네트워크 서비스를 이용할 수 있는 기능을 제공했습니다. 이 서비스는 정보의 접근성을 크게 향상하고 데이터 통신 비용을 줄이는데 크게 기여하기도 했습니다.

 

텔레넷은 상업적인 패킷 스위칭 네트워크로서의 성공이 증명되었으며 이후 다른 많은 상업 네트워크들의 등장에 큰 영향을 미쳤으며 기술적인 혁신뿐만 아니라 군사적 용도가 아닌 일반 사업 및 개인용으로도 널리 활용될 수 있음을 보여주면서 비즈니스 모델에서도 중요한 전환점을 제공하여 인터넷이 전 세계적으로 확산되기 이전에 디지털 통신의 가능성을 넓히는 데 중요한 역할을 했습니다. 

 

Ethernet

이더넷은 로컬 에리어 네트워크(LAN) 기술의 한 형태로 오늘날 가장 널리 사용되는 네트워킹 기술 중 하나입니다. 이더넷은 1973년에 제록스 PARC(Xerox Palo Alto Research Center)의 로버트 메트칼프(Robert Metcalfe)와 그의 동료들에 의해 처음 개발되었으며 이 기술은 컴퓨터들이 데이터 패킷을 공유 미디어를 통해 서로 전송할 수 있도록 하는 데 초점을 맞추었습니다. 

 

1970년대 초 제록스 PARC에서는 Alto라는 개인용 컴퓨터의 네트워킹 필요성을 인식하고 이를 해결하기 위한 방안으로 이더넷을 개발하기 시작했습니다. 메트칼프는 하와이 대학교의 ALOHAnet 무선 패킷 네트워크에서 영감을 받아 유선 환경에 적합한 네트워크를 설계하게 되었습니다.

PARC - Xerox Alto

제록스 알토는 데스크톱 메타포와 그래픽 사용자 인터페이스를 이용한 최초의 컴퓨터로 상업적인 프로젝트는 아니었지만 수십 년에 걸쳐 개인용 컴퓨터 특히 매킨토시와 썬 워크스테이션의 설계에 큰 영향을 주었습니다.

 

이더넷 기술은 계속해서 발전하여 초기 10 Mbps에서 기가비트 오늘날에는 10 기가비트 이상의 속도로 데이터를 전송할 수 있는 기술로 발전하였으며 또한 트위스티드 페어 케이블과 광섬유 케이블(Fiber-optic cable) 같은 다양한 전송 매체가 도입되기도 했습니다.

Twisted pair cable
Fiber-optic cable

 

현대에서 이더넷은 표준화와 호환성이 높아 다양한 네트워크 장비와 시스템에서 손쉽게 구현할 수 있어 광범위한 기업 환경은 물론 가정과 학교 등 다양한 곳에서 LAN을 구축할 때 기본적으로 사용되는 기술입니다. 간단한 개념과 구현의 용이성으로 인해 수십 년 동안 기술의 중심에 있었으며 네트워킹의 가장 기본적이고 중요한 기술 중 하나로 자리 잡게 되었습니다.

 

네트워크 케이블

이러한 네트워크의 연결을 위해서는 정보를 주고받을 수 있도록 물리적인 장치가 필요합니다. 

 

FLAG (Fiber-Optic Link Around the Globe) = FEA(Fiber-Optic Europe-Asia)

1990년대 후반 FLAG 해저 케이블 시스템은 아시아, 중동을 연결하는 글로벌 통신망 프로젝트로 1997년에 완공되었습니다. 이 케이블 시스템은 주로 대륙 간 데이터 통신 수요를 충족시키기 위해 설계되었으며 여러 국가와 대륙을 연결하는 역할을 합니다. 이 중 한국 또한 이 케이블 시스템의 주요 노드 중 하나가 되었습니다.

 

약 28,000 킬로미터에 달하는 광섬유 케이블로 구성되어 있으며 영국에서 출발하여 유럽, 중동, 아시아를 거쳐 일본까지 이어지는 것으로 북아메리카와 아시아를 연결하는 주요 노선 중 하나입니다. 주요 연결 지점(Node)으로는 영국, 프랑스, 이탈리아, 이집트, 사우디아라비아, 아랍에미리트, 인도, 태국, 말레이시아, 싱가포르, 홍콩, 대만, 한국, 일본 등의 해안 도시들과 연결되어 있습니다.

 

현재는 FEA로 초기 FLAG 시스템이 더 많은 국가와 지역을 포괄하였지만 경제적 중요성에 따라서 유럽과 아시아 지역 간의 특정 연결성의 강화에 의해서 FEA로 변경되기도 했습니다.

 

이외에도 아시아 태평양 지역의 여러 국가들을 연결하는 APCN(Asia Pacific Cable Network) 등 필요와 기술의 발전에 따라서 추가로 케이블들이 설치되기도 했습니다.

 

통신망은 규모에 따라 다양하게 분류됩니다.

LAN(Local Area Network)

근거리 통신망으로 가까운 거리에 있는 단말 간의 네트워크를 말합니다. 한정된 공간 내에 분산 설치되어 있는 단말을 통신회선 연결을 통해 상호작용 가능하게 한 네트워크로 단일 구성은 거리적으로 한정되지만 복수의 근거리 통신망을 설치하여 대형 네트워크를 형성하게 됩니다. 이때 다른 종류의 LAN은 게이트워이라는 통로를 통해서 연결되어 사용하게 됩니다.

 

MAN(Metropolitan Area Network)

도시권 통신망으로 근거리 통신망이 1개 기업의 범위 또는 빌딩 전체를 연결하는 네트워크라면 도시권 통신망은 이를 확장하여 하나의 도시 내로 확장한 네트워크입니다. 초기 통신망이 구축되었을 때는 존재하지 않았지만 휴대전화의 보급으로 인해서 각 도시마다 네트워크를 구축할 필요가 생기게 되어서 기지국이 생기게 되었는데 이 기지국을 칭하는 개념으로 생겨나게 되었습니다. 도시권 통신망은 다른 도시권 통신망과 직접적으로 연결되어 있습니다.

 

WAN(Wide Area Network)

광역 통신망으로 도시 간 또는 국가 간 등을 연결하는 통신망입니다. 대부분 통신사가 전국에 회선을 깔아서 구축한 통신망으로 가장 최상위 규모의 통신망입니다. 일반적으로 개인이 네트워크에 연결될 때는 대부분 LAN을 통해 이루어집니다. 그리고 연결하고자 하는 네트워크의 범위에 따라서 MAN을 거치거나 WAN을 거쳐 목적지에 도착하게 되는데 이때 ISP를 거치게 됩니다. 우리가 특정 사이트를 방문하다 보면 연결이 차단되기도 하는데 이것은 ISP에 의해서 관리를 받기 때문입니다.

 

 

이외에도 기업에서 통신사로부터 회선을 임대받아 광역 통신망 간의 직접 연결한 경우도 있으며 대표적으로 인트라넷이 이러한 경우입니다. 

 

ISP(Internet Service Provider)

인터넷 서비스 제공자로 개인, 기업, 정부 등 고객을 대상으로 인터넷 접속 서비스를 제공하는 회사나 조직을 말합니다. 대한민국의 경우 KT, SKT, LG 등의 통신사들의 인터넷 서비스를 ISP라고 볼 수 있습니다.

 

 

 

728x90
반응형

에디터 버전 : 2021.3.28f1 (LTS)

Asset Pipeline

예전 에디터 버전에서는 Asset Pipeline 은 version 1, 2를 구분하여 선택하여 사용할 수 있었지만 최근 버전에서부터는 Asset Pipeline 2로 자동설정되며 선택할 수 없다.

 

Asset Pipeline

 

에셋을 처리하는 과정에 대한 설정을 관리하는 항목들이다.

 

Remove unused Artifacts on Restart

재실행시 사용하지 않는 아티팩트들을 삭제할지 여부에 대한 토글로 기본으로 활성화된 상태이다.

Remove unused Artifacts on Restart

 

유니티는 에디터가 실행될 때 라이브러리 폴더의 artifact 파일과 에셋 데이터베이스 엔트리에서 제거한다.

가비지 콜렉션의 형태로 이 설정을 비활성화하면 에셋 데이터베이스의 가비지 컬렉션이 비활성화된다.

즉 더 이상 사용하지 않는 수정된 아티팩트가 에디터가 재실행될 때에도 계속 보존되기 때문에 예상하지 못한 임포트 결과를 디버그 할 때 유용하다.

 

하지만 계속해서 사용하지 않는 데이터들이 쌓여갈 수 있기 때문에 일반적인 상황에서는 활성화해두는게 나을 것 같다.


라이브러리 폴더

유니티에 임포트 된 에셋은 두 가지 버전으로 구분된다. 하나는 사용자가 사용하기 위한 것이고 다른 하나는 유니티가 사용하기 위한 것이다. 이 유니티가 사용하기 위한 에셋은 프로젝트의 라이브러리 폴더에 캐시로 생성된다. 즉 라이브러리 폴더 내의 캐시들은 로컬에서 에디터가 빠르게 작업을 처리하기 위해 사용하는 정보들로 많은 정보들을 계속해서 저장하기 때문에 용량이 큰 편이다.

 

로컬에서만 필요한 이 정보들은 프로젝트가 켜질 때마다 확인하는 과정을 거치며 폴더가 없으면 다시 생성하기 때문에 프로젝트를 공유하는 경우에는 제외시켜도 되는 파일들이다.


 

Parallel Import

Parallel Import

 

에셋을 임포트 할 때 동시에 진행하도록 하는 설정이다.

 

Parallel Import tip

 

해당옵션은 기본으로 비활성화되어있고 이 경우 에셋을 순차적으로 임포트 하게 된다.

 

이 기능은 특정 유형의 에셋에서만 지원되며  에디터가 프로젝트 폴더에서 에셋이 새로 임포트 되거나 수정된 에셋을 감지하고 자동으로 임포트 할 때 발생하는 에셋 데이터베이스가 새로고침을 수행할 때만 실행된다. 이때 에셋은 하위 프로세스에서 임포트가 실행된다.

 

특정유형

- Texture Importer로 가져온 이미지 파일

- Model Importer 로 가져온 모델 파일

 

특정 유형은 임포트 시간이 오래 걸리는 두 가지로만 구성되며 현재 버전까지는 별도의 스크립터블이 가능한 API는 마련된

지 않은 상태이다.

 

Parallel Import

 

이외의 유형은 해당 설정이 활성화되어 있어도 순차적으로 임포트 된다.

 

Desired Import Worker Count

병렬 임포트에서 사용할 작업 프로세스의 최적의 수

 

Standby Import Worker Count

쉬고 있는 상태에서도 유지시킬 최소의 작업 프로세스의 수

에디터에서 작업에 필요한 프로세스의 수가 최소보다 큰 경우 쉬고있는 프로세스를 중지시키고 시스템 리소스를 확보하도록 한다. 

 

Idle Import Worker Shutdown Delay

쉬는 상태의 작업 프로세스를 종료할 때 대기하는 시간

 

또한 Edit > Preferences > Asset Pipeline에서 새 프로젝트에서 필요한 작업 프로세스의 기본 값을 제어할 수 있다.

Preferences > Asset Pipeline

 

Import Worker Count % 의 값을 사용하여 Desired Import Worker Count 값을 할당할 수 있다.

이때 할당되는 값은 시스템에서 사용할 수 있는 논리 코어 수의 비율에 해당한다.

(16개의 논리 코어가 있다면 이중 25%를 할당하여  Desired Import Worker Count 값은 4가 할당된다.)

 

Cache Server (project specific)

Cache Server

Asset Pipeline 1 일 때 사용한 기능으로 버전 2에서는 기본으로 비활성화되어 있고 활성화할 수 없고 Unity Accelerator로 대체되었다.

 

Accelerator

팀 작업 속도를 높이기 위한 기능이다.

임포트 한 에셋의 사본을 유지하는 캐싱 프락시 에이전트이다. 팀이 동일한 네트워크에서 작업할 때 프로젝트 일부를 다시 임포트 할 필요가 없도록 하여 반복 시간을 줄일 수 있도록 돕는다.

 

Unity Accelerator

 

Prefab Mode

프리팹 관련 설정

Prefab Mode

 

Allow Auto Save

프리팹 설정 시 자동으로 저장되는 기능을 활성화할지 여부를 정할 수 있다.

활성화된 경우 프리팹 수정 씬에서 자동 저장 기능을 사용할 수 있는 상태가 된다.

 

Prefab Scene Auto Save - Enable

 

Prefab Scene Auto Save - Disable

 

Editing Environments

프리팹을 수정하는 환경을 편집하는 기능을 제공한다.

 

Regular Environment

일반 프리팹을 편집하는 환경에서 사용하고자 하는 신을 할당하면 배경으로 사용할 수 있다.

Regular Environment

 

UI Envrionment

UI 프리팹의 편집하는 환경에서 사용할 수 있다.

UI Environment

 

Graphics

Graphics

 

Show Lightmap Resolution Overlay

씬의 드로우 모드 중에서 Baked Lightmap 모드에 체커보드 오버레이를 그린다. 

여기서 타일 하나는 텍셀에 해당하며 라이트매핑 작업 시 씬의 텍셀 밀도를 확인할 수 있다.

Draw Mode - Baked Lightmap / left enable

 

Use legacy Light Probe sample counts

활성화 시 Progressive Lightmapper를 사용하여 베이크 할 때 고정된 라이트 프로브 샘플 수를 사용한다. 

Direct Sample 64, Indirect Sample 2048, Environment Sample 2048

Lighjtmapping - right enable

 

Enable baked cookies support

2020.1 이상의 프로젝트는 기본적으로 베이크 된 쿠키가 Progressive Lightmapper의 베이크된 광원과 혼합 광원에 대해 활성화된다. 이전의 경우 해당 부분이 비활성화되는데 이 옵션은 이전 버전과의 호환성을 위해서 제공되는 기능이다.

 

Cookie

특정 모양이나 색상의 그림자를 만들기 위해 광원에 배치하는 마스크로 광원의 모양과 강도를 변경한다.

쿠키를 통해 런타임 성능에 최소한 또는 전혀 영향을 미치지 않는 선에서 복잡한 조명 효과를 효율적으로 사용할 수 있다.

Light cookie

 

728x90
반응형

바이너리와 텍스트(YAML) 비교

비주얼 스튜디오에서 바이너리를 볼 수 있는 확장 툴을 설치해서 해당 파일을 분석해 본다.

 

프로젝트 설정 중에서 에셋 데이터를 관리하는 방식인 바이너리와 텍스트 두 가지에 대해서 몇 가지 테스트를 해볼 것이다.

두 방식을 비교해 보기 위해서 프로젝트에서 모든 컴포넌트의 데이터가 동일한 오브젝트를 생성해 보고 차이점을 비교한다. 

 

하이어라키에서 큐브를 생성하고 프리팹으로 만들어 파일을 확인해 본다.

.prefab Text

파일의 크기는 3kb이며 파일 내용은 YAML 형식으로 오브젝트의 모든 컴포넌트의 정보가 저장되어 있다.

길이는 100줄 정도 된다.

.prefab Text view

 

데이터 내용을 그대로 보아도 어떤 정보를 담고 있는지 파악하기 쉽다.

 

그대로 프로젝트 세팅에서 Asset Seriailization 모드를 Force Binary로 변경한다.

 

.prefab Binary

 

용량이 더 줄어들었을 거라고 예상했지만 반대로 증가했다.

 

.prefab Binary view

 

파일의 마지막은 다음과 같이 정보를 보여준다.

좌측의 메모리주소와 우측의 아스키코드에 대응하는 문자는 편집기의 기능으로 데이터에 포함되지 않는 정보일 것이다.

Binary

 

맨 앞의 8자리 숫자+알파벳의 조합은 16진수로 보인다.

이 주소가 16 단위로 증가하고 뒤에 오는 정보는 8 + 8 총 16으로 정보의 개수를 의미하는 것 같다.

ASCII

메모리 주소 뒤에 오는 행렬 형태의 정보는 아스키코드로 보이는데 아스키 테이블에서 20은 공백, 3C는 < 로 확인할 수 있다. 따라서 맨 우측에는 테이블에 대응하는 문자를 확인된다.

 

마지막 주소가 2030으로 10진법으로 변환 시 8240이다. 즉 총 8240개의 데이터가 담겨있으며 파일의 크기가 9kb인 것으로 생각해 볼 때 하나에 1byte로 떨어지고 각 데이터가 아스키코드이므로 1byte라고 생각하면 얼추 맞아떨어지는 거 같다.

 

파일크기는 9kb로 나오는데 해당 파일을 속성을 열어서 자세히 보면

.prefab size

더 근접한 크기임을 알 수 있다. 

 

좀 더 정밀하게 계산하면 마지막 줄에는 데이터 4개가 빠져있어서 8236이다. 즉 최종적으로 16byte가 모자라다.

만약 마지막 메모리가 온전히 16을 차지한다고 해도 8240이 최대일 텐데 그래도 12byte가 채워지지 않는다.

 

어디서 계산이 잘못된 건지 이 부분은 다시 확인해 볼 필요가 있다.

 

다시 본래의 목적으로 돌아가서 YAML 형식이 바이너리보다 용량이 적은 것은 의문이 들어서 프리팹의 크기를 키워보기로 한다. 기존의 큐브 프리팹에 자식으로 큐브를 추가해서 수정해 결과를 확인해 본다.

 

+1 cube biary

 

바이너리의 경우 768 byte 가 추가되었다.

 

모드를 변경해서 Text의 크기를 확인해 보니 6kb로 처음 경우에서 2배로 사이즈가 커졌다. 증가량만 따졌을 때는 엄청난 크기 차이가 있다.

 

몇 번 더 큐브를 추가해 보면서 살펴본다.

큐브 개수 / 파일 사이즈(kb)  Binary Text
1 9 3
2 9 6
3 10 9
4 11 12
20 23 56
100 82 276

 

프리팹에 오브젝트가 많이 포함되어 있을수록 파일의 사이즈는 확연히 차이가 난다.

게임을 만들다 보면 프리팹 하나에 여러 오브젝트들이 붙어있게 되는 경우는 많기 때문에 거의 일반적으로 Text 모드가 용량이 크다고 보인다.

 

비교

테스트 결과로 비교해 보면 바이너리를 사용하는 것이 데이터의 크기를 줄여주기 때문에 프로젝트를 열고 데이터를 저장하는 과정에서 시간이 단축될 수 있다.

 

하지만 유니티를 사용한 프로젝트를 협업할 때에는 바이너리보다는 Text 가 권장된다. Github에서는 공식문서에서 해당 부분에 대하여 Force Text로 설정해야 한다고 명시해 두었다.

 

Github unity Asset Serialization

 

Github - Git and Unity

 

Git and Unity

Git and Unity. GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

 

유니티에서도 기본값은 Force Text이며 이렇게 Force Text를 권장하는 이유는 바이너리 형식으로는 파일을 수정하고 병합하는 것이 불가능하다. 따라서 변경된 사항을 파악하는 것이 불가능한데 협업뿐만 아니라 개인 프로젝트 또한 버전 컨트롤을 사용하는 것이 일반적인데 해당 기능을 사용하지 못하는 Mixed 또는 Binary 모드는 더 이상은 사용되지 않는 기능으로 생각된다.

 

 

 

728x90
반응형

+ Recent posts