Hallo,
ich habe ein Spiel bei dem sich der Spieler (Ego-Perspektive) durch ein Asteroidenfeld bewegt (technisch gesehen kommt alles auf ihn zu, weil das level unendlich lang ist).
Dabei rollt er, also er dreht sich um (hier) die x-Achse:
x-Achse zeigt nach vorne,
y-Achse nach rechts und
z-Achse nach oben.
Nun gibt es eine Art Box, die die Bewegungen nach oben, unten, links, rechts einschränkt (zum Ausweichen).
Wegen dem Camera Roll dreht sich die Box ja auch mit.
Es gibt im GUI Indikatoren an jeder Seite wenn er an eine Seite stößt (als Warnung dass es nicht weitergeht).
Ich muss also unter jeder Drehung herausfinden, an welche Seite er vielleicht stößt.
Dazu dachte ich mir folgendes:
Ich mache einen Transform (Ein Objekt mit Position, Rotation, ...), der als Koordinatensystem dient (akzeptiert auch Achsen im Konstruktor).
Dieses ist ausgerichtet wie der Spieler, allerdings im Mittelpunkt positioniert. Dann transformiere ich die Spielerposition in das System und ich kann einfach immer die y und z Werte untersuchen, da y immer zur rechten Seite zeigt.
Nach der Transformation scheinen die Koordinaten aber irgendwie invertiert sein (positive Y-Werte gehen nach links und Z-Werte nach unten). Wenn ich eine inverse Transformation anwende funktioniert es.
Kann mir jemand erklären warum? Ich habe noch Code angehängt:
|
C-/C++-Quelltext
|
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
|
void AMainPawn::TickPlayerMovement(float Delta)
{
// Move player
FVector NewLoc = FVector(0.0f, MoveRightVal * FMath::Abs(MovementSpeedFactor) * Delta, MoveUpVal * MovementSpeedFactor * Delta);
this->AddActorLocalOffset(NewLoc, true);
// Ensure, that player is in the camera bounds
NewLoc = this->GetActorLocation();
// The Actor transform in the center, so our calculations are rotation aligned
FTransform LocalTransform = FTransform(this->GetActorRotation(), FVector::ZeroVector, this->GetActorScale3D());
NewLoc = LocalTransform.InverseTransformPosition(NewLoc);
NewLoc.Y = FMath::Clamp<float>(NewLoc.Y, 0.0f - CameraBoundsWidth, 0.0f + CameraBoundsWidth);
NewLoc.Z = FMath::Clamp<float>(NewLoc.Z, 0.0f - CameraBoundsHeight, 0.0f + CameraBoundsHeight);
if (NewLoc.Y <= 0.0f - CameraBoundsWidth)
ShowEdgeIndicator(0, true);
else
ShowEdgeIndicator(0, false);
if (NewLoc.Y >= 0.0f + CameraBoundsWidth)
ShowEdgeIndicator(2, true);
else
ShowEdgeIndicator(2, false);
if (NewLoc.Z >= 0.0f + CameraBoundsHeight)
ShowEdgeIndicator(1, true);
else
ShowEdgeIndicator(1, false);
if (NewLoc.Z <= 0.0f - CameraBoundsHeight)
ShowEdgeIndicator(3, true);
else
ShowEdgeIndicator(3, false);
NewLoc = LocalTransform.TransformPosition(NewLoc);
this->SetActorLocation(NewLoc);
}
|