오늘의 코드카타
오늘의 공부
팀 프로젝트 진행 내용
1. 발이 공중에 뜨는 현상 개선
- 아래와 같이 지면이 고르지 않은 경우, 공중에 발이 뜨는 현상을 확인했다.
| 계단 | 고르지 않은 잔해 |
|---|
 |  |
- 지면이 고르지 않은 경우를 해결하기 위해 Foot Placement 노드를 사용하여 발이 바닥에 고정되게끔 했다.
- Foot Placement 노드를 사용하여 발이 땅에 고정(Planted)되거나 고정 해제(Unplanted)되는 조건을 세밀하게 제어하는 데 중점을 둔다. Line Trace를 통해 바닥을 검사하는 과정은 기존의 IK Rig와 동일하다.

- Plant Settings의 값과 Interpolation Settings 값을 통해 캐릭터의 상태에 따라 발의 움직임 민감도와 전환 속도를 다르게 적용하여 현실감을 높일 수 있다.
- Plant Settings는 발이 지면에 IK 고정될지 혹은 애니메이션에 의해 움직일지를 결정하는 상태 전환 조건이다.
| 종류 | Plant Settings Default (이동 중) | Plant Settings Stops (정지 중) |
|---|
| 사진 |  |  |
| Speed Threshold | 60cm/s 이상이면 이동 중 프로파일 사용 | 20cm/s 이하면 멈춤 프로파일로 전환 |
| Unplant Radius | 발의 애니메이션이 20cm만 벗어나도 IK 해제 | 발의 애니메이션을 40cm까지 허용하여 IK 고정을 오래 유지 |
| Replant Radius Ratio | 고정 해제 후, 발이 지면에 가까워지면 빠르게 IK를 재시도 | 고정 해제 후, 재고정 시도를 늦추거나 덜 민감하게 하여 Idle 포즈로 부드럽게 전환 |
- Interpolation Settings 값을 통해 발의 IK 고정 상태가 해제되거나 재고정될 때, 애니메이션 포즈와 IK 포즈 사이를 얼마나 빠르고 부드럽게 전환할지 결정함
| 종류 | Interpolation Settings Default (이동 중) | Interpolation Settings Stops (정지 중) |
|---|
| 사진 |  |  |
| Unplant Linear Stiffness | 이동 중에는 발의 전환을 부드럽고 느리게 하여, 땅에 닿는 순간의 충격이나 떨림을 줄임 | 정지할 때는 발이 최종 Idle 포즈에 빠르고 단단하게 안착하도록 강도를 높여, 미끄러짐을 최소화함 |
| 계단 | 고르지 않은 잔해 |
|---|
 |  |
2. 파쿠르 동작 동기화 업데이트
- 기존의 파쿠르 정보를 가지고 있는 구조체를 동기화되게 설정했다.
- 파쿠르 동작을 서버에서만 실행시켜주게끔 구조를 바꿨다.
- 플레이어에서 파쿠르 동작을 요청할 때, 파쿠르가 실행 중인지 확인하는 변수도 동기화되게 설정했다.
// AO_TraversalComponent.h
UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
class AO_API UAO_TraversalComponent : public UActorComponent
{
...
UPROPERTY(VisibleAnywhere, Replicated, Category = "Traversal")
FTraversalCheckResult TraversalResult;
...
UFUNCTION(Server, Reliable)
void ServerRPC_PlayTraversal(const FTraversalCheckResult InTraversalResult);
UFUNCTION(NetMulticast, Reliable)
void MulticastRPC_PlayTraversal(const FTraversalCheckResult InTraversalResult);
...
UPROPERTY(Replicated)
bool bDoingTraversal = false;
}
- 서버에서는 NetMulticastRPC를 통해 모든 클라이언트에서 보이게 했다.
- 클라에서는 ServerRPC를 통해 서버에서만 파쿠르 동작을 실행시키게 했다.
- 이외에도, 기존에는
TryTraversal()을 실행하면 컴포넌트의 TraversalResult를 수정했지만, 임시 변수를 설정해서 마지막에 정상적으로 실행시킬 수 있을 때만 컴포넌트의 TraversalResult에 할당하는 구조로 변경해서 동기화를 최소로 줄였다.
// AO_TraversalComponent.cpp
bool UAO_TraversalComponent::TryTraversal()
{
...
// PerformTraversalAnimation();
TraversalResult = TraversalCheckResult;
if (Owner->HasAuthority())
{
MulticastRPC_PlayTraversal(TraversalResult);
}
else
{
ServerRPC_PlayTraversal(TraversalResult);
}
return true;
}
void UAO_TraversalComponent::MulticastRPC_PlayTraversal_Implementation(const FTraversalCheckResult InTraversalResult)
{
TraversalResult = InTraversalResult;
PerformTraversalAnimation();
}
void UAO_TraversalComponent::ServerRPC_PlayTraversal_Implementation(const FTraversalCheckResult InTraversalResult)
{
TraversalResult = InTraversalResult;
MulticastRPC_PlayTraversal(TraversalResult);
}
오늘의 CS
프로세스 간의 통신 (IPC: Inter-Process Communication)
1. 직접 통신
- 파이프 : 단방향 통신 방식이며, 부모 자식 프로세스 관계에서 많이 사용됨.
- 메시지 큐 : 메시지들을 저장하는 큐를 사용하여 통신하는 방식.
- 프로세스는 큐에 메시지를 보내거나 받기 댸문에 비동기적으로 처리할 수 있음.
2. 간접 통신
- 공유 메모리 : 통신하려는 프로세스들이 커널을 통해 특정 메모리 영역을 공유하도록 설정
- 데이터를 한 번 커널에 복사하거나 시스템 호출을 거칠 필요 없이 직접 접근하여 읽고 쓰기 때문에 다른 IPC 방법에 비해 가장 빠름.
- 다만, 접근 순서와 동기화를 프로세스들이 직접 관리해야 함.
- 소켓 : 네트워크를 통해 통신하는 방법.
- 로컬 시스템 내의 프로세스 간 통신이나 네트워크 상의 다른 컴퓨터에 있는 프로세스와 통신할 때 사용됨
스레드 간의 통신 (Inter-Thread Communication)
- 스레드는 같은 프로세스 내의 코드, 데이터, 힙 영역을 공유하기 때문에, 공유 데이터에 대한 동기화만 진행함
- 직접 공유 및 동기화
- 공유 메모리 방식과 유사함. 단순히 공유 변수를 통해 데이터를 주고 받음
- 스레드는 전역 변수나 힙에 할당된 데이터에 직접 접근하여 읽고 씀으로 통신함