다양한 기록

[ChronoSpace] Gravity Core / Gravity Direction 조정을 통한 Custom Gravity 본문

언리얼 엔진/ChronoSpace

[ChronoSpace] Gravity Core / Gravity Direction 조정을 통한 Custom Gravity

라구넹 2025. 1. 26. 23:30

https://www.youtube.com/watch?v=CZK7QplEbJs

위 영상을 보고 만들긴 했는데, 위 영상은 Player한테 Gravity Direction의 조정을 맡긴다

Player에 책임이 과도해지기도 하고 마음에 안드는 부분들이 좀 있어서

분리하여 역할을 GravityCore에 맡겼다

 

분리하는 것으로 모든 ACharacter를 상속하는 클래스가 이 영향을 받을 수 있게 된다

 

// Fill out your copyright notice in the Description page of Project Settings.


#include "Actor/CSGravityCore.h"
#include "GameFramework/Character.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "ChronoSpace.h"

ACSGravityCore::ACSGravityCore()
{
	PrimaryActorTick.bCanEverTick = true;

	OnActorBeginOverlap.AddDynamic(this, &ACSGravityCore::OnActorBeginOverlapCallback);
	OnActorEndOverlap.AddDynamic(this, &ACSGravityCore::OnActorEndOverlapCallback);
}

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

	if ( TargetCharacters.Num() == 0 ) return;

	for (auto Character = TargetCharacters.CreateIterator(); Character; ++Character)
	{
		FVector NewDirection = GetGravityDirection(Character.Value());
		Character.Value()->GetCharacterMovement()->SetGravityDirection(NewDirection);
	}
}

FVector ACSGravityCore::GetGravityDirection(ACharacter* Character)
{
	FVector SelfLocation = GetActorLocation();
	FVector TargetLocation = Character->GetActorLocation();

	return (SelfLocation - TargetLocation).GetSafeNormal();
}

void ACSGravityCore::OnActorBeginOverlapCallback(AActor* OverlappedActor, AActor* OtherActor)
{
	if ( ACharacter* Character = Cast<ACharacter>(OtherActor) )
	{
		TargetCharacters.Emplace(Character->GetFName(), Character);
	}
}

void ACSGravityCore::OnActorEndOverlapCallback(AActor* OverlappedActor, AActor* OtherActor)
{
	if (ACharacter* Character = Cast<ACharacter>(OtherActor))
	{
		Character->GetCharacterMovement()->SetGravityDirection(FVector(0.0f, 0.0f, -1.0f));
		TargetCharacters.Remove(Character->GetFName());
	}
}

상위 클래스인 CSGravityCore에서 중력 조절을 맡는다

 

// Fill out your copyright notice in the Description page of Project Settings.


#include "Actor/CSGravityCoreSphere.h"
#include "Components/SphereComponent.h"
#include "Components/StaticMeshComponent.h"
#include "Physics/CSCollision.h"


ACSGravityCoreSphere::ACSGravityCoreSphere()
{
	// GravitySphereTrigger
	SphereTrigger = CreateDefaultSubobject<USphereComponent>(TEXT("GravitySphereTrigger"));
	SphereTrigger->SetSphereRadius(GravityInfluenceRange, true);
	SphereTrigger->SetRelativeLocation(FVector(0.0f, 0.0f, 0.0f));
	RootComponent = SphereTrigger;

	// Static Mesh
	StaticMeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMesh"));
	StaticMeshComp->SetRelativeLocation(FVector(0.0f, 0.0f, 0.0f));
	StaticMeshComp->SetupAttachment(SphereTrigger);
	StaticMeshComp->SetCollisionProfileName(CPROFILE_CSCAPSULE);

	static ConstructorHelpers::FObjectFinder<UStaticMesh> StaticMeshRef(TEXT("/Script/Engine.StaticMesh'/Game/Mesh/StaticMesh/BlockSphere.BlockSphere'"));
	if (StaticMeshRef.Object)
	{
		StaticMeshComp->SetStaticMesh(StaticMeshRef.Object);
	}

	float MeshRadius = 50.0f;
	float MeshScale = (GravityInfluenceRange / MeshRadius) * 0.75f;
	StaticMeshComp->SetRelativeScale3D(FVector(MeshScale, MeshScale, MeshScale));

}

하위 클래스인 CSGravityCoreSphere에서 스태틱 메시와 SphereComponent 설정을 한다

상속받아 블루프린트로 만들고 메테리얼 설정 및 중력 영역 설정

 

 

 

 

https://lagooneng.tistory.com/358

 

[ChronoSpace] SetGravityDirection 동기화 문제 (Pitch 동기화)

서버 말고는 GravityDirection이 동기화가 안되어 있었다CharacterMovementComponent는 위치나 가속도 등의 핵심 정보만 동기화한다고 함  방법1. 다시 캐릭터로 중력 세팅 책임 옮기기이건 그냥 코드가 마

lagooneng.tistory.com

멀티플레이용 변경 사항