UE - 라이라 Cosmetic 분석-1
UnrealEngine, Lyra
이번 팀프로젝트에선 모듈러 캐릭터를 이용할 예정이기에 라이라 코스메틱 부분을 분석해 봤다.
Cometic 관련 파일
라이라에서 사용하는 코스메틱 파일들
LyraCharacterPartTypes
LyraControllerComponent_CharacterParts
LyraCosmeticAnimationTypes
LyraCosmeticCheats
LyraCosmeticDeveloperSettings
LyraPawnComponent_CharacterParts
컴포넌트로 된 클래스들
LyraPawnComponent_CharacterParts
의 파생 블프는 B_MannequinnPawnCosmetics
1가지.
LyraControllerComponent_CharacterParts
파생 블프 B_CharacterSelection
, B_PickRandomCharacter
2가지.
이 컨트롤러쪽은 플레이어 컨트롤러에 부착되어 사용되는 것을 저번에 확인했다.
때문에 액터에 붙어서 캐릭터 파츠를 부착하는 기능을 담당하는 것은 LyraPawnComponent_CharacterParts
로 예상한다.
LyraPawnComponent_CharacterParts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
UCLASS(meta=(BlueprintSpawnableComponent))
class ULyraPawnComponent_CharacterParts : public UPawnComponent
{
GENERATED_BODY()
public:
ULyraPawnComponent_CharacterParts(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
//~UActorComponent interface
virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
virtual void OnRegister() override;
//~End of UActorComponent interface
// Adds a character part to the actor that owns this customization component, should be called on the authority only UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category=Cosmetics)
FLyraCharacterPartHandle AddCharacterPart(const FLyraCharacterPart& NewPart);
// Removes a previously added character part from the actor that owns this customization component, should be called on the authority only
UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category=Cosmetics)
void RemoveCharacterPart(FLyraCharacterPartHandle Handle);
// Removes all added character parts, should be called on the authority only
UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category=Cosmetics)
void RemoveAllCharacterParts();
// Gets the list of all spawned character parts from this component
UFUNCTION(BlueprintCallable, BlueprintPure=false, BlueprintCosmetic, Category=Cosmetics)
TArray<AActor*> GetCharacterPartActors() const;
// If the parent actor is derived from ACharacter, returns the Mesh component, otherwise nullptr
USkeletalMeshComponent* GetParentMeshComponent() const;
// Returns the scene component to attach the spawned actors to
// If the parent actor is derived from ACharacter, we'll use the Mesh component, otherwise the root component USceneComponent* GetSceneComponentToAttachTo() const;
// Returns the set of combined gameplay tags from attached character parts, optionally filtered to only tags that start with the specified root
UFUNCTION(BlueprintCallable, BlueprintPure=false, BlueprintCosmetic, Category=Cosmetics)
FGameplayTagContainer GetCombinedTags(FGameplayTag RequiredPrefix) const;
void BroadcastChanged();
public:
// Delegate that will be called when the list of spawned character parts has changed
UPROPERTY(BlueprintAssignable, Category=Cosmetics, BlueprintCallable)
FLyraSpawnedCharacterPartsChanged OnCharacterPartsChanged;
private:
// List of character parts
UPROPERTY(Replicated, Transient)
FLyraCharacterPartList CharacterPartList;
// Rules for how to pick a body style mesh for animation to play on, based on character part cosmetics tags
UPROPERTY(EditAnywhere, Category=Cosmetics)
FLyraAnimBodyStyleSelectionSet BodyMeshes;
};
이 폰 컴포넌트가 캐릭터에 캐릭터 파츠를 붙일 수 있는 기능을 제공하는 컴포넌트라고 생각한다.
캐릭터 파츠를 추가하는 함수
1
2
3
// Adds a character part to the actor that owns this customization component, should be called on the authority only
UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category=Cosmetics)
FLyraCharacterPartHandle AddCharacterPart(const FLyraCharacterPart& NewPart);
이게 캐릭터 파츠를 추가하는 함수다.
이건 서버에서만 호출이 가능하다고 한다.
저기서 반환하는 핸들이 캐릭터 파츠를 참조하는 핸들로 보인다.
1
2
3
4
FLyraCharacterPartHandle ULyraPawnComponent_CharacterParts::AddCharacterPart(const FLyraCharacterPart& NewPart)
{
return CharacterPartList.AddEntry(NewPart);
}
함수 내부는 이렇게 생겼다.
결국 캐릭터 파츠를 CharacterPartList
에 추가하는 작업 뿐. 결국 CharacterPartList
가 메인이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// A handle created by adding a character part entry, can be used to remove it later
USTRUCT(BlueprintType)
struct FLyraCharacterPartHandle
{
GENERATED_BODY()
void Reset()
{
PartHandle = INDEX_NONE;
}
bool IsValid() const
{
return PartHandle != INDEX_NONE;
}
private:
UPROPERTY()
int32 PartHandle = INDEX_NONE;
friend FLyraCharacterPartList;
};
핸들의 내부 구조는 이렇다.
캐릭터 파츠를 관리하는 메인
1
2
UPROPERTY(Replicated, Transient)
FLyraCharacterPartList CharacterPartList;
private
맴버 변수 중 하나다.
리플랙션으로 사용한 Replicated
는 네트워크 복제 기능을 수행한다. 변수가 서버 -> 클라이언트로 동기화 되는 기능을 제공한다.
Transiendt
는 휘발성 데이터라고 한다. 휘발성 데이터는 런타임에서만 유효하고 게임이 종료되면 사라지는 데이터라고 한다.
내일은 CharacterPartList
분석 내용을 정리해보겠다.