My goal when assigning the UPROPERTY values as shown in the code below was to be able to adjust them in a blueprint so that I could get my camera relatively correct before hard-coding them later.
However, it seems that adjusting these values no longer seems to change the camera location, which seems strange to me. The relative X and Y seem to be correct, as is the rotation Z value. However, I’d like to adjust the camera’s relative Z coordinate so the bird doesn’t start at the top of the screen like it is, and so that I can eventually see a floor at Z = 0.
Seems that adjusting these values both in the *.h file and the EaglePawn blueprint does nothing. Also, according to my debug message, the eagle is apparently generated at (0, 0, 0), and so is the camera. These don’t make sense.
How should I go about adjusting the camera’s relative location?
It’s saying it wants a constant pointer, and it’s getting a non-constant pointer (I think?) This is despite me basically copying the code verbatim from the FPS tutorial of Unreal (accounting for the variable name change, of course.)
Okay. I nixed the casting, but apparently my Pawn class doesn’t have a GetCapsuleComponent() property? It seemed to be automatic in the FPS C++ tutorial. What do you recommend I do?
Okay. You were correct that the GetCapsuleComponent() method is not a method of APawn. I replaced it with GetRootComponent() (after setting the RootComponent value to the mesh,) and now Unreal Engine crashes on startup because it does not like the DetachFromComponent call.
AEaglePawn::AEaglePawn()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
//Get a reference to the game world so we can spawn new objects as needed
UWorld* World = GetWorld();
if (World) {
FActorSpawnParameters SpawnParams;
SpawnParams.Owner = this;
SpawnParams.Instigator = GetInstigator();
//Create an obstacle spawner. Its state will depend on the player's state (pause, ready, etc)
Spawner = World->SpawnActor<AObstacleSpawner>(SpawnParams);
}
//Create a first-person mesh component for the owning player.
PlayerMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("PlayerMesh"));
check(PlayerMesh != nullptr);
//Assign the mesh as the root component of the player object
RootComponent = PlayerMesh;
//Create a third person camera component
ThirdPersonCameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("ThirdPersonCamera"));
check(ThirdPersonCameraComponent != nullptr);
//Attach the camera so you can set its relative location and rotation
ThirdPersonCameraComponent->SetupAttachment(GetRootComponent());
//Position the camera about 5 meters away from the bird, sideways
ThirdPersonCameraComponent->SetRelativeLocation(FVector(CAMERA_OFFSET_X, CAMERA_OFFSET_Y, CAMERA_OFFSET_Z));
//Rotate the camera to face the player, and so that player appears to face to the right.
ThirdPersonCameraComponent->SetRelativeRotation(FRotator(CAMERA_ROTATE_X, CAMERA_ROTATE_Y, CAMERA_ROTATE_Z));
//Indicator whether a flap has been initiated
bFlap = false;
bFlapInitiated = false;
//Initialize vector speed
zspeed = 0.0f;
//Initailize Player State
state = ST_READY;
//DEBUG
FVector pos = GetActorLocation();
FVector campos = ThirdPersonCameraComponent->GetComponentLocation();
const auto debug_msg = FString::Printf(TEXT("Eagle X = %f, Y = %f, Z = %f; Camera X = %f, Y = %f, Z = %f"), pos.X, pos.Y, pos.Z, campos.X, campos.Y, campos.Z);
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Blue, debug_msg);
//Detach the camera so it doesn't bounce with the player
ThirdPersonCameraComponent->DetachFromComponent(FDetachmentTransformRules::KeepWorldTransform); //Unreal Engine Launch crashes due to this line.
}
You might then extrapolate that you shouldn’t be detatching a component from within the constructor. Much less detatching it at all. If you detach it, how will it follow your player at all?
Well, the idea is that the bird will be flapping up and down, similar to FlappyBird, but I don’t want the camera bouncing with it. The game is almost a side-scroller, except the environment moves instead of the player, save for up and down movement.
Okay, so what’s weird is that apparently the crash report was misleading. I commented out the DEBUG code (meant to display the debug message upon creation) and I left the DetachFromComponent line in. Compiled and loaded just fine.
[EDIT] However, this still puts me back at square 1. changing the CAMERA_OFFSET_Z UPROPERTY in the blueprint does not affect the camera’s location.
It won’t move the camera because the position of the camera isn’t relative to the character anymore. You’ve detached it, so it has no position to be relative to.
Your best option is to disable Z movement on the camera boom
Well, the goal is to initialize the camera to a relative location (Z included) in the constructor, and then detach it so it doesn’t move.
It’s just bizarre to me that every relative coordinate I’m using for the camera seem to work, EXCEPT the CAMERA_OFFSET_Z value. Granted, I haven’t tried changing the other values recently, but it makes no sense to me that the camera is positioned with the wanted X and Y offsets, as well as the Z axis turn, but I can’t get the Z offset correct.
Okay. Looks like I was able to solve it by putting the following code in BeginPlay() instead of the constructor. And bonus! The debug message works again!
//DEBUG
check(ThirdPersonCameraComponent != nullptr);
FVector pos = GetActorLocation();
FVector campos = ThirdPersonCameraComponent->GetComponentLocation();
const auto debug_msg = FString::Printf(TEXT("Eagle X = %f, Y = %f, Z = %f; Camera X = %f, Y = %f, Z = %f"), pos.X, pos.Y, pos.Z, campos.X, campos.Y, campos.Z);
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Blue, debug_msg);
//Detach the camera so it doesn't bounce with the player
ThirdPersonCameraComponent->DetachFromComponent(FDetachmentTransformRules::KeepWorldTransform);