일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- gameplay ability system
- listen server
- Multiplay
- attribute
- 언리얼 엔진
- nanite
- 유니티
- network object pooling
- gameplay effect
- Aegis
- map design
- photon fusion2
- CTF
- 게임 개발
- 게임개발
- 보안
- unity
- animation
- UI
- local prediction
- gas
- rpc
- stride
- os
- 언리얼엔진
- Replication
- gameplay tag
- Unreal Engine
- ability task
- MAC
- Today
- Total
Replicated
[Drag Down] 미끄러지는 길 (Physical Material + Surface type + Data Asset) 본문
[Drag Down] 미끄러지는 길 (Physical Material + Surface type + Data Asset)
라구넹 2025. 4. 17. 22:11모듈화를 위해 당연히 컴포넌트로 분리
* OnLand나 CurrentFloor.HitResult에서 현재 바닥 트레이스 정보를 주긴 하는데, Physical Material을 안들고 온다
* bReturnPhysicalMaterial 설정이 기본적으로 안되어 있음
Project Settings -> Physics 가서 Physical Surface 추가
#pragma once
#include "CoreMinimal.h"
#define CPROFILE_DDCAPSULE TEXT("DDCapsule")
#define CPROFILE_DDTRIGGER TEXT("DDTrigger")
#define CPROFILE_OVERLAPALL TEXT("OverlapAll")
#define CPROFILE_NOCOLLISION TEXT("NoCollision")
#define CCHANNEL_CSACTION ECC_GameTraceChannel1
#define SURFACE_DEFAULT SurfaceType_Default
#define SURFACE_ICE SurfaceType1
Surface Type은 Collision 타입이랑 같이 관리한다
* SurfaceType1 이런 건 엔진이 알아서 관리하는 값.. 정확히는 ini 파일에서 관리
Physical Material 만들고 Surface 설정
* Character는 CharacterMovementComponent 기반으로 움직여서 여기서 Friction 설정하는 것만으로는 부족함
메시에다 Physical Material 설정
// Fill out your copyright notice in the Description page of Project Settings.
#include "ActorComponent/DDSurfaceDetectionComponent.h"
#include "PhysicalMaterials/PhysicalMaterial.h"
#include "GameFramework/Character.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "DataAsset/DDGroundFrictionData.h"
#include "Physics/DDCollision.h"
UDDSurfaceDetectionComponent::UDDSurfaceDetectionComponent()
{
SetIsReplicatedByDefault(true);
static ConstructorHelpers::FObjectFinder<UDDGroundFrictionData> GroundFrictionDataRef(TEXT("/Script/DragDown.DDGroundFrictionData'/Game/Blueprint/DataAsset/DDDA_GroundFrictionData.DDDA_GroundFrictionData'"));
if (GroundFrictionDataRef.Succeeded())
{
GroundFrictionData = GroundFrictionDataRef.Object;
}
}
void UDDSurfaceDetectionComponent::BeginPlay()
{
Super::BeginPlay();
OwnerCharacter = Cast<ACharacter>(GetOwner());
if (OwnerCharacter == nullptr) return;
CharacterMovementComp = OwnerCharacter->GetCharacterMovement();
if (CharacterMovementComp == nullptr) return;
OwnerCharacter->OnCharacterMovementUpdated.AddDynamic(this, &UDDSurfaceDetectionComponent::OnMovementUpdated);
}
void UDDSurfaceDetectionComponent::OnMovementUpdated(float DeltaTime, FVector OldLocation, FVector OldVelocity)
{
if (CharacterMovementComp == nullptr || GroundFrictionData == nullptr) return;
FVector Start = OwnerCharacter->GetActorLocation();
FVector End = Start - FVector(0.f, 0.f, 200.f);
FHitResult Hit;
FCollisionQueryParams Params;
Params.AddIgnoredActor(OwnerCharacter);
Params.bReturnPhysicalMaterial = true; // CurrentFloor.HitResult is not support bReturnPhysicalMaterial
if (GetWorld()->LineTraceSingleByChannel(Hit, Start, End, ECC_Visibility, Params))
{
if (UPhysicalMaterial* PhysMat = Hit.PhysMaterial.Get())
{
EPhysicalSurface SurfaceType = UPhysicalMaterial::DetermineSurfaceType(PhysMat);
switch (SurfaceType)
{
case SURFACE_ICE:
SetMovementForFriction(SURFACE_ICE);
break;
default:
SetMovementForFriction(SURFACE_DEFAULT);
break;
}
}
}
}
void UDDSurfaceDetectionComponent::SetMovementForFriction(EPhysicalSurface NewSurface)
{
CharacterMovementComp->GroundFriction = GroundFrictionData->FrictionData[NewSurface].GroundFriction;
CharacterMovementComp->BrakingFrictionFactor = GroundFrictionData->FrictionData[NewSurface].BrakingFrictionFactor;
CharacterMovementComp->BrakingDecelerationWalking = GroundFrictionData->FrictionData[NewSurface].BrakingDecelerationWalking;
}
움직임에 업데이트가 있으면 발 밑 트레이스해서 피지컬 메테리얼 들고오고
GroundFriction, BrakingFrictionFactor, BrakingDecelerationWalking을 데이터 애셋에서 들고 온다
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Engine/DataAsset.h"
#include "Engine/EngineTypes.h"
#include "DDGroundFrictionData.generated.h"
USTRUCT(BlueprintType)
struct FFrictionEntry
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float GroundFriction = 8.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float BrakingFrictionFactor = 2.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float BrakingDecelerationWalking = 2000.0f;
};
/**
*
*/
UCLASS()
class DRAGDOWN_API UDDGroundFrictionData : public UDataAsset
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "FrictionData")
TMap<TEnumAsByte<EPhysicalSurface>, FFrictionEntry > FrictionData;
};
데이터 애셋은 EPhysicalSurface를 키로 하고(TMap에 넣기 위해 TEnumAsByte로 감쌈) FFrictionEntry를 밸류로 가지는 맵이다
블루프린트로 만들고 이렇게 에디터에서 바로바로 수정 가능하다
나중에 Surface 추가 시 쉽게 확장 가능하다
플레이어는 그냥 만들어놓으기만 하면 끝
자연스럽게 잘 미끄러지는 걸 확인 가능하다
데이터 기반 설계로 굉장히 유연하게 작동한다
'언리얼 엔진 > Drag Down (캡스톤 디자인)' 카테고리의 다른 글
[Drag Down] Action 인풋 처리 (0) | 2025.04.22 |
---|---|
[Drag Down] 앞으로 해야 하는 거 간단히 정리 (0) | 2025.04.20 |
** [Drag Down] Performance Enhancement of Network Object Pooling ** (0) | 2025.04.16 |
** [Drag Down] Network Object Pooling (Subsystem + Interface + GameMode + DataAsset) ** (0) | 2025.04.16 |
[Drag Down] 눈발사대 눈사람(주기적 발사 장애물) (0) | 2025.04.14 |