This repository was archived by the owner on Dec 21, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathNavLadderComponent.cpp
More file actions
122 lines (107 loc) · 4.34 KB
/
Copy pathNavLadderComponent.cpp
File metadata and controls
122 lines (107 loc) · 4.34 KB
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Fill out your copyright notice in the Description page of Project Settings.
#include "NavLadderComponent.h"
UNavLadderComponent::UNavLadderComponent()
:Super()
{
MovementModes.Empty();
MovementModes.Add(EGridMovementMode::ClimbingUp);
MovementModes.Add(EGridMovementMode::ClimbingDown);
}
void UNavLadderComponent::SetGrid(ANavGrid *InGrid)
{
Super::SetGrid(InGrid);
TileSize = InGrid->TileSize;
}
void UNavLadderComponent::GetNeighbours(const UCapsuleComponent &CollisionCapsule, TArray<UNavTileComponent *> &OutUnObstructed, TArray<UNavTileComponent *> &OutObstructed)
{
OutUnObstructed.Empty();
OutObstructed.Empty();
if (IsValid(Grid))
{
FCollisionShape Shape = FCollisionShape::MakeBox(BoxExtent + FVector(Grid->TileSize / 2));
TArray<FHitResult> HitResults;
TArray<UNavTileComponent *> AllNeighbours;
Grid->GetWorld()->SweepMultiByChannel(HitResults, GetComponentLocation(), GetComponentLocation() + FVector(0, 0, 1), GetComponentQuat(), Grid->ECC_NavGridWalkable, Shape);
for (FHitResult &Hit : HitResults)
{
UNavTileComponent *HitTile = Cast<UNavTileComponent>(Hit.GetComponent());
if (IsValid(HitTile) && HitTile != this)
{
AllNeighbours.AddUnique(HitTile);
}
}
for (UNavTileComponent *N : AllNeighbours)
{
//Determine if we should trace from the top or bottom point
float TopDistance = (GetTopPathPoint() - N->GetPawnLocation()).Size();
float BottomDistance = (GetBottomPathPoint() - N->GetPawnLocation()).Size();
FVector TracePoint = TopDistance < BottomDistance ? GetTopPathPoint() : GetBottomPathPoint();
if (N->Obstructed(TracePoint, CollisionCapsule))
{
OutObstructed.Add(N);
}
else
{
OutUnObstructed.Add(N);
}
}
}
}
bool UNavLadderComponent::Obstructed(const FVector & FromPos, const UCapsuleComponent & CollisionCapsule) const
{
//Determine if we should trace to the top or bottom point
float TopDistance = (GetTopPathPoint() - FromPos).Size();
float BottomDistance = (GetBottomPathPoint() - FromPos).Size();
FVector TracePoint = TopDistance < BottomDistance ? GetTopPathPoint() : GetBottomPathPoint();
FHitResult OutHit;
FCollisionShape CollisionShape = CollisionCapsule.GetCollisionShape();
FCollisionQueryParams CQP;
CQP.AddIgnoredActor(CollisionCapsule.GetOwner());
CQP.TraceTag = "NavGridMovement";
return CollisionCapsule.GetWorld()->SweepSingleByChannel(OutHit, FromPos + CollisionCapsule.GetRelativeLocation(), TracePoint + CollisionCapsule.GetRelativeLocation(),
GetComponentQuat(), ECollisionChannel::ECC_Pawn, CollisionShape, CQP);
}
void UNavLadderComponent::AddPathSegments(USplineComponent &OutSpline, TArray<FPathSegment> &OutPathSegments, bool EndTile) const
{
FVector EntryPoint = OutSpline.GetLocationAtSplinePoint(OutSpline.GetNumberOfSplinePoints() - 1, ESplineCoordinateSpace::Local);
float TopDistance = (GetTopPathPoint() - EntryPoint).Size();
float BottomDistance = (GetBottomPathPoint() - EntryPoint).Size();
FPathSegment NewSegment;
NewSegment.MovementModes = MovementModes;
NewSegment.PawnRotationHint = GetComponentRotation();
NewSegment.PawnRotationHint.Yaw -= 180;
// add spline points and segments
if (TopDistance > BottomDistance)
{
OutSpline.AddSplinePoint(GetBottomPathPoint(), ESplineCoordinateSpace::Local);
NewSegment.Start = OutSpline.GetSplineLength();
OutSpline.AddSplinePoint(GetTopPathPoint(), ESplineCoordinateSpace::Local);
NewSegment.End = OutSpline.GetSplineLength();
}
else
{
OutSpline.AddSplinePoint(GetTopPathPoint(), ESplineCoordinateSpace::Local);
NewSegment.Start = OutSpline.GetSplineLength();
OutSpline.AddSplinePoint(GetBottomPathPoint(), ESplineCoordinateSpace::Local);
NewSegment.End = OutSpline.GetSplineLength();
}
// unlike regular tiles, we do not want the pawn to change movement mode untill it reaches the first path point
// we therefore extend the previous segment to that point
if (OutPathSegments.Num())
{
OutPathSegments.Last().End = NewSegment.Start;
}
// add the new segment
OutPathSegments.Add(NewSegment);
if (EndTile)
{
OutSpline.RemoveSplinePoint(OutSpline.GetNumberOfSplinePoints() - 1);
OutSpline.AddSplinePoint(PawnLocationOffset + GetComponentLocation(), ESplineCoordinateSpace::Local);
}
}
FVector UNavLadderComponent::GetSplineMeshUpVector()
{
FRotator Rot = GetComponentRotation();
FVector UpVector = Rot.RotateVector(FVector(0, -1, 0));
return UpVector;
}