728x90

-TArray

Reset() : 배열의 모든 요소를 제거, 할당된 메모리는 유지, 즉 배열을 다시 채울 계획이 있어서 메모리가 재할당을 피하고 싶을때 사용

Empty() : 배열의 모든 요소를 제거, 할당된 메모리 까지 해제, 즉 배열을 더이상 사용하지 않아서 메모리 사용을 줄이고 싶을때 사용

 

-Delegate

UFUCTION() 매크로 : 델리게이트에 등록하여 사용할 함수는 UFUNCTION 매크로를 선언해주어야 한다. 이유는 언리얼에서 이 매크로를 통해 리플렉션 시스템이 해당 함수를 인식하고 등록하여 사용될수 있도록 작동하기 때문

IsBound() or IsAlreadyBound() : 언리얼에서는 델리게이트에 함수를 등록하려할때 이미 해당함수가 등록되어 있으면 에러를 발생시킨다.
언리얼에서는 기본적으로 중복 등록을 허용하지 않으며, 중복 등록으로 인한 의도하지 않은 동작, 메모리 누수와 같은 성능문제, 기타 예상치 못하는 예외 발생등을 고려하여 허용하지 않는다.

그래서 함수를 등록전에 이 함수들을 사용하여 이미 등록되어있는지 체크를 하여 등록 해줄수 있다.

RemoveAll(const void* InUserObject) or Clear() : 위 함수 델리게이트 등록전 등록 여부를 체크하는것이 아닌, 이 함수들을 사용하면 현재 델리게이트에 등록되어있는 함수들을 제거해준다.
차이점은 RemoveAll은 해당하는 객체에 등록된 모든 함수를 제거 해주는것으로 보통은  this인자로 해당 객체를 넘겨준다, Clear는 델리게이트에 등록된 모든 함수를 그냥 제거해 주는것이다.

그래서 델리게이트에 중복 등록 여부 체크를 하고 싶지 않다 하면 종료시점에 델리게이트에 등록된 함수를 제거해주는것도 하나의 방법이다.

728x90
Posted by 정망스
,
728x90

작업을 하던중 브러시 모드에서 펜툴을 이용해 내가 원하는 모양의 지오메트리를 생성했고
브러시 세팅 탭에서 브러시 셰이프를 내가 직접 만든 클래스 (ATriggerVolume 상속)로 변환해주었다.
의도는 내가 원하는 모양의 충돌 영역을 만들고 싶었던것이다.

그런데 작업을 하고 충돌 체크를 확인해보는데 아예 충돌 자체가 안되는 것이다.

찾다가 브러시 버텍스 정렬이라는 것을 보았고 이걸 한번 거친후에 다시 확인해보니 충돌이 제대로 되었다.

정확한 정보인지는 알수 없지만 내가 알아본 바로는
언리얼 엔진에서 브러시를 사용하여 TriggerVolume을 만들 때, 브러시의 버텍스(Vertex)가 제대로 정렬되지 않으면 충돌 체킹이 제대로 작동하지 않을 수 있다라는 것이다. 

브러시 버텍스 정렬을 통해  기대할수 있는 상황은 아래 3가지 정도였다

1. 정확한 지오메트리 생성: 브러시의 버텍스가 정렬되지 않으면, 브러시의 지오메트리가 왜곡되거나 비정상적으로 생성될 수 있다. 이로 인해 충돌 체킹이 제대로 작동하지 않을 수 있다.
버텍스 정렬을 통해 브러시의 지오메트리가 정확하게 생성되면, 충돌 체킹도 정상적으로 작동하게 된다.

2. 충돌 데이터 갱신: 브러시의 버텍스를 정렬하면, 언리얼 엔진은 브러시의 충돌 데이터를 갱신한다.
이 과정에서 충돌체의 경계와 폴리곤이 다시 계산되므로, 충돌 체킹이 정상적으로 작동하게 된다.

3. 브러시의 일관성 유지: 버텍스 정렬은 브러시의 일관성을 유지하는 데 도움이 된다.
일관된 브러시는 충돌 체킹과 같은 물리 연산에서 더 예측 가능하고 안정적으로 작동한다.

비슷한 상황으로 안된다면 버텍스 정렬을 해보자.

728x90
Posted by 정망스
,
728x90

언리얼에서 TFieldIterator을 사용하여 리플렉션으로 속성과 함수들의 검색이 가능하다.

멤버 변수에는 UPROPERTY, 멤버 함수에는 UFUNCTION 매크로를 지정해주어야 가능하다.

 

TFieldIterator<UProperty>타입을 사용하면 속성을 가져올수 있다.

for (TFieldIterator<UProperty> It(ClassInfo1); It; ++It)
{
    AB_LOG(Warning, TEXT("Field : %s, Type : %s"), *It->GetName(), *It->GetClass()->GetName());
    UStrProperty* StrProp = FindField<UStrProperty>(ClassInfo1, *It->GetName());
    if (StrProp)
    {
       AB_LOG(Warning, TEXT("Value = %s"), *StrProp->GetPropertyValue_InContainer(WebConnection));
    }
 }

 

TFieldIterator< UFunction >타입을 사용하면 함수을 가져올수 있다.

for ( TFieldIterator<UFunction> FunctionIterator( MyObjectsClass ); FunctionIterator; ++FunctionIterator )
{
    UFunction* Func = *FunctionIterator;
    
    UE_LOG( LogTemp, Log, TEXT( "%s" ), *FunctionIterator->GetName() ); 
}

 

함수의 경우 NativeFunctionLookupTable 배열을 사용해 현재 클래스에 어떤 함수가 있는지 알수 있다.

함수의 이름을 사용하여 FindFunctionByName함수를 사용해 가져올수 있다.

for (const auto& Entry : ClassInfo1->NativeFunctionLookupTable)
{
    AB_LOG(Warning, TEXT("Function=%s"), *Entry.Name.ToString());
 
    UFunction* Func1 = ClassInfo1->FindFunctionByName(Entry.Name);
    if (Func1->ParmsSize == 0)
    {
        WebConnection->ProcessEvent(Func1, NULL);
    }
}

 

728x90
Posted by 정망스
,
728x90

이펙트에 입체적으로 라이팅을 적용하는 기술이다.

기존에 이펙트 시스템에서는 라이팅에 자연스럽게 반응하지 않는 미스 매치가 되는 상황이 종종 발생할수 밖에 없었다고 한다.
이번에 6-way lighting을 적용하면 환경에 자연스럽게 반응하는 이펙트를 제작할수 있게 됬다고 한다.

6-way lighting의 구조는 노말맵을 6방향(위, 아래, 앞, 뒤, 좌, 우)으로 2장의 텍스쳐를 사용해서 6면을 커버하는 방식이라고 한다.

출처 : Unity Korea Youtube

텍스쳐 2장을 사용하여 각각의 RGB 채널에서 6방향을 담당하고
한장의 알파채널에서는 투명값 알파값을 담당하고
다른 한장의 텍스쳐에서는 emissive나 기타 여러가지등을 담당하는 구조로 되어있다고 한다.

Ouput Particle 영역을 선택하고 인스펙터 창을 보면 Lighting 영역의 Material Type에 Six Way라는 옵션이 있다.
이 옵션을 선택하게 되면 앞서 말한대로 2장의 텍스쳐를 이용해 6면을 담당하기 때문에 Positive, Negative의 텍스쳐 2장을 세팅할수 있게 된다.

그리고 2개의 텍스쳐중 하나의 텍스쳐 알파채널에서는 emissive와 같은 처리를 담당한다고 했다 옵션을 보면 Emissive Mode를 Single Channel을 통해서 적용할수 있다.

여러 빛에 반응해서 이펙트가 발생하는 만큼 퀄리티는 확실히 더 좋아질수 있지만 그만큼 고려하고 계산해야 되어지는 양이 많아지기 때문에 모든 이펙트를 6-way lighting 방식으로 적용하기에는 성능 이슈가 있을수 있다.

그래서 이 방식을 사용할때는 개발 과정에 있어서 이펙트의 중요도 혹은 환경에 따라 잘 고려해서 사용해야 할 필요성이 있다.

라이팅의 색깔, 카메라가 보고 있는 방향등의 변화에 따라 잘 적용되어 표현해주는걸 볼수 있다.

728x90
Posted by 정망스
,
728x90

Adaptive Probe Volumes 이하 줄여서 APV라 하겠다.
유니티에서 제공하는 새로운 Light Probe 시스템이다.

장점으로는
- 멀티플랫폼 지원.
- 사용 방법이 쉽다.

출처 : Unity Korea Youtube

특히 사용방법이 쉬워졌다라는 점은
이전 Light Probe Groups의 경우 이하 LPG는 개별 Probe들을 그림자 영역이라던지, 밝은 영역이라던지 여러 요소를 고려해서 수동으로 잘 배치해줘야 효과를 잘 볼수 있는 많은 작업량과 시간이 필요로 하는 힘든점이 있었다.

하지만 APV에선 볼륨 기반 시스템으로 Probe의 볼륨 영역만 잘 배치해주면 나머지는 유니티가 알아서 맡게끔 배치해주는것이다. 특히 지오메트리 정보를 기반으로 밀도가 필요한부분 덜한부분 이러한 정보를 바탕으로 알아서 Probe를 자동으로 배치해주기 때문에 최적화된 배치를 알아서 해준다는것이다.

그리고 기존 LPG는 연산이 CPU영역에서 이루어진 반면 APV에선 GPU영역에서 이루어지기 때문에 연산도 훨씬 빠르다는 장점이 있다.

출처 : Unity Korea Youtube

그리고 APV에선 Per Pixel Lighting을 지원한다.

기존의 LPG에선 Per Object Lighting으로써 라이팅이 오브젝트에 일괄적으로 균일하게 적용되는 방식이였다.
그래서 균일하게 적용되는 부분이 오히려 위 사진의 왼쪽 트럭처럼 왼쪽 문만 하얗고 본체는 그림자가 져 버리는것처럼 보이는게 어색한 부분이 있다.

하지만 APV에선 픽셀별로 라이팅이 계산되서 위 사진의 오른쪽 트럭처럼 자연스럽게 적용되는 부분이 확연하게 보인다.
물론 픽셀당 연산이 효과는 확실히 좋지만 픽셀마다 계산해야되는 부분이 부담이 될수 있기 때문에. 그보다 좀 더 부담을 줄이고 적용할수 있도록 버텍스 정점을 기준으로 계산될수 있게 Per Vertex 옵션도 있다.

아직까지는 이 APV 기능의 개발과 최적화가 계속 진행중이라는 점에서 현재 개발이 상당히 진행된 프로젝트에는 적용하기 쉽지는 않을거 같고, 신규 개발과 같은곳에서 한번 적용해볼법 한것 같다.

728x90
Posted by 정망스
,


맨 위로
홈으로 ▲위로 ▼아래로 ♥댓글쓰기 새로고침