使用RTS相机的c ++程序中的错误

时间:2018-01-29 10:52:38

标签: c++ unreal-engine4

有人可以解决这个错误。我创建了rts相机运动到虚幻的引擎游戏。我正在使用本教程:https://forums.unrealengine.com/community/community-content-tools-and-tutorials/58912-rts-camera-c

这是代码https://answers.unrealengine.com/questions/752415/help-with-camera-errors.html

https://i.stack.imgur.com/U38Qj.png

RTSCameraSpectatorPawn.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "RTSPlayerCameraSpectatorPawn.generated.h"

UCLASS()
class GALICJA_API ARTSPlayerCameraSpectatorPawn : public APawn
{
GENERATED_BODY()

public:

//------------------------------------

/** Constructor */
ARTSPlayerCameraSpectatorPawn(const FObjectInitializer& ObjectInitializer);

//------------------------------------

/** Camera Component */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera)
    class UCameraComponent* CameraComponent;

//------------------------------------

//** Camera XY limit */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
    float CameraXYLimit;

//** Camera height over terrain */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
    float CameraHeight;

//** Camera min height over terrain */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
    float CameraHeightMin;

//** Camera max height over terrain */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
    float CameraHeightMax;

/** Camera Rotation around Axis Z */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
 "  float CameraZAnlge;

/** Camera Height Angle */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
    float CameraHeightAngle;

/** Camera Pitch Angle Max */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
    float CameraHeightAngleMax;

/** Camera Pitch Angle Min */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
    float CameraHeightAngleMin;

/** Camera Radius (Distance) From Pawn Position */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
    float CameraRadius;

/** Camera Radius Max */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
    float CameraRadiusMax;

/** Camera Radius Min */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
    float CameraRadiusMin;

/** Camera Zoom Speed */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
    float CameraZoomSpeed;

/** Camera Rotation Speed */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
    float CameraRotationSpeed;

/** Camera Movement Speed */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
    float CameraMovementSpeed;

/** Camera Scroll Boundary */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
    float CameraScrollBoundary;

/** Should the camera move? */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Camera)
    bool bCanMoveCamera;

//------------------------------------

private:

/** Sets up player inputs
*    @param InputComponent - Input Component
*/
void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent);

//------------------------------------

public:

/** Zooms In The Camera */
void ZoomInByWheel();

/** Zooms Out The Camera */
void ZoomOutByWheel();

/** Rotate The Camera Left */
void RotateLeftByWheel();

/** Rotate The Camera Right */
void RotateRightByWheel();

/** Rotate The Camera Up */
void RotateUpByWheel();

/** Rotate The Camera Down */
void RotateDownByWheel();

//---

/** Calculates the new Location and Rotation of The Camera */
void RepositionCamera();

//------------------------------------

private:

// set them to +/-1 to get player input from keyboard
float FastMoveValue;                                            // movement speed multiplier : 1 if shift unpressed, 2 is pressed
float RotateValue;                                                // turn instead of move camera

float MoveForwardValue;
float MoveRightValue;
float MoveUpValue;
float ZoomInValue;

//---

public:

/** Left or Right Shift is pressed
* @param direcation - (1.0 for Right, -1.0 for Left)
*/
void FastMoveInput(float Direction);

/** Left or Right Ctrl is pressed
* @param direcation - (1.0 for Right, -1.0 for Left)
*/
void RotateInput(float Direction);

/** Input recieved to move the camera forward
* @param direcation - (1.0 for forward, -1.0 for backward)
*/
void MoveCameraForwardInput(float Direction);

/** Input recieved to move the camera right
* @param direcation - (1.0 for right, -1.0 for left)
*/
void MoveCameraRightInput(float Direction);

/** Input recieved to move the camera right
* @param direcation - (1.0 for right, -1.0 for left)
*/
void MoveCameraUpInput(float Direction);

/** Input recieved to move the camera right
* @param direcation - (1.0 for right, -1.0 for left)
*/
void ZoomCameraInInput(float Direction);

//---

private:

/** Moves the camera forward
* @param direcation - (+ forward, - backward)
*/
FVector MoveCameraForward(float Direction);

/** Moves the camera right
* @param direcation - (+ right, - left)
*/
FVector MoveCameraRight(float Direction);

/** Gets the roatation of the camera with only the yaw value
* @return - returns a rotator that is (0, yaw, 0) of the Camera
*/
FRotator GetIsolatedCameraYaw();

//---

/** Moves the camera up/down
* @param direcation - (+ up, - down)
*/
float MoveCameraUp(float Direction);

//---

/** Zooms the camera in/out
* @param direcation - (+ in, - out)
*/
void ZoomCameraIn(float Direction);

/** Turns the camera up/down
* @param direcation - (+ up, - down)
*/
void TurnCameraUp(float Direction);

/** Turns the camera right/left
* @param direcation - (+ right, - left)
*/
void TurnCameraRight(float Direction);

//------------------------------------

public:

/** Tick Function, handles keyboard inputs */
virtual void Tick(float DeltaSeconds) override;

//------------------------------------

// detect landscape and terrain static-mesh
// usage: RTS Obstacle and RTS Building placement onto landscape, terrain static-mesh
float    GetLandTerrainSurfaceAtCoord(float XCoord, float YCoord) const;

//------------------------------------
};

RTSCameraSpectatorPawn.cpp

// Fill out your copyright notice in the Description page of Project Settings.

#include "RTSPlayerCameraSpectatorPawn.h"
#include "Camera/CameraComponent.h"
#include "Components/InputComponent.h"
#include "Engine.h"
#include "Galicja.h"


//////////////////////////////////////////////////////////////////


ARTSPlayerCameraSpectatorPawn::ARTSPlayerCameraSpectatorPawn(const FObjectInitializer& ObjectInitializer)
{
// enable Tick function
PrimaryActorTick.bCanEverTick = true;

// disable standard WASD movement
bAddDefaultMovementBindings = false;

// not needed Pitch Yaw Roll
bUseControllerRotationPitch = false;
bUseControllerRotationYaw = false;
bUseControllerRotationRoll = false;

// collision
GetCollisionComponent()->bGenerateOverlapEvents = false;
GetCollisionComponent()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
GetCollisionComponent()->SetCollisionProfileName(TEXT("NoCollision"));
GetCollisionComponent()->SetSimulatePhysics(false);

// set defaults

CameraXYLimit = 25000.f;
CameraHeight = 1000.f;
CameraHeightMin = 300.f;                // 100 for debugging
CameraHeightMax = 5000.f;

CameraRadius = 2000.f;
CameraRadiusMin = 1000.f;                // 100 for debugging
CameraRadiusMax = 8000.f;

CameraZAnlge = 0.f;                        // yaw

CameraHeightAngle = 30.f;                // pitch
CameraHeightAngleMin = 15.f;
CameraHeightAngleMax = 60.f;

CameraZoomSpeed = 200.f;                // wheel
CameraRotationSpeed = 10.f;                // wheel + ctrl
CameraMovementSpeed = 3000.f;            // in all directions

CameraScrollBoundary = 25.f;            // screen edge width

bCanMoveCamera = true;

// intialize the camera
CameraComponent = ObjectInitializer.CreateDefaultSubobject<UCameraComponent>(this, TEXT("RTS Camera"));
CameraComponent->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
CameraComponent->bUsePawnControlRotation = false;

RepositionCamera();
}


//////////////////////////////////////////////////////////////////


void ARTSPlayerCameraSpectatorPawn::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
{
if (!PlayerInputComponent) return;

Super::SetupPlayerInputComponent(PlayerInputComponent);

// action mappings

// mouse zoom
PlayerInputComponent->BindAction("ZoomOutByWheel", IE_Pressed, this, &ARTSPlayerCameraSpectatorPawn::ZoomOutByWheel);
PlayerInputComponent->BindAction("ZoomInByWheel", IE_Pressed, this, &ARTSPlayerCameraSpectatorPawn::ZoomInByWheel);

// mouse rotate (+Ctrl or +Alt)
// unnecessary...
//PlayerInputComponent->BindAction("RotateLeftByWheel", IE_Pressed, this, &ARTSPlayerCameraSpectatorPawn::RotateLeftByWheel);
//PlayerInputComponent->BindAction("RotateRightByWheel", IE_Pressed, this, &ARTSPlayerCameraSpectatorPawn::RotateRightByWheel);
// needed...
PlayerInputComponent->BindAction("RotateUpByWheel", IE_Pressed, this, &ARTSPlayerCameraSpectatorPawn::RotateUpByWheel);
PlayerInputComponent->BindAction("RotateDownByWheel", IE_Pressed, this, &ARTSPlayerCameraSpectatorPawn::RotateDownByWheel);

// axis mappings

// keyboard move (WASD, Home/End)
PlayerInputComponent->BindAxis("MoveForward", this, &ARTSPlayerCameraSpectatorPawn::MoveCameraForwardInput);
PlayerInputComponent->BindAxis("MoveRight", this, &ARTSPlayerCameraSpectatorPawn::MoveCameraRightInput);
PlayerInputComponent->BindAxis("MoveUp", this, &ARTSPlayerCameraSpectatorPawn::MoveCameraUpInput);
PlayerInputComponent->BindAxis("ZoomIn", this, &ARTSPlayerCameraSpectatorPawn::ZoomCameraInInput);

// double speed (WASD +Shift)
PlayerInputComponent->BindAxis("FastMove", this, &ARTSPlayerCameraSpectatorPawn::FastMoveInput);
// yaw and pitch (WASD +Ctrl)
PlayerInputComponent->BindAxis("Rotate", this, &ARTSPlayerCameraSpectatorPawn::RotateInput);
}


//////////////////////////////////////////////////////////////////


void ARTSPlayerCameraSpectatorPawn::ZoomInByWheel()
{
if (!bCanMoveCamera)    return;

CameraRadius -= CameraZoomSpeed * FastMoveValue;
CameraRadius = FMath::Clamp(CameraRadius, CameraRadiusMin, CameraRadiusMax);

//RepositionCamera();
}


void ARTSPlayerCameraSpectatorPawn::ZoomOutByWheel()
{
if (!bCanMoveCamera)    return;

CameraRadius += CameraZoomSpeed * FastMoveValue;
CameraRadius = FMath::Clamp(CameraRadius, CameraRadiusMin, CameraRadiusMax);

//RepositionCamera();
}


void ARTSPlayerCameraSpectatorPawn::RotateLeftByWheel()
{
if (!bCanMoveCamera)    return;

CameraZAnlge -= CameraRotationSpeed * FastMoveValue;

//RepositionCamera();
}


void ARTSPlayerCameraSpectatorPawn::RotateRightByWheel()
{
if (!bCanMoveCamera)    return;

CameraZAnlge += CameraRotationSpeed * FastMoveValue;

//RepositionCamera();
}


void ARTSPlayerCameraSpectatorPawn::RotateUpByWheel()
{
if (!bCanMoveCamera)    return;

CameraHeightAngle += CameraRotationSpeed * FastMoveValue;
CameraHeightAngle = FMath::Clamp(CameraHeightAngle, CameraHeightAngleMin, CameraHeightAngleMax);

//RepositionCamera();
}


void ARTSPlayerCameraSpectatorPawn::RotateDownByWheel()
{
if (!bCanMoveCamera)    return;

CameraHeightAngle -= CameraRotationSpeed * FastMoveValue;
CameraHeightAngle = FMath::Clamp(CameraHeightAngle, CameraHeightAngleMin, CameraHeightAngleMax);

//RepositionCamera();
}

//---------------

void ARTSPlayerCameraSpectatorPawn::RepositionCamera()
{
FVector NewLocation(0.f, 0.f, 0.f);
FRotator NewRotation(0.f, 0.f, 0.f);

float sinCameraZAngle = FMath::Sin(FMath::DegreesToRadians(CameraZAnlge));
float cosCameraZAngle = FMath::Cos(FMath::DegreesToRadians(CameraZAnlge));

float sinCameraHeightAngle = FMath::Sin(FMath::DegreesToRadians(CameraHeightAngle));
float cosCameraHeightAngle = FMath::Cos(FMath::DegreesToRadians(CameraHeightAngle));

NewLocation.X = cosCameraZAngle * cosCameraHeightAngle * CameraRadius;
NewLocation.Y = sinCameraZAngle * cosCameraHeightAngle * CameraRadius;
NewLocation.Z = sinCameraHeightAngle * CameraRadius;

// do not allow camera component to go under ground - not enough alone, actor also needed to be limited
float TerrainSurfaceZ = GetLandTerrainSurfaceAtCoord(GetActorLocation().X + NewLocation.X, GetActorLocation().Y + NewLocation.Y);
if (GetActorLocation().Z + NewLocation.Z < TerrainSurfaceZ + CameraHeight)
{
    //FVector NewLocation = CameraComponent->GetComponentLocation();
    NewLocation.Z = TerrainSurfaceZ - GetActorLocation().Z + CameraHeight;
}

// new camera location
CameraComponent->SetRelativeLocation(NewLocation);

// new camera rotation
NewRotation = (FVector(0.0f, 0.0f, 0.0f) - NewLocation).Rotation();
CameraComponent->SetRelativeRotation(NewRotation);
}


//////////////////////////////////////////////////////////////////


 void ARTSPlayerCameraSpectatorPawn::FastMoveInput(float Direction)
{
if (!bCanMoveCamera)    return;

// left or right does not matter, to set double speed in any direction
FastMoveValue = FMath::Abs(Direction) * 2.0f;

// used as multiplier so must be 1 if not pressed
if (FastMoveValue == 0.0f)
{
    FastMoveValue = 1.0f;
}
}


void ARTSPlayerCameraSpectatorPawn::RotateInput(float Direction)
{
if (!bCanMoveCamera)    return;

// left or right does not matter
RotateValue = FMath::Abs(Direction);
}


void ARTSPlayerCameraSpectatorPawn::MoveCameraForwardInput(float Direction)
{
if (!bCanMoveCamera)    return;

MoveForwardValue = Direction;
}


void ARTSPlayerCameraSpectatorPawn::MoveCameraRightInput(float Direction)
{
if (!bCanMoveCamera)    return;

MoveRightValue = Direction;
}


void ARTSPlayerCameraSpectatorPawn::MoveCameraUpInput(float Direction)
{
if (!bCanMoveCamera)    return;

MoveUpValue = Direction;
}


void ARTSPlayerCameraSpectatorPawn::ZoomCameraInInput(float Direction)
{
if (!bCanMoveCamera)    return;

ZoomInValue = Direction;
}


//------------------------------------------------------------


FVector ARTSPlayerCameraSpectatorPawn::MoveCameraForward(float Direction)
{
float MovementValue = Direction * CameraMovementSpeed;
FVector DeltaMovement = MovementValue * GetIsolatedCameraYaw().Vector();
//FVector NewLocation = GetActorLocation() + DeltaMovement;
//SetActorLocation(NewLocation);
return DeltaMovement;
}


FVector ARTSPlayerCameraSpectatorPawn::MoveCameraRight(float Direction)
{
float MovementValue = Direction * CameraMovementSpeed;
FVector DeltaMovement = MovementValue * (FRotator(0.0f, 90.0f, 0.0f) + GetIsolatedCameraYaw()).Vector();
//FVector NewLocation = GetActorLocation() + DeltaMovement;
//SetActorLocation(NewLocation);
return DeltaMovement;
}


FRotator ARTSPlayerCameraSpectatorPawn::GetIsolatedCameraYaw()
{
// FRotator containing Yaw only
return FRotator(0.0f, CameraComponent->ComponentToWorld.Rotator().Yaw, 0.0f);
}

//---------------

float ARTSPlayerCameraSpectatorPawn::MoveCameraUp(float Direction)
 {
float MovementValue = Direction * CameraMovementSpeed;
//FVector DeltaMovement = FVector(0.0f, 0.0f, MovementValue);
//FVector NewLocation = GetActorLocation() + DeltaMovement;
//NewLocation.Z = FMath::Clamp(NewLocation.Z, CameraRadiusMin, CameraRadiusMax);
//SetActorLocation(NewLocation);
return MovementValue;
}

//---------------

void ARTSPlayerCameraSpectatorPawn::ZoomCameraIn(float Direction)
{
float MovementValue = Direction * CameraMovementSpeed;
CameraRadius += MovementValue;
CameraRadius = FMath::Clamp(CameraRadius, CameraRadiusMin, CameraRadiusMax);

//RepositionCamera();
}


void ARTSPlayerCameraSpectatorPawn::TurnCameraUp(float Direction)
{
CameraHeightAngle -= Direction * CameraRotationSpeed * 10.0f;
CameraHeightAngle = FMath::Clamp(CameraHeightAngle, CameraHeightAngleMin, CameraHeightAngleMax);

//RepositionCamera();
}


void ARTSPlayerCameraSpectatorPawn::TurnCameraRight(float Direction)
{
CameraZAnlge += Direction * CameraRotationSpeed * 10.0f;

//RepositionCamera();
}


//////////////////////////////////////////////////////////////////


void ARTSPlayerCameraSpectatorPawn::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);

// mouse position and screen size
FVector2D MousePosition;
FVector2D ViewportSize;

UGameViewportClient* GameViewport = GEngine->GameViewport;

// it is always nullptr on dedicated server
if (!GameViewport) return;
GameViewport->GetViewportSize(ViewportSize);

// if viewport is focused, contains the mouse, and camera movement is allowed
if (GameViewport->IsFocused(GameViewport->Viewport)
    && GameViewport->GetMousePosition(MousePosition) && bCanMoveCamera)
{
    //-------------------
    // movement direction by mouse at screen edge

    if (MousePosition.X < CameraScrollBoundary)
    {
        MoveRightValue = -1.0f;
    }
    else if (ViewportSize.X - MousePosition.X < CameraScrollBoundary)
    {
        MoveRightValue = 1.0f;
    }

    if (MousePosition.Y < CameraScrollBoundary)
    {
        MoveForwardValue = 1.0f;
    }
    else if (ViewportSize.Y - MousePosition.Y < CameraScrollBoundary)
    {
        MoveForwardValue = -1.0f;
    }

    //-------------------
    // tweak camera actor position

    FVector ActualLocation = GetActorLocation();
    FVector ActualMovement = FVector::ZeroVector;

    // horizontal movement
    if (RotateValue == 0.f)
    {
        ActualMovement += MoveCameraForward(MoveForwardValue * FastMoveValue * DeltaSeconds);
        ActualMovement += MoveCameraRight(MoveRightValue * FastMoveValue * DeltaSeconds);
    }
    ActualLocation += ActualMovement;

    // vertical movement
    CameraHeight += MoveCameraUp(MoveUpValue * FastMoveValue * DeltaSeconds);
    CameraHeight = FMath::Clamp(CameraHeight, CameraHeightMin, CameraHeightMax);

    // adjust actor height to surface
    float TerrainSurfaceZ = GetLandTerrainSurfaceAtCoord(ActualLocation.X, ActualLocation.Y);
    ActualLocation.Z = TerrainSurfaceZ + CameraHeight;

    // limit movement area
    ActualLocation.X = FMath::Clamp(ActualLocation.X, -CameraXYLimit, CameraXYLimit);
    ActualLocation.Y = FMath::Clamp(ActualLocation.Y, -CameraXYLimit, CameraXYLimit);

    // move actor
    SetActorLocation(ActualLocation);

    //-------------------
    // tweak camera component relative transform

    // set rotation parameters
    if (RotateValue != 0.f)
    {
        TurnCameraUp(MoveForwardValue * FastMoveValue * DeltaSeconds);
        TurnCameraRight(MoveRightValue * FastMoveValue * DeltaSeconds);
    }

    // set zoom distance
    ZoomCameraIn(ZoomInValue * FastMoveValue * DeltaSeconds);

    // adjust camera component relative location and rotation
    RepositionCamera();

    //-------------------
    // debug

    //DrawDebugSphere(    
    //                    GetWorld(),
    //                    GetCollisionComponent()->GetComponentLocation(),
    //                    GetCollisionComponent()->GetScaledSphereRadius(),
    //                    8,
    //                    FColor::White,
    //                    false,
    //                    -1.f
    //                );

    //-------------------
}
}


//////////////////////////////////////////////////////////////////


float    ARTSPlayerCameraSpectatorPawn::GetLandTerrainSurfaceAtCoord(float XCoord, float YCoord) const
{
FCollisionQueryParams TraceParams(FName(TEXT("LandTerrain")), false, this);        // TraceTag (info for debugging), bTraceComplex, AddIgnoredActor
TraceParams.bFindInitialOverlaps = false;                                        // needed

FHitResult Hit;

FVector Start = FVector(XCoord, YCoord, GetActorLocation().Z + CameraRadius);
FVector End = FVector(XCoord, YCoord, -500.f);

// ECC_ channels should be set properly !!!
bool bHit = GetWorld()->LineTraceSingleByChannel(Hit, Start, End, ECollisionChannel::ECC_WorldStatic, TraceParams);

if (bHit)
{
    return Hit.ImpactPoint.Z;    // for shape trace it differs from Location
}

return 0.f;        // water level
}

//////////////////////////////////////////////////////////////////

1 个答案:

答案 0 :(得分:0)

您是否阅读过教程下的帖子? 这是教程第一页的最后一篇文章:

#include "RTSPlayerCameraSpectatorPawn.h"
#include "Components/SphereComponent.h" //Needed for the Collision Component to work
#include "Camera/CameraComponent.h" //Needed for the Camera Component to work
#include "Components/InputComponent.h" //Needed for the Player Input Component to work
#include "Classes/Engine/GameViewportClient.h" //Needed for the GameViewport to work
#include "Engine.h" //Needed for Gengine to work

frederic post

用户 Frederic 生成重叠事件有相同的问题,请先按照他的步骤操作。