UE5

언리얼 Monster AI 구현(4): 통신

개발꼬순내 ㅣ 2025. 4. 22. 18:48

	UFUNCTION(Server, Reliable)
	virtual void RPCIsHit(bool value,AActor* DamageCauser);

Client -> Server로 보내려면 UFUNCTION(Server, Reliable(or Unreliable))을 사용해야 한다. 이렇게 하면 해당함수는 Server에서 실행되게 된다.

 

그다음 원하는 데이터를 다시 Client로 뿌려줘야 하는데 Replicate를 사용해 변경된값을 자동으로 뿌리거나 Multicast를 통해서 수동으로 뿌려줄 수 있다. Replicate 사용법이 미숙하여 이번 프로젝트에서는 Multicast를 사용하였다.

 

void ANormalMonster::RPCIsHit_Implementation(bool value, AActor* DamageCauser)
{
	FVector HitLocation = GetActorLocation();
	FRotator HitRotation = DamageCauser->GetActorRotation();
	MulticastIsHit(value, HitLocation, HitRotation);
}

RPC구현부를 보면 Multicast를 사용하고 있다. 그래야만 정상적으로 클라이언트들에게 똑같은 정보를 뿌려줄 수 있다.

 

UFUNCTION(NetMulticast, Reliable)
	virtual void MulticastIsHit(bool value, FVector HitLocation, FRotator HitRotation);

Multicast는 위와 같은 UFUNCTION을 사용한다.

 

아무래도 Multicast는 뿌려주는 함수이다보니 실질적인 구현내용자체를 여기다 적는 것이 편했다.

void ANormalMonster::MulticastIsHit_Implementation(bool value, FVector HitLocation, FRotator HitRotation)
{
	UGrux_AnimInstance* AnimInstance = Cast<UGrux_AnimInstance>(GetMesh()->GetAnimInstance());
	if (AnimInstance)
	{
		AnimInstance->UpdateHit(value);
		if (value == true)
		{
			UGameplayStatics::SpawnDecalAtLocation(GetWorld(), DecalMaterial, FVector(250, 300, 200),
			                                       HitLocation - FVector(0.0f, 0.0f, 320.0f),
			                                       HitRotation,
			                                       5.0f);
		}
	}
}

 

이런식으로 UpdateHit자체를 서버에서 실행하여 뿌려주면 각각의 Client들은 해당 bool값을 받고 자체적으로 애니메이션을 출력하고 SpanwDecal 같은경우에만 서버에서 만들어 뿌려주게 된다.

 

여기서 주의해야할 것중 하나가 .h에서 void RPCIsHit() 를 선언했다고 해서 .cpp에다 void ANormalMonster::RPCIsHit 로 선언을 하게되면 .cpp파일 인식을 못한다. 항상 뒤에 _Implementation(구현)을 붙여줘야 인식을 한다.

 

그리고 만약 Server, Multicast를 상속받았다면

virtual void MulticastIsHit_Implementation(bool value, FVector HitLocation, FRotator HitRotation) override;

이렇게 .h파일에도 Implementation을 붙여줘야 정상적으로 인식한다.

 

AnimInstance의 Notify역시 RPC를 해줘야 해당 애니메이션이 끝났다고 모든 클라이언트들이 인식을 하게 된다

void UGrux_AnimInstance::AnimNotify_EndHit()
{
	IsHit = false;
	AActor* OwnerActor = GetOwningActor();
	if (OwnerActor)
	{
		ANormalMonster* Monster = Cast<ANormalMonster>(OwnerActor);
		if (Monster)
		{
			Monster->RPCIsHit(IsHit, OwnerActor);
		}
	}
}

 

'UE5' 카테고리의 다른 글

NavMesh Invoker  (0) 2025.04.23
언리얼 Monster AI 구현(3): Animation  (0) 2025.04.22
언리얼 Monster AI구현(2): Behavior Tree  (0) 2025.04.15
언리얼 Monster AI 구현(1): 전투  (0) 2025.04.15
C++ Behavior Tree  (0) 2025.04.08