Developer Tools

에디터에서 개발자를 위한 설정들이 제공된다.

Unreal Engine - Editor Settings Miscellaneous

 

 

UI 익스텐션 포인트 디스플레이

이 설정을 활성화하면 에디터에서 추가적인 UI 정보가 표시된다.

Unreal Engine - UI Extension Pointer Display

 

문서 링크 디스플레이

해당 설정을 활성화하면 마우스 호버시 보이는 툴팁에 추가로 문서 페이지가 제공된다.

Unreal Engine - Docs link display

 

프로젝트 배지에 엔진 버전 번호 디스플레이

Unreal Engine - Engine version number display

 

엔진 버전 번호가 추가로 표시된다.

 

Unreal Engine - Engine version number display

 

AI

Unreal Engine - Engine AI

 

비헤이비어 트리 디버거 데이터 항상 수집

이 설정은 특정 디버깅 기능과 관련된 옵션으로 AI 컴포넌트의 일부인 비헤이비어 트리(Behaviour Tree)의 동작을 실시간으로 모니터링하고 분석하는 데 사용할 수 있다. 비헤이비어 트리는 주로 NPC나 기타 게임 내 인공지능 캐릭터의 행동을 제어하는 데 사용된다.

 

설정을 활성화하면 에디터나 게임이 실행되는 동안 비헤이비어 트리의 모든 활동과 상태 변화가 지속적으로 기록되는데 이는 개발자가 AI의 행동 패턴을 더 잘 이해하고 문제를 진단하는데 도움 받을 수 있다.

 

유용한 기능이지만 데이터를 항상 수집하기 때문에 성능에 영향을 줄 수 있다. 데이터 수집 과정에서 추가적인 처리가 필요하기 때문에 특히 대규모 AI 시스템을 사용하는 게임에서는 성능 저하에 유의해야 한다.

 

일반적으로 이 설정은 개발 중이나 테스트 단계에서 문제를 해결하기 위한 디버깅 용도로 사용되며 성능을 위해서 릴리즈 버전에서는 비활성화하는 것이 좋다. 수집된 데이터는 언리얼 엔진의 디버거 도구를 통해 시각적으로 표현될 수 있으며 이를 통해 개발자는 비헤이비어 트리의 각 노드에서 발생하는 결정과 변경사항을 보다 쉽게 추적할 수 있다.

 

블랙보드 키를 알파벳 순으로 디스플레이

비헤이비어 트리의 블랙보드에서 사용되는 키들을 알파벳 순서로 정렬하여 표시하도록 설정하는 기능으로 블랙보드의 데이터를 관리하고 검토할 때 편의성을 높이기 위해 사용된다.

 

많은 수의 키가 있을 때 알파벳 순으로 정렬하면 필요한 키를 빠르고 쉽게 찾을 수 있고 키들을 체계적으로 정리하여 블랙보드를 보다 효과적으로 관리할 수 있어 가독성과 관리 용이성을 향상할 수 있다. 

 

비헤이비어 트리 디버거 데이터 항상 수집과 블랙보드 키를 알파벳 순으로 디스플레이 설정은 사용 중인 트리와 블랙보드의 수가 많을 때 유의미한 결과를 확인할 수 있기 때문에 어떤 식으로 표시되는지 정보에 대한 확인은 이후에 다시 작성하도록 한다.

 

Simplygon Swarm

Unreal Engine - Engine Simply Swarm

 

언리얼 엔진에서는 3D 모델 최적화와 자동 LOD 생성을 위한 소프트웨어인 Simplygon을 사용한다.

Simplygon을 통해서 게임 내에서 3D 모델의 성능을 향상하기 위해 다양한 디테일 레벨을 자동으로 생성하고 관리할 수 있다. 

 

Simplygon Swarm은 이러한 Simplygon과 관련된 데이터를 분산처리하는 시스템이다. Simplygon은 주로 3D 모델의 폴리곤 수를 줄이는 데 사용되며, 고품질의 LOD(Level of Detail) 모델을 생성하는 데 이러한 최적화 작업을 여러 대의 컴퓨터에 분산시켜 작업 효율성을 극대화한다.

 

Simplygon 배포 프록시 서버 사용

Simplygon Swarm은 위 작업을 위해서 제안된 기능으로 해당 설정을 활성화하면 작업 처리와 데이터 관리에 있어 중앙 집중화된 접근 방식을 취하게 된다. 배포되기 전 개발 단계에서 사용되는 도구이며 개발 단계에서 자원의 효율성을 증가시키기 위해서 사용한다. 이 설정을 활성화해야 관련된 다른 설정들도 활성화된다.

 

Simplygon 배포 프록시 서버 IP

분산처리 작업을 위한 프록시 서버 IP를 설정한다.

프록시 서버는 Simplygon Swarm의 네트워크 통신 허브로 작업을 여러 에이전트(작업을 실제로 수행하는 컴퓨터)에게 분산하는 중추 역할을 한다. 이 서버는 각 에이전트의 상태를 모니터링하고 최적의 분산 전략을 수립하여 작업을 효율적으로 할당한다. 

 

프록시 서버는 각 에이전트의 리소스 사용 상태를 파악하여 특정 에이전트에 과부하가 걸리지 않도록 작업을 분산하여 전체 시스템의 효율성을 높이고 작업 시간을 최소화하는 데 도움을 준다.

 

스웜 디버깅 활성화

Simplygon Swarm에서 분산 처리 작업을 진행할 때 발생하는 다양한 이벤트와 오류를 모니터링하고 로깅하는 기능이다.

이 설정을 활성화하면 시스템의 동작을 보다 상세하게 이해할 수 있으며 발생하는 문제들을 신속하게 진단하고 해결하는데 도움을 준다.

 

- 작업 중 발생하는 네트워크 문제, 데이터 처리 오류, 작업 실행 실패 등의 오류를 기록하여 오류를 추적한다.

- 작업 할당, 데이터 전송, 작업 완료 등의 이벤트가 발생할 때마다 로그에 기록되는 이벤트 로깅을 통해서 시스템의 전반적인 흐름과 작업 처리 상태를 확인할 수 있다.

- 시스템의 성능을 실시간으로 모니터링하면서 성능 지표를 기록하여 시스템 최적화와 자원 할당에 중요한 정보를 얻을 수 있다.

- 디버깅 데이터를 분석하여 시스템의 성능을 향상하거나 잠재적인 문제를 사전에 파악하고 수정하는 데 사용할 수 있다.

 

MS 단위 시간 json 요청 간 딜레이

Simplygon Swarm의 각 노드 간에 발생하는 JSON 데이터 요청들 사이에 설정된 딜레이를 의미한다. 밀리 세컨드 단위로 설정할 수 있으며(기본 5000ms) 네트워크 트래픽을 조절하고 서버의 부하를 관리할 수 있다.

 

효율적인 시스템 관리와 최적의 성능 유지를 위한 설정 중 하나로 데이터 처리와 네트워크 통신의 안정성을 보장하고 전체적인 시스템 운영의 효율성을 높일 수 있다.

 

Swarm 시스템에서는 다수의 노드가 서로 데이터를 요청하고 응답하는 과정에서 네트워크 트래픽이 급격히 증가할 수 있는데 이때 딜레이를 설정함으로써 요청이 일정한 간격으로 이루어지게 하여 네트워크의 과부하를 방지한다. 딜레이를 통해 각 요청이 처리되기까지의 시간을 일정하게 하여 서버가 한꺼번에 많은 요청을 처리해야 하는 부담을 줄인다. 이는 서버의 안정적인 운영을 도와주고 시스템의 전반적인 응답성을 개선한다.

 

너무 많은 요청이 짧은 시간 내에 발생할 경우 일부 요청이 실패할 가능성이 있어 딜레이를 적절히 설정하여 요청 실패율을 줄일 수 있다. 네트워크와 서버의 처리 능력을 고려하여 딜레이를 설정해야 하며 너무 짧은 딜레이는 시스템에 과부하를 주며 너무 긴 딜레이는 전체 작업의 처리 속도를 저하시킨다. 딜레이 설정 후에도 시스템의 성능과 안정성을 지속적으로 모니터링하고 필요에 따라 딜레이 값을 조정하는 것이 중요하다.

 

Simplygon 그리드 서버에 제출할 동시 작업 수

서버에서 동시에 처리할 수 있는 작업의 수를 지정하는 설정이다. 이 설정은 Simplygon Swarm의 작업 분산 및 처리 효율성을 관리한다. 서버의 리소스를 효율적으로 활용하기 위해 동시에 실행할 수 있는 작업의 수를 조정하여 서버의 처리 능력과 메모리 사용을 고려하여 작업의 처리 속도를 타협하여 균형 있게 조절할 수 있다. 

 

Simplygon 스웜 zip 파일 최대 업로드 용량(MB)

Simplygon 그리드 서버로 업로드할 수 있는 zip 파일의 최대 크기를 제한하는 설정이다.

이는 서버의 데이터 처리 능력과 네트워크의 대역폭 저장 공간 등을 고려하여 설정하여 네트워크 트래픽과 서버의 저장 공간을 효율적으로 관리한다. 최대 용량보다 큰 파일은 청크로 분할된다.

 

서버가 한 번에 처리할 수 있는 데이터 양을 제한하여 서버의 과부하를 방지하고 데이터 처리 효율을 유지하며 대용량 파일의 업로드가 네트워크에 미치는 영향을 최소화한다. 시스템의 안정성을 유지하기 위해 각 사용자가 업로드할 수 있는 파일의 크기를 제한함으로써 서버에 발생할 수 있는 예기치 않은 문제들을 사전에 방지한다.

 

Simplygon 스웜 Intermediate 폴더

작업의 중간 데이터를 저장하는 경로를 지정하는 설정이다. 3D 모델 최적화 프로세스 동안 생성되는 임시 파일들이나 처리 중인 데이터를 보관하는 장소로 사용되며 스웜에 업로드되는 중간 텍스처와 메시 데이터가 저장된다.

 

처리 중인 3D 모델의 데이터를 체계적으로 관리하여 프로세스의 효율성을 높이고 데이터 접근성을 개선하여 데이터를 조직화하고 프로세스 중 생성되는 임시 파일들을 별도의 위치에 저장함으로써 최종 출력 파일과 중간 파일을 명확히 구분할 수 있어 이는 작업의 명확성과 추적성을 향상해 작업의 효율성을 향상한다. 대용량 데이터의 경우 처리 시 시스템의 리소스를 효과적으로 활용하고 서버의 부하를 분산시키는 역할을 한다.

728x90
반응형

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
반응형

+ Recent posts