Categories
미분류

Reallusion 라이센스 관리


포맷 전 필수!

홈페이지 접속 후 Resistration 항목에서 삭제

https://www.reallusion.com/

1 Activated Seats에서 2 컴퓨터 이름 확인 후 3 디엑티브 나우를 클릭!

Categories
Unreal

Foliage Grass Flicker 해소

Categories
Blender

Blender 그림자 렌더링

표시부에 그림자 추가하는 방법

  1. 평면 추가

2. 디테일 패널
Shadow Catcher 표시

짠!

Categories
Blender

Blender 파일 열리지 않을 때 대처법

블렌더 파일이 오픈되지 않는 경우는 2가지

  1. **.Blender1 파일 생성 후 열리지 않음
  2. .Blender 파일이 클릭만 되고 실행 안되는 경움

대처법

1. Blender 실행
2. 폴더에서 파일을 드래그하여 블렌더로 이동 후 오픈

3. Save as 기능으로 다시 저장

Categories
Unreal

언리얼 애셋 이동 방법

애셋 이동 방법

  1. Mesh / Material
    – Content Browser에서 Migrate

2. Migrate를 할 수 없는 경우나 많은 양의 데이터를 옮길 경우
– Create Level Instance 사용하여 레벨을 만든 후 Migrate

저장 후 Migrate 실행

이동한 파일에서 Level Instance 배치 후 Level Break로 해제

Categories
미분류

UE_GenLock 설정

UE Docs 참고
https://dev.epicgames.com/documentation/ko-kr/unreal-engine/timecode-and-genlock-in-unreal-engine#%EC%96%B8%EB%A6%AC%EC%96%BC%EC%97%90%EB%94%94%ED%84%B0%EC%97%90%EC%84%9C%ED%83%80%EC%9E%84%EC%BD%94%EB%93%9C%EC%8B%9C%EA%B0%81%ED%99%94

GenLock(Generator Lock) – 동기 신호 발생기(Sync Generator)에 고정(Lock)시킨다는 뜻
언리얼 엔진의 타임코드를 작업 중인 비디오 피드의 타임코드와 일치시키는 작업

  1. 명령어
    stat timecode
    현재 타임코드 확인

2. BP_BM_Timecode_Provider와
BP_BM_TimeStep 생성 및 각각 Detail 설정

3. 프로젝트 설정 입력
1) TimeCode
2) TimeStep
입력란에 위에서 만든 BP 선택

4. 프로젝트 재시작 (권장)

5. stat time code
확인

Categories
AE

[익스프레션] 한글 타이핑 자막 효과 개선

한글 타이핑 자막 효과의 시작 시간을 정할 수 있도록 개선

let cCho = ["ㄱ", "ㄲ", "ㄴ", "ㄷ", "ㄸ", "ㄹ", "ㅁ", "ㅂ", "ㅃ", "ㅅ", "ㅆ", "ㅇ", "ㅈ", "ㅉ", "ㅊ", "ㅋ", "ㅌ", "ㅍ", "ㅎ"],
cJung = ["ㅏ", "ㅐ", "ㅑ", "ㅒ", "ㅓ", "ㅔ", "ㅕ", "ㅖ", "ㅗ", "ㅘ", "ㅙ", "ㅚ", "ㅛ", "ㅜ", "ㅝ", "ㅞ", "ㅟ", "ㅠ", "ㅡ", "ㅢ", "ㅣ"],
cJong = ["", "ㄱ", "ㄲ", "ㄳ", "ㄴ", "ㄵ", "ㄶ", "ㄷ", "ㄹ", "ㄺ", "ㄻ", "ㄼ", "ㄽ", "ㄾ", "ㄿ", "ㅀ", "ㅁ", "ㅂ", "ㅄ", "ㅅ", "ㅆ", "ㅇ", "ㅈ", "ㅊ", "ㅋ", "ㅌ", "ㅍ", "ㅎ"]

let toStringFromCharCode = (cho, jung, jong) =>
String.fromCharCode(44032 + cho * 588 + jung * 28 + (jong || 0));

let seperateChar = (char) => {
let cCode = char.charCodeAt() - 0xac00;
let jong = cCode % 28;
let jung = ((cCode - jong) / 28) % 21;
let cho = ((cCode - jong) / 28 - jung) / 21;
return []
.concat(cCho[cho])
.concat(toStringFromCharCode(cho, jung))
.concat(cJong[jong] !== "" ? toStringFromCharCode(cho, jung, jong) : []);
};

let toKorChars = (char) => {
let cCode = char.charCodeAt();
return [].concat(
(!cCode && []) ||
(cCode === 32 && " ") ||
((cCode < 0xac00 || cCode > 0xd7a3) && char) ||
seperateChar(char)
);
};

let typing = (str) =>
str
.split("")
.map((char) => toKorChars(char))
.reduce(
(pre, cur) =>
pre.concat(
cur.map((v) => (pre.length !== 0 ? pre[pre.length - 1] : "") + v)
),
[""]
);

let p = thisLayer.effect("Speed")("Slider");
let strList = typing(thisLayer.text.sourceText);

if (time > 2) {
let adjustedTime = time - 2;
let strListIndex = Math.round(adjustedTime*p);
[strList[strList.length > strListIndex ? strListIndex : strList.length-1]]
} else {
[]
}

//------------초성, 중성 종성 글자 수 세기--------------
/*let countCharComponents = (str) => {
return str.split("").reduce((count, char) => {
let components = toKorChars(char);
return count + components.length;
}, 0);
};

[countCharComponents(thisLayer.text.sourceText)]*/
//------------초성, 중성 종성 글자 수 세기--------------
Categories
AE

[익스프레션] 포인트텍스트 기준 문장 나누기

타입 1

const layerNameNum = parseInt(thisLayer.name.replace(/[^0-9]/g, ""));
const totalText = thisComp.layer("Text_" + layerNameNum).text.sourceText;
const pointTextArray = thisComp.layer("PointText_" + layerNameNum).text.sourceText.split("$$");

function splitTextByWords(text, words) {
let currentIndex = 0;
const result = [];

for (const word of words) {
const index = text.indexOf(word, currentIndex);
if (index !== -1) {
const preWord = text.substring(currentIndex, index).trim();
if (preWord !== '') result.push(preWord);
result.push(word);
currentIndex = index + word.length;
}
}

// 마지막 단어 이후의 텍스트를 결과에 추가
if (currentIndex < text.length) {
const lastText = text.substring(currentIndex).trim();
if (lastText !== '') result.push(lastText);
}

return result;
}

const thisLayerRenderText = splitTextByWords(totalText, pointTextArray);


[thisLayerRenderText]

타입 2

const layerNameNum = parseInt(thisLayer.name.replace(/[^0-9]/g, ""));
const totalText = thisComp.layer("Text_" + layerNameNum).text.sourceText;
const pointTextArray = thisComp.layer("PointText_" + layerNameNum).text.sourceText.split("$$");

// splitTextByWords 함수 정의
function splitTextByWords(text, words) {
let result = [];
let currentIndex = 0;

for (let i = 0; i < words.length; i++) {
const word = words[i];
const index = text.indexOf(word, currentIndex);

if (index !== -1) {
// 단어 이전의 텍스트를 결과에 추가
if (index > currentIndex) {
result.push(text.substring(currentIndex, index).trim());
}
result.push(word);
currentIndex = index + word.length;
}
// 해당 단어가 발견되지 않았을 때는 다음 단어를 찾기 위해 현재 인덱스를 유지
}

// 마지막 단어 이후의 텍스트를 결과에 추가
if (currentIndex < text.length) {
result.push(text.substring(currentIndex).trim());
}

// 결과 배열에서 빈 문자열을 필터링하여 반환
return result.filter(word => word !== "");
}

// 결과 계산
const thisLayerRenderText = splitTextByWords(totalText, pointTextArray);
[thisLayerRenderText]

포지션

const layerNameNum = parseInt(thisLayer.name.replace(/[^0-9]/g, ""))-1;
const totalText = thisComp.layer("Text_1").text.sourceText.toString();
const thisLayerText = thisLayer.text.sourceText.toString();

baseTextLayer = thisComp.layer("SecondLine_Render_Text_" + layerNameNum);
baseTextXPosition = baseTextLayer.transform.position[0];
baseTextWidth = baseTextLayer.sourceRectAtTime().width;

spaceBlankWidth = thisComp.layer("Control_Text_1").effect("Space_Blank_Width")("Slider");
spaceDefaultWidth = thisComp.layer("Control_Text_1").effect("Space_Default_Width")("Slider");

const checkSpaceBefore = (totalCheckText, word) => {
const thisTextindex = totalCheckText.indexOf(word);
return thisTextindex > 0 && totalCheckText[thisTextindex - 1] === ' ';
};

const spaceBefore = checkSpaceBefore(totalText, thisLayerText);

if (spaceBefore === true) {
x = baseTextXPosition + baseTextWidth + spaceBlankWidth;
} else {
x = baseTextXPosition + baseTextWidth + spaceDefaultWidth;
}

[x, baseTextLayer.transform.position[1]]
Categories
미분류

Mixamo Amimation 적용 Body + Face

  1. Mixamo에서 원하는 Animation 다운로드

2. Mixamo Converter로 UE에서 사용할 수 있게 변환

3. UE에서 파일 Import

4. MetaHuman BP –> Root —> Body에서 Animation 적용

Disable Post Process Blueprint 체크

5. 얼굴 Animation Import

Face Anim 파일을 Montage 파일로 변환

5. MetaHuman BP에서 Play_Montage 추가

-끝-

Categories
Unreal

[Unreal] Chroma & Crop

Unreal에서 Chroma Rectangle Area를 설정하고 Mask Area를 2개 설정한다. 또한 영상의 Crop 범위를 설정한다.

  1. M_VideoPlateDefault 머터리얼 수정

2. UVCropping 머터리얼 수정

3. M_SinglePassChromakeyer 머터리얼 수정

4. Radial_SQ 머터리얼 수정 (GenerateRoundRect로 대제 가능)