有人可以解决这个错误。我创建了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
}
//////////////////////////////////////////////////////////////////
答案 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 与生成重叠事件有相同的问题,请先按照他的步骤操作。