일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
Tags
- 게임개발
- Race condition
- MAC
- 게임 개발
- gameplay ability
- stride
- gas
- MLFQ
- dtft
- DSP
- ability task
- CTF
- 운영체제
- DP
- ret2libc
- AINCAA
- sampling theory
- frequency-domain spectrum analysis
- pdlc
- Rr
- dirty cow
- linear difference equation
- reverse gravity
- 메카님
- Security
- 언리얼 엔진
- 언리얼엔진
- 유니티
- 유스케이스
- Unreal Engine
Archives
- Today
- Total
다양한 기록
[ChronoSpace] 중력 반전 #2 / Box Trigger 본문
// Fill out your copyright notice in the Description page of Project Settings.
#include "GA/TA/CSTA_ReverseGravityBox.h"
#include "AbilitySystemComponent.h"
#include "Abilities/GameplayAbility.h"
#include "GameFramework/Character.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "Components/CapsuleComponent.h"
#include "AbilitySystemBlueprintLibrary.h"
#include "Components/BoxComponent.h"
#include "Physics/CSCollision.h"
#include "ChronoSpace.h"
ACSTA_ReverseGravityBox::ACSTA_ReverseGravityBox()
{
ReverseGravityTrigger = CreateDefaultSubobject<UBoxComponent>(TEXT("ReverseGravityTrigger"));
RootComponent = ReverseGravityTrigger;
ReverseGravityTrigger->SetBoxExtent(FVector(200.0f, 200.0f, 1000.0f));
ReverseGravityTrigger->SetRelativeLocation(FVector(0.0f, 0.0f, 0.0f));
ReverseGravityTrigger->SetCollisionProfileName(CPROFILE_CSTRIGGER);
ReverseGravityTrigger->OnComponentBeginOverlap.AddDynamic(this, &ACSTA_ReverseGravityBox::OnTriggerBeginOverlap);
ReverseGravityTrigger->OnComponentEndOverlap.AddDynamic(this, &ACSTA_ReverseGravityBox::OnTriggerEndOverlap);
}
void ACSTA_ReverseGravityBox::StartTargeting(UGameplayAbility* Ability)
{
Super::StartTargeting(Ability);
SourceActor = Ability->GetCurrentActorInfo()->AvatarActor.Get();
}
void ACSTA_ReverseGravityBox::ConfirmTargetingAndContinue()
{
//UE_LOG(LogCS, Log, TEXT("ConfirmTargetingAndContinue"));
if (SourceActor)
{
OnComplete.Broadcast();
}
}
void ACSTA_ReverseGravityBox::BeginPlay()
{
Super::BeginPlay();
if (ReverseGravityTrigger)
{
FVector BoxLocation = ReverseGravityTrigger->GetComponentLocation();
FVector BoxExtent = ReverseGravityTrigger->GetScaledBoxExtent(); // 스케일이 적용된 박스 크기
FQuat BoxRotation = ReverseGravityTrigger->GetComponentRotation().Quaternion();
DrawDebugBox(
GetWorld(),
BoxLocation,
BoxExtent,
BoxRotation,
FColor::Green,
false, // 지속 표시
DurtionTime, // -1은 시간 제한 없음
0, // 디버그 선 우선순위
2.0f // 선 두께
);
}
}
void ACSTA_ReverseGravityBox::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
for (auto Act = ActorsThatIsReveredGravity.CreateIterator(); Act; ++Act)
{
if (!IsValid(Act.Value())) continue;
ACharacter* RemainedCharacter = Cast<ACharacter>(Act.Value());
if (RemainedCharacter)
{
UCharacterMovementComponent* MovementComp = RemainedCharacter->GetCharacterMovement();
if (!MovementComp) continue;
if (MovementComp->GravityScale > 0) continue;
MovementComp->AddImpulse(FVector(0.0f, 0.0f, 0.1f));
MovementComp->GravityScale *= -1.0f;
}
ActorsThatIsReveredGravity.FindAndRemoveChecked(Act.Value()->GetFName());
}
Super::EndPlay(EndPlayReason);
}
void ACSTA_ReverseGravityBox::OnTriggerBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepHitResult)
{
ACharacter* DetectedCharacter = Cast<ACharacter>(OtherActor);
if (DetectedCharacter)
{
UCharacterMovementComponent* MovementComp = DetectedCharacter->GetCharacterMovement();
if (MovementComp)
{
if (MovementComp->GravityScale < 0)
{
return;
}
MovementComp->AddImpulse(FVector(0.0f, 0.0f, 0.1f));
MovementComp->GravityScale *= -1.0f;
ActorsThatIsReveredGravity.Emplace(OtherActor->GetFName(), OtherActor);
}
}
}
void ACSTA_ReverseGravityBox::OnTriggerEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
//UE_LOG(LogCS, Log, TEXT("OnTriggerEndOverlap called: %s"), *OtherActor->GetName());
ACharacter* DetectedCharacter = Cast<ACharacter>(OtherActor);
if (DetectedCharacter)
{
UCharacterMovementComponent* MovementComp = DetectedCharacter->GetCharacterMovement();
if (MovementComp)
{
if (MovementComp->GravityScale > 0)
{
return;
}
MovementComp->AddImpulse(FVector(0.0f, 0.0f, 0.1f));
MovementComp->GravityScale *= -1.0f;
ActorsThatIsReveredGravity.FindAndRemoveChecked(OtherActor->GetFName());
}
}
}
이전에 썼던 SweepMultiByChannel보다 좀 더 안정적으로 쓰기 위해 캐릭터의 중력 변수를 조절
캐릭터가 영역에 들어오면 중력 반전 /
영역에서 나가거나 중력 필드의 지속시간이 끝나면 원상 복구
중력 반전 시 AddImpulse 하는 이유는 중력이 반전되어도 지면에 붙어 있으면 반전의 영향을 안받고 붙어있어서
일단 힘을 Z축으로 한 번 줘야 함
void ACSTA_ReverseGravityBox::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
for (auto Act = ActorsThatIsReveredGravity.CreateIterator(); Act; ++Act)
{
if (!IsValid(Act.Value())) continue;
ACharacter* RemainedCharacter = Cast<ACharacter>(Act.Value());
if (RemainedCharacter)
{
UCharacterMovementComponent* MovementComp = RemainedCharacter->GetCharacterMovement();
if (!MovementComp) continue;
if (MovementComp->GravityScale > 0) continue;
MovementComp->AddImpulse(FVector(0.0f, 0.0f, 0.1f));
MovementComp->GravityScale *= -1.0f;
}
ActorsThatIsReveredGravity.FindAndRemoveChecked(Act.Value()->GetFName());
}
Super::EndPlay(EndPlayReason);
}
원상 복구를 위해 TMap에 중력 반전의 영향을 받았던 액터들을 저장해두고
EndPlay에서 원상 복구 시킴
'언리얼 엔진 > ChronoSpace' 카테고리의 다른 글
[ChronoSpace] 중력 반전 #1 / SweepMultiByChannel (0) | 2025.01.16 |
---|---|
[ChronoSpace] 트레이스 세팅, 움직임 동기화 (0) | 2025.01.15 |
[ChronoSpace] 파일 include 문제 (PublicIncludePaths) (0) | 2025.01.15 |
[ChronoSpace] 개요 / Session Create, Session Join + 스팀 친구 초대 (0) | 2025.01.14 |