다양한 기록

[ChronoSpace] 밀리는 Character 본문

언리얼 엔진/ChronoSpace

[ChronoSpace] 밀리는 Character

라구넹 2025. 1. 25. 17:00

Character Movement Component의 Gravity Scale을 이용하기 때문에, 각종 물체를 Character로 하기로 기획하며 정했다

그런데 문제는, 이러면 Mesh의 Simulate Physics 기능을 이용할 수 없다

Character Movement Component가 움직임을 덮어써버리기 때문이다

 

그렇기에, Character Movement Component 자체의 AddForce를 이용하기로 했다

내부적으로 Character Movement Component에 설정된 Mass를 계산해서 알아서 물리 적용을 해준다

CharacterMovementComponent에 모든 물리적 이동을 맡겨야 한다

(안그러면 설정 충돌 때문에 제대로 이동이 안됨)

 

CharacterMovementComponent에는 질량이 존재하고,

AddForce, AddImpulse가 존재한다

또한, 캐릭터에 LaunchCharacter라는게 존재한다

 

LaunchCharacter는 근데 속도(Velocity)를 설정해주는 거라 Mass가 적용되지 않는다

또한, 계속 밀어서 연속적인 힘을 줄 것이기에 AddForce를 선택한다

 

단, 이벤트 발생을 위해 Static Mesh에서 Collision Preset 설정은 필요하다

CSCapsule 선택

 

일단 캡슐 컴포넌트로 트리거 만들어주고,콜리전 프로필을 CSTrigger로 설정한다

그리고 오버랩 델리게이트 설정을 해준다

void ACSCharacterPlayer::OnTriggerBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepHitResult)
{
	if (nullptr != Cast<ACSCharacterPlayer>(OtherActor)) return;

	ACharacter* OverlappedCharacter = Cast<ACharacter>(OtherActor);

	if (OverlappedCharacter)
	{
		CharsInPushing.Emplace(OverlappedCharacter->GetFName(), OverlappedCharacter);

		UE_LOG(LogCS, Log, TEXT("OnTriggerBeginOverlap : %s"), *OtherActor->GetName());
	}
}

void ACSCharacterPlayer::OnTriggerEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
	if (nullptr != Cast<ACSCharacterPlayer>(OtherActor)) return;

	ACharacter* OverlappedCharacter = Cast<ACharacter>(OtherActor);

	if (OverlappedCharacter)
	{
		CharsInPushing.FindAndRemoveChecked(OverlappedCharacter->GetFName());
	}
}

맵으로 현재 밀고 있는 캐릭터를 관리하고

 

void ACSCharacterPlayer::Tick(float DeltaSeconds)
{
	Super::Tick(DeltaSeconds);

	if ( GetCharacterMovement()->Velocity.IsNearlyZero() )
	{
		return;
	}

	FVector ForwardDirection = GetMesh()->GetComponentRotation().Vector();
	FVector Power = FVector(10000.0f, 10000.0f, 0.0f);
	Power.X *= -ForwardDirection.Y;
	Power.Y *= ForwardDirection.X;

	for (auto Char = CharsInPushing.CreateIterator(); Char; ++Char)
	{
		if ( IsValid(Char.Value()) )
		{
			Char.Value()->GetCharacterMovement()->AddImpulse(Power);
		}
	}
}

Tick에서 캐릭터가 가만히 있는게 아닌 이상, 캐릭터가 미는 방향으로 밀도록 설정한다

 

 

캐릭터가 밀리는 걸 확인 가능하다