第一次提交
This commit is contained in:
@@ -0,0 +1,249 @@
|
||||
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
|
||||
|
||||
#include "Collision/GCS_TraceStructLibrary.h"
|
||||
|
||||
#include "GCS_LogChannels.h"
|
||||
#include "Components/BoxComponent.h"
|
||||
#include "Components/CapsuleComponent.h"
|
||||
#include "Components/SphereComponent.h"
|
||||
#include "TargetingSystem/TargetingPreset.h"
|
||||
|
||||
|
||||
bool FGCS_CollisionShape::InitializeShape(const UPrimitiveComponent* SourceComponent)
|
||||
{
|
||||
GCS_OWNED_CLOG(SourceComponent, Warning, "Should never use this shape:%s", *FGCS_CollisionShape::StaticStruct()->GetName());
|
||||
FDebug::DumpStackTraceToLog(ELogVerbosity::VeryVerbose);
|
||||
return false;
|
||||
}
|
||||
|
||||
FTransform FGCS_CollisionShape::GetTransform(const UPrimitiveComponent* SourceComponent, const float& Time) const
|
||||
{
|
||||
GCS_OWNED_CLOG(SourceComponent, Warning, "Should never use this shape:%s", *FGCS_CollisionShape::StaticStruct()->GetName());
|
||||
FDebug::DumpStackTraceToLog(ELogVerbosity::VeryVerbose);
|
||||
return SourceComponent->GetComponentTransform();
|
||||
}
|
||||
|
||||
FCollisionShape FGCS_CollisionShape::GetDynamicCollisionShape(const UPrimitiveComponent* SourceComponent, const float& Time) const
|
||||
{
|
||||
GCS_OWNED_CLOG(SourceComponent, Warning, "Should never use this shape:%s", *FGCS_CollisionShape::StaticStruct()->GetName());
|
||||
FDebug::DumpStackTraceToLog(ELogVerbosity::VeryVerbose);
|
||||
return FCollisionShape::MakeSphere(30);
|
||||
}
|
||||
|
||||
bool FGCS_CollisionShape_Static::InitializeShape(const UPrimitiveComponent* SourceComponent)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
FTransform FGCS_CollisionShape_Static::GetTransform(const UPrimitiveComponent* SourceComponent, const float& Time) const
|
||||
{
|
||||
const auto ComponentCurrentTransform = SourceComponent->GetComponentTransform();
|
||||
return FTransform(Orientation, Offset) * ComponentCurrentTransform;
|
||||
}
|
||||
|
||||
FCollisionShape FGCS_CollisionShape_Static::GetDynamicCollisionShape(const UPrimitiveComponent* SourceComponent, const float& Time) const
|
||||
{
|
||||
switch (ShapeType)
|
||||
{
|
||||
case EGCS_CollisionShapeType::Sphere:
|
||||
{
|
||||
return FCollisionShape::MakeSphere(Radius);
|
||||
}
|
||||
case EGCS_CollisionShapeType::Box:
|
||||
{
|
||||
return FCollisionShape::MakeBox(HalfSize);
|
||||
}
|
||||
case EGCS_CollisionShapeType::Capsule:
|
||||
{
|
||||
return FCollisionShape::MakeCapsule(Radius, HalfHeight);
|
||||
}
|
||||
default:
|
||||
{
|
||||
return FCollisionShape::MakeSphere(Radius);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool FGCS_CollisionShape_ShapeBased::InitializeShape(const UPrimitiveComponent* SourceComponent)
|
||||
{
|
||||
if (ShapeType == EGCS_CollisionShapeType::Sphere)
|
||||
{
|
||||
if (const auto SphereCollision = Cast<USphereComponent>(SourceComponent))
|
||||
{
|
||||
Radius = SphereCollision->GetScaledSphereRadius();
|
||||
return true;
|
||||
}
|
||||
GCS_OWNED_CLOG(SourceComponent->GetOwner(), Warning, "No compatible shape component was found! Requires SphereComponent, Got %s(%s)", *GetNameSafe(SourceComponent),
|
||||
*SourceComponent->GetClass()->GetName())
|
||||
}
|
||||
if (ShapeType == EGCS_CollisionShapeType::Box)
|
||||
{
|
||||
if (const auto BoxCollision = Cast<UBoxComponent>(SourceComponent))
|
||||
{
|
||||
HalfSize = BoxCollision->GetScaledBoxExtent();
|
||||
return true;
|
||||
}
|
||||
GCS_OWNED_CLOG(SourceComponent->GetOwner(), Warning, "No compatible shape component was found! Requires BoxComponent, Got %s(%s)", *GetNameSafe(SourceComponent),
|
||||
*SourceComponent->GetClass()->GetName())
|
||||
}
|
||||
if (ShapeType == EGCS_CollisionShapeType::Capsule)
|
||||
{
|
||||
if (const auto CapsuleCollision = Cast<UCapsuleComponent>(SourceComponent))
|
||||
{
|
||||
HalfHeight = CapsuleCollision->GetScaledCapsuleHalfHeight();
|
||||
Radius = CapsuleCollision->GetScaledCapsuleRadius();
|
||||
return true;
|
||||
}
|
||||
GCS_OWNED_CLOG(SourceComponent->GetOwner(), Warning, "No compatible shape component was found! Requires CapsuleComponent, Got %s(%s)", *GetNameSafe(SourceComponent),
|
||||
*SourceComponent->GetClass()->GetName())
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
FTransform FGCS_CollisionShape_ShapeBased::GetTransform(const UPrimitiveComponent* SourceComponent, const float& Time) const
|
||||
{
|
||||
const auto ComponentCurrentTransform = SourceComponent->GetComponentTransform();
|
||||
return FTransform(Orientation, Offset) * ComponentCurrentTransform;
|
||||
}
|
||||
|
||||
FCollisionShape FGCS_CollisionShape_ShapeBased::GetDynamicCollisionShape(const UPrimitiveComponent* SourceComponent, const float& Time) const
|
||||
{
|
||||
switch (ShapeType)
|
||||
{
|
||||
case EGCS_CollisionShapeType::Sphere:
|
||||
{
|
||||
return FCollisionShape::MakeSphere(Radius);
|
||||
}
|
||||
case EGCS_CollisionShapeType::Box:
|
||||
{
|
||||
return FCollisionShape::MakeBox(HalfSize);
|
||||
}
|
||||
case EGCS_CollisionShapeType::Capsule:
|
||||
{
|
||||
return FCollisionShape::MakeCapsule(Radius, HalfHeight);
|
||||
}
|
||||
default:
|
||||
{
|
||||
return FCollisionShape::MakeSphere(Radius);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool FGCS_CollisionShape_Attached::InitializeShape(const UPrimitiveComponent* SourceComponent)
|
||||
{
|
||||
if (!IsValid(SourceComponent) || !SourceComponent->DoesSocketExist(SocketOrBoneName))
|
||||
{
|
||||
GCS_OWNED_CLOG(SourceComponent->GetOwner(), Warning, "No SocketOrBone(%s) exists on mesh component! Got %s(%s)", *SocketOrBoneName.ToString(), *GetNameSafe(SourceComponent),
|
||||
*SourceComponent->GetClass()->GetName())
|
||||
FDebug::DumpStackTraceToLog(ELogVerbosity::VeryVerbose);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
FTransform FGCS_CollisionShape_Attached::GetTransform(const UPrimitiveComponent* SourceComponent, const float& Time) const
|
||||
{
|
||||
const auto BoneTransform = SourceComponent->GetSocketTransform(SocketOrBoneName);
|
||||
return FTransform(Orientation, Offset) * BoneTransform;
|
||||
}
|
||||
|
||||
FTransform FGCS_CollisionShape_SocketBased::GetTransform(const UPrimitiveComponent* SourceComponent, const float& Time) const
|
||||
{
|
||||
const auto ComponentCurrentTransform = SourceComponent->GetComponentTransform();
|
||||
return FTransform(Orientation, Offset) * ComponentCurrentTransform;
|
||||
}
|
||||
|
||||
bool FGCS_CollisionShape_SocketBased::InitializeShape(const UPrimitiveComponent* SourceComponent)
|
||||
{
|
||||
if (const UMeshComponent* MeshComponent = Cast<UMeshComponent>(SourceComponent))
|
||||
{
|
||||
const auto SocketStartTransform = MeshComponent->GetSocketTransform(MeshSocketStart, RTS_Component);
|
||||
const auto SocketStartLocation = SocketStartTransform.GetLocation();
|
||||
|
||||
const auto SocketEndTransform = MeshComponent->GetSocketTransform(MeshSocketEnd, RTS_Component);
|
||||
const auto SocketEndLocation = SocketEndTransform.GetLocation();
|
||||
|
||||
const FVector CenterLocation = (SocketStartLocation + SocketEndLocation) / 2.f;
|
||||
|
||||
HalfHeight = FMath::Max((SocketStartLocation - SocketEndLocation).Length() / 2.f + MeshSocketLengthOffset, 1.f);
|
||||
Offset = CenterLocation;
|
||||
Orientation = FRotationMatrix::MakeFromZ(SocketStartLocation - SocketEndLocation).Rotator();
|
||||
|
||||
return true;
|
||||
}
|
||||
GCS_OWNED_CLOG(SourceComponent->GetOwner(), Warning, "No compatible mesh component was found! Got %s(%s)", *GetNameSafe(SourceComponent),
|
||||
*SourceComponent->GetClass()->GetName())
|
||||
return false;
|
||||
}
|
||||
|
||||
FCollisionShape FGCS_CollisionShape_SocketBased::GetDynamicCollisionShape(const UPrimitiveComponent* SourceComponent, const float& Time) const
|
||||
{
|
||||
return FCollisionShape::MakeCapsule(Radius, HalfHeight);
|
||||
}
|
||||
|
||||
FGCS_TraceDefinition::FGCS_TraceDefinition()
|
||||
{
|
||||
CollisionShape.InitializeAs(FGCS_CollisionShape_Static::StaticStruct());
|
||||
}
|
||||
|
||||
bool FGCS_TraceDefinition::IsValidDefinition() const
|
||||
{
|
||||
// Base collision shape is not allowed!
|
||||
return TraceTag.IsValid() && CollisionShape.IsValid() && CollisionShape.GetScriptStruct() != FGCS_CollisionShape::StaticStruct();
|
||||
}
|
||||
|
||||
FString FGCS_TraceDefinition::ToString() const
|
||||
{
|
||||
return FString::Format(TEXT("{0} {1}"), {TraceTag.ToString(), GetNameSafe(CollisionShape.GetScriptStruct())});
|
||||
}
|
||||
|
||||
bool FGCS_TraceHandle::IsValidHandle() const
|
||||
{
|
||||
return TraceTag.IsValid() && Guid.IsValid() && SourceObject.IsValid();
|
||||
}
|
||||
|
||||
void FGCS_TraceState::ChangeExecutionState(const bool bNewTraceState, const bool bStopImmediate)
|
||||
{
|
||||
if (bNewTraceState)
|
||||
{
|
||||
this->ExecutionState = EGCS_TraceExecutionState::InProgress;
|
||||
this->TimeSinceLastTick = 0;
|
||||
this->TimeSinceActive = 0;
|
||||
this->TotalTickNumDuringExecution = 0;
|
||||
this->HitActors.Reset();
|
||||
if (SourceComponent)
|
||||
{
|
||||
UpdatePreviousTransform(GetCurrentTransform());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this->ExecutionState == EGCS_TraceExecutionState::InProgress && !bStopImmediate)
|
||||
{
|
||||
this->ExecutionState = EGCS_TraceExecutionState::PendingStop;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->ExecutionState = EGCS_TraceExecutionState::Stopped;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FTransform FGCS_TraceState::GetCurrentTransform() const
|
||||
{
|
||||
check(Shape.IsValid())
|
||||
return Shape.Get<FGCS_CollisionShape>().GetTransform(SourceComponent.Get(), TimeSinceActive);
|
||||
}
|
||||
|
||||
void FGCS_TraceState::UpdatePreviousTransform(const FTransform& Transform)
|
||||
{
|
||||
if (TransformsOverTime.Num() == 0)
|
||||
{
|
||||
TransformsOverTime.Add(Transform);
|
||||
}
|
||||
else
|
||||
{
|
||||
TransformsOverTime[0] = Transform;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user