Unreal Engine开发:虚拟摄像机开发_虚拟摄像机的交互设计

虚拟摄像机的交互设计

1. 摄像机控制的基本概念

在Unreal Engine中,虚拟摄像机的交互设计是指通过用户输入来控制摄像机的行为,使摄像机能够根据玩家的意图和动作做出相应的反应。这种控制可以是平移、旋转、缩放等,也可以是更复杂的摄像机切换、跟随、避障等。理解摄像机控制的基本概念是设计高效、自然的摄像机交互的基础。

1.1 摄像机的基本属性

在Unreal Engine中,摄像机的基本属性包括位置(Position)、旋转(Rotation)和视野(Field of View, FOV)。这些属性可以通过蓝图或C++代码进行控制。

1.1.1 位置(Position)

摄像机的位置决定了它在场景中的空间位置。可以使用Set World Location函数来设置摄像机的位置。


// C++ 代码示例

APlayerCameraManager* CameraManager = UGameplayStatics::GetPlayerCameraManager(GetWorld(), 0);

FVector NewLocation = FVector(1000.0f, 0.0f, 500.0f);

CameraManager->SetCameraLocation(NewLocation);

1.1.2 旋转(Rotation)

摄像机的旋转决定了它在场景中的朝向。可以使用Set World Rotation函数来设置摄像机的旋转。


// C++ 代码示例

APlayerCameraManager* CameraManager = UGameplayStatics::GetPlayerCameraManager(GetWorld(), 0);

FRotator NewRotation = FRotator(0.0f, 90.0f, 0.0f);

CameraManager->SetCameraRotation(NewRotation);

1.1.3 视野(Field of View, FOV)

摄像机的视野决定了它可以捕捉的场景范围。可以使用Set FOV函数来设置摄像机的视野。


// C++ 代码示例

APlayerCameraManager* CameraManager = UGameplayStatics::GetPlayerCameraManager(GetWorld(), 0);

CameraManager->SetFOV(90.0f);

1.2 摄像机控制的方式

摄像机控制的方式主要有两种:直接控制和间接控制。

1.2.1 直接控制

直接控制是指通过玩家的输入直接改变摄像机的位置和旋转。例如,使用鼠标来旋转摄像机,使用键盘来平移摄像机。


// C++ 代码示例

void AMyCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)

{
    
    

    Super::SetupPlayerInputComponent(PlayerInputComponent);



    PlayerInputComponent->BindAxis("MoveForward", this, &AMyCharacter::MoveForward);

    PlayerInputComponent->BindAxis("MoveRight", this, &AMyCharacter::MoveRight);

    PlayerInputComponent->BindAxis("Turn", this, &AMyCharacter::Turn);

    PlayerInputComponent->BindAxis("LookUp", this, &AMyCharacter::LookUp);

}



void AMyCharacter::MoveForward(float Value)

{
    
    

    if (Value != 0.0f)

    {
    
    

        // 找到当前摄像机的前向方向

        FVector ForwardVector = GetActorForwardVector();

        // 以角色的速度和输入值移动角色

        AddMovementInput(ForwardVector, Value);

    }

}



void AMyCharacter::MoveRight(float Value)

{
    
    

    if (Value != 0.0f)

    {
    
    

        // 找到当前摄像机的右向方向

        FVector RightVector = GetActorRightVector();

        // 以角色的速度和输入值移动角色

        AddMovementInput(RightVector, Value);

    }

}



void AMyCharacter::Turn(float Value)

{
    
    

    if (Value != 0.0f)

    {
    
    

        // 以输入值旋转角色

        AddControllerYawInput(Value);

    }

}



void AMyCharacter::LookUp(float Value)

{
    
    

    if (Value != 0.0f)

    {
    
    

        // 以输入值旋转角色

        AddControllerPitchInput(Value);

    }

}

1.2.2 间接控制

间接控制是指通过控制其他对象(如角色或场景元素)来间接改变摄像机的位置和旋转。例如,摄像机可以跟随角色的移动,或者在特定场景元素之间切换。


// C++ 代码示例

void AMyCharacter::UpdateCameraLocation()

{
    
    

    // 获取角色的位置

    FVector CharacterLocation = GetActorLocation();

    // 设置摄像机的位置

    APlayerCameraManager* CameraManager = UGameplayStatics::GetPlayerCameraManager(GetWorld(), 0);

    FVector CameraOffset = FVector(-300.0f, 0.0f, 200.0f);

    FVector NewCameraLocation = CharacterLocation + CameraOffset;

    CameraManager->SetCameraLocation(NewCameraLocation);

}

2. 摄像机的基本交互

在Unreal Engine中,摄像机的基本交互包括鼠标和键盘的输入处理、摄像机的平移、旋转和缩放等。

2.1 鼠标和键盘的输入处理

鼠标和键盘的输入处理是摄像机交互的基础。通过绑定输入轴和输入动作,可以实现对摄像机的精细控制。

2.1.1 绑定输入轴

输入轴用于处理连续的输入,例如鼠标移动和键盘按下的持续输入。


// C++ 代码示例

void AMyCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)

{
    
    

    Super::SetupPlayerInputComponent(PlayerInputComponent);



    PlayerInputComponent->BindAxis("Turn", this, &AMyCharacter::Turn);

    PlayerInputComponent->BindAxis("LookUp", this, &AMyCharacter::LookUp);

    PlayerInputComponent->BindAxis("MoveForward", this, &AMyCharacter::MoveForward);

    PlayerInputComponent->BindAxis("MoveRight", this, &AMyCharacter::MoveRight);

}

2.1.2 绑定输入动作

输入动作用于处理离散的输入,例如按键的按下和释放。


// C++ 代码示例

void AMyCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)

{
    
    

    Super::SetupPlayerInputComponent(PlayerInputComponent);



    PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &AMyCharacter::Jump);

    PlayerInputComponent->BindAction("Jump", IE_Released, this, &AMyCharacter::StopJumping);

}

2.2 摄像机的平移

摄像机的平移是指在场景中移动摄像机的位置。可以通过输入轴来实现平移。

2.2.1 使用输入轴平移摄像机

// C++ 代码示例

void AMyCharacter::MoveForward(float Value)

{
    
    

    if (Value != 0.0f)

    {
    
    

        // 找到当前摄像机的前向方向

        FVector ForwardVector = GetActorForwardVector();

        // 以角色的速度和输入值移动角色

        AddMovementInput(ForwardVector, Value);

    }

}



void AMyCharacter::MoveRight(float Value)

{
    
    

    if (Value != 0.0f)

    {
    
    

        // 找到当前摄像机的右向方向

        FVector RightVector = GetActorRightVector();

        // 以角色的速度和输入值移动角色

        AddMovementInput(RightVector, Value);

    }

}

2.3 摄像机的旋转

摄像机的旋转是指改变摄像机的朝向。可以通过输入轴来实现旋转。

2.3.1 使用输入轴旋转摄像机

// C++ 代码示例

void AMyCharacter::Turn(float Value)

{
    
    

    if (Value != 0.0f)

    {
    
    

        // 以输入值旋转角色

        AddControllerYawInput(Value);

    }

}



void AMyCharacter::LookUp(float Value)

{
    
    

    if (Value != 0.0f)

    {
    
    

        // 以输入值旋转角色

        AddControllerPitchInput(Value);

    }

}

2.4 摄像机的缩放

摄像机的缩放是指改变摄像机的视野(FOV)。可以通过输入轴或输入动作来实现缩放。

2.4.1 使用输入轴缩放摄像机

// C++ 代码示例

void AMyCharacter::Zoom(float Value)

{
    
    

    if (Value != 0.0f)

    {
    
    

        APlayerCameraManager* CameraManager = UGameplayStatics::GetPlayerCameraManager(GetWorld(), 0);

        float CurrentFOV = CameraManager->GetFOVAngle();

        float NewFOV = FMath::Clamp(CurrentFOV + Value, 10.0f, 120.0f);

        CameraManager->SetFOV(NewFOV);

    }

}

2.4.2 使用输入动作缩放摄像机

// C++ 代码示例

void AMyCharacter::ZoomIn()

{
    
    

    APlayerCameraManager* CameraManager = UGameplayStatics::GetPlayerCameraManager(GetWorld(), 0);

    float CurrentFOV = CameraManager->GetFOVAngle();

    float NewFOV = FMath::Clamp(CurrentFOV - 10.0f, 10.0f, 120.0f);

    CameraManager->SetFOV(NewFOV);

}



void AMyCharacter::ZoomOut()

{
    
    

    APlayerCameraManager* CameraManager = UGameplayStatics::GetPlayerCameraManager(GetWorld(), 0);

    float CurrentFOV = CameraManager->GetFOVAngle();

    float NewFOV = FMath::Clamp(CurrentFOV + 10.0f, 10.0f, 120.0f);

    CameraManager->SetFOV(NewFOV);

}



void AMyCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)

{
    
    

    Super::SetupPlayerInputComponent(PlayerInputComponent);



    PlayerInputComponent->BindAction("ZoomIn", IE_Pressed, this, &AMyCharacter::ZoomIn);

    PlayerInputComponent->BindAction("ZoomOut", IE_Pressed, this, &AMyCharacter::ZoomOut);

}

3. 摄像机的高级交互

在Unreal Engine中,摄像机的高级交互包括摄像机的跟随、避障、平滑过渡和锁定等。

3.1 摄像机的跟随

摄像机的跟随是指摄像机跟随角色或其他对象的移动。可以通过设置摄像机的位置和旋转来实现跟随。

3.1.1 基本的摄像机跟随

// C++ 代码示例

void AMyCharacter::UpdateCameraLocation()

{
    
    

    // 获取角色的位置

    FVector CharacterLocation = GetActorLocation();

    // 设置摄像机的位置

    APlayerCameraManager* CameraManager = UGameplayStatics::GetPlayerCameraManager(GetWorld(), 0);

    FVector CameraOffset = FVector(-300.0f, 0.0f, 200.0f);

    FVector NewCameraLocation = CharacterLocation + CameraOffset;

    CameraManager->SetCameraLocation(NewCameraLocation);

}



void AMyCharacter::UpdateCameraRotation()

{
    
    

    // 获取角色的旋转

    FRotator CharacterRotation = GetActorRotation();

    // 设置摄像机的旋转

    APlayerCameraManager* CameraManager = UGameplayStatics::GetPlayerCameraManager(GetWorld(), 0);

    CameraManager->SetCameraRotation(CharacterRotation);

}

3.1.2 平滑的摄像机跟随

平滑的摄像机跟随可以通过插值来实现,使摄像机的移动更加自然。


// C++ 代码示例

void AMyCharacter::Tick(float DeltaTime)

{
    
    

    Super::Tick(DeltaTime);



    UpdateCameraLocationSmooth(DeltaTime);

    UpdateCameraRotationSmooth(DeltaTime);

}



void AMyCharacter::UpdateCameraLocationSmooth(float DeltaTime)

{
    
    

    // 获取角色的位置

    FVector CharacterLocation = GetActorLocation();

    // 设置摄像机的目标位置

    FVector CameraOffset = FVector(-300.0f, 0.0f, 200.0f);

    FVector TargetCameraLocation = CharacterLocation + CameraOffset;



    // 获取当前摄像机的位置

    APlayerCameraManager* CameraManager = UGameplayStatics::GetPlayerCameraManager(GetWorld(), 0);

    FVector CurrentCameraLocation = CameraManager->GetCameraLocation();



    // 通过插值平滑移动摄像机

    FVector NewCameraLocation = FMath::VInterpTo(CurrentCameraLocation, TargetCameraLocation, DeltaTime, 10.0f);

    CameraManager->SetCameraLocation(NewCameraLocation);

}



void AMyCharacter::UpdateCameraRotationSmooth(float DeltaTime)

{
    
    

    // 获取角色的旋转

    FRotator CharacterRotation = GetActorRotation();

    // 设置摄像机的目标旋转

    FRotator TargetCameraRotation = CharacterRotation;



    // 获取当前摄像机的旋转

    APlayerCameraManager* CameraManager = UGameplayStatics::GetPlayerCameraManager(GetWorld(), 0);

    FRotator CurrentCameraRotation = CameraManager->GetCameraRotation();



    // 通过插值平滑旋转摄像机

    FRotator NewCameraRotation = FMath::RInterpTo(CurrentCameraRotation, TargetCameraRotation, DeltaTime, 10.0f);

    CameraManager->SetCameraRotation(NewCameraRotation);

}

3.2 摄像机的避障

摄像机的避障是指在摄像机移动时,避免摄像机穿透墙壁或其他障碍物。可以通过检测摄像机与障碍物之间的距离来实现避障。

3.2.1 摄像机避障的实现

// C++ 代码示例

void AMyCharacter::UpdateCameraLocationWithObstacleAvoidance(float DeltaTime)

{
    
    

    // 获取角色的位置

    FVector CharacterLocation = GetActorLocation();

    // 设置摄像机的目标位置

    FVector CameraOffset = FVector(-300.0f, 0.0f, 200.0f);

    FVector TargetCameraLocation = CharacterLocation + CameraOffset;



    // 获取当前摄像机的位置

    APlayerCameraManager* CameraManager = UGameplayStatics::GetPlayerCameraManager(GetWorld(), 0);

    FVector CurrentCameraLocation = CameraManager->GetCameraLocation();



    // 检测摄像机与障碍物之间的距离

    FHitResult HitResult;

    FVector Start = CurrentCameraLocation;

    FVector End = TargetCameraLocation;

    bool bHit = GetWorld()->LineTraceSingleByChannel(HitResult, Start, End, ECC_WorldStatic);



    if (bHit)

    {
    
    

        // 如果检测到障碍物,调整摄像机的位置

        FVector AdjustedCameraOffset = FVector(-200.0f, 0.0f, 200.0f);

        TargetCameraLocation = CharacterLocation + AdjustedCameraOffset;

    }



    // 通过插值平滑移动摄像机

    FVector NewCameraLocation = FMath::VInterpTo(CurrentCameraLocation, TargetCameraLocation, DeltaTime, 10.0f);

    CameraManager->SetCameraLocation(NewCameraLocation);

}

3.3 摄像机的平滑过渡

摄像机的平滑过渡是指在摄像机状态之间进行平滑切换,例如在不同视角之间切换。可以通过插值来实现平滑过渡。

3.3.1 摄像机平滑过渡的实现

// C++ 代码示例

void AMyCharacter::SwitchToFirstPerson()

{
    
    

    bIsFirstPerson = true;

    bIsTransitioning = true;

    FirstPersonTargetLocation = GetActorLocation() + FVector(0.0f, 0.0f, 200.0f);

}



void AMyCharacter::SwitchToThirdPerson()

{
    
    

    bIsFirstPerson = false;

    bIsTransitioning = true;

    ThirdPersonTargetLocation = GetActorLocation() + FVector(-300.0f, 0.0f, 200.0f);

}



void AMyCharacter::Tick(float DeltaTime)

{
    
    

    Super::Tick(DeltaTime);



    if (bIsTransitioning)

    {
    
    

        UpdateCameraLocationDuringTransition(DeltaTime);

    }

    else

    {
    
    

        UpdateCameraLocationWithObstacleAvoidance(DeltaTime);

    }

}



void AMyCharacter::UpdateCameraLocationDuringTransition(float DeltaTime)

{
    
    

    APlayerCameraManager* CameraManager = UGameplayStatics::GetPlayerCameraManager(GetWorld(), 0);

    FVector CurrentCameraLocation = CameraManager->GetCameraLocation();



    FVector TargetLocation = bIsFirstPerson ? FirstPersonTargetLocation : ThirdPersonTargetLocation;



    FVector NewCameraLocation = FMath::VInterpTo(CurrentCameraLocation, TargetLocation, DeltaTime, 10.0f);

    CameraManager->SetCameraLocation(NewCameraLocation);



    float Distance = (TargetLocation - CurrentCameraLocation).Size();

    if (Distance < 10.0f)

    {
    
    

        bIsTransitioning = false;

    }

}

3.4 摄像机的锁定

摄像机的锁定是指在特定情况下锁定摄像机的某些属性,例如在过场动画中锁定摄像机的旋转。

3.4.1 摄像机锁定的实现

// C++ 代码示例

void AMyCharacter::LockCamera()

{
    
    

    bIsCameraLocked = true;

}



void AMyCharacter::UnlockCamera()

{
    
    

    bIsCameraLocked = false;

}



void AMyCharacter::Turn(float Value)

{
    
    

    if (Value != 0.0f && !bIsCameraLocked)

    {
    
    

        // 以输入值旋转角色

        AddControllerYawInput(Value);

    }

}



void AMyCharacter::LookUp(float Value)

{
    
    

    if (Value != 0.0f && !bIsCameraLocked)

    {
    
    

        // 以输入值旋转角色

        AddControllerPitchInput(Value);

    }

}

4. 摄像机的交互设计模式

在Unreal Engine中,摄像机的交互设计模式可以分为几种常见的类型,每种类型适用于不同的游戏场景。理解这些设计模式有助于开发者根据游戏需求选择合适的摄像机控制方式。

4.1 第一人称摄像机

第一人称摄像机(First-Person Camera)是指摄像机位于角色的视野位置,玩家通过摄像机的视角直接看到角色的前方。这种摄像机模式适用于射击游戏、冒险游戏等。

4.1.1 第一人称摄像机的实现

// C++ 代码示例

void AMyCharacter::BeginPlay()

{
    
    

    Super::BeginPlay();



    // 初始化摄像机

    if (FirstPersonCamera)

    {
    
    

        FirstPersonCamera->SetRelativeLocation(FVector(0.0f, 0.0f, 100.0f));

    }

}



void AMyCharacter::Tick(float DeltaTime)

{
    
    

    Super::Tick(DeltaTime);



    if (bIsFirstPerson)

    {
    
    

        UpdateFirstPersonCamera(DeltaTime);

    }

    else

    {
    
    

        UpdateCameraLocationWithObstacleAvoidance(DeltaTime);

    }

}



void AMyCharacter::UpdateFirstPersonCamera(float DeltaTime)

{
    
    

    // 获取角色的位置

    FVector CharacterLocation = GetActorLocation();

    // 设置摄像机的位置

    APlayerCameraManager* CameraManager = UGameplayStatics::GetPlayerCameraManager(GetWorld(), 0);

    FVector CameraOffset = FVector(0.0f, 0.0f, 100.0f);

    FVector NewCameraLocation = CharacterLocation + CameraOffset;

    CameraManager->SetCameraLocation(NewCameraLocation);



    // 设置摄像机的旋转

    FRotator NewCameraRotation = GetActorRotation();

    CameraManager->SetCameraRotation(NewCameraRotation);

}



void AMyCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)

{
    
    

    Super::SetupPlayerInputComponent(PlayerInputComponent);



    PlayerInputComponent->BindAxis("MoveForward", this, &AMyCharacter::MoveForward);

    PlayerInputComponent->BindAxis("MoveRight", this, &AMyCharacter::MoveRight);

    PlayerInputComponent->BindAxis("Turn", this, &AMyCharacter::Turn);

    PlayerInputComponent->BindAxis("LookUp", this, &AMyCharacter::LookUp);



    PlayerInputComponent->BindAction("SwitchCamera", IE_Pressed, this, &AMyCharacter::SwitchCamera);

}



void AMyCharacter::SwitchCamera()

{
    
    

    bIsFirstPerson = !bIsFirstPerson;

    if (bIsFirstPerson)

    {
    
    

        SwitchToFirstPerson();

    }

    else

    {
    
    

        SwitchToThirdPerson();

    }

}

4.2 第三人称摄像机

第三人称摄像机(Third-Person Camera)是指摄像机位于角色的后方或侧面,玩家通过摄像机的视角看到角色。这种摄像机模式适用于动作游戏、角色扮演游戏等。

4.2.1 第三人称摄像机的实现

// C++ 代码示例

void AMyCharacter::SwitchToThirdPerson()

{
    
    

    bIsFirstPerson = false;

    bIsTransitioning = true;

    ThirdPersonTargetLocation = GetActorLocation() + FVector(-300.0f, 0.0f, 200.0f);

}



void AMyCharacter::UpdateThirdPersonCamera(float DeltaTime)

{
    
    

    // 获取角色的位置

    FVector CharacterLocation = GetActorLocation();

    // 设置摄像机的位置

    APlayerCameraManager* CameraManager = UGameplayStatics::GetPlayerCameraManager(GetWorld(), 0);

    FVector CameraOffset = FVector(-300.0f, 0.0f, 200.0f);

    FVector NewCameraLocation = CharacterLocation + CameraOffset;

    CameraManager->SetCameraLocation(NewCameraLocation);



    // 设置摄像机的旋转

    FRotator NewCameraRotation = GetActorRotation();

    CameraManager->SetCameraRotation(NewCameraRotation);

}



void AMyCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)

{
    
    

    Super::SetupPlayerInputComponent(PlayerInputComponent);



    PlayerInputComponent->BindAxis("MoveForward", this, &AMyCharacter::MoveForward);

    PlayerInputComponent->BindAxis("MoveRight", this, &AMyCharacter::MoveRight);

    PlayerInputComponent->BindAxis("Turn", this, &AMyCharacter::Turn);

    PlayerInputComponent->BindAxis("LookUp", this, &AMyCharacter::LookUp);



    PlayerInputComponent->BindAction("SwitchCamera", IE_Pressed, this, &AMyCharacter::SwitchCamera);

}

4.3 过场动画摄像机

过场动画摄像机(Cinematic Camera)是指在特定的过场动画或剧情场景中使用的摄像机。这种摄像机模式通常需要锁定摄像机的某些属性,以确保动画的流畅和一致性。

4.3.1 过场动画摄像机的实现

// C++ 代码示例

void AMyCharacter::PlayCinematicCamera()

{
    
    

    bIsCinematic = true;

    LockCamera();



    // 开始过场动画

    UCameraComponent* CinematicCamera = GetCinematicCamera();

    if (CinematicCamera)

    {
    
    

        CinematicCamera->Activate();

    }

}



void AMyCharacter::EndCinematicCamera()

{
    
    

    bIsCinematic = false;

    UnlockCamera();



    // 结束过场动画

    UCameraComponent* CinematicCamera = GetCinematicCamera();

    if (CinematicCamera)

    {
    
    

        CinematicCamera->Deactivate();

    }

}



void AMyCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)

{
    
    

    Super::SetupPlayerInputComponent(PlayerInputComponent);



    PlayerInputComponent->BindAxis("MoveForward", this, &AMyCharacter::MoveForward);

    PlayerInputComponent->BindAxis("MoveRight", this, &AMyCharacter::MoveRight);

    PlayerInputComponent->BindAxis("Turn", this, &AMyCharacter::Turn);

    PlayerInputComponent->BindAxis("LookUp", this, &AMyCharacter::LookUp);



    PlayerInputComponent->BindAction("PlayCinematic", IE_Pressed, this, &AMyCharacter::PlayCinematicCamera);

    PlayerInputComponent->BindAction("EndCinematic", IE_Pressed, this, &AMyCharacter::EndCinematicCamera);

}



UCameraComponent* AMyCharacter::GetCinematicCamera() const

{
    
    

    // 返回过场动画摄像机组件

    return CinematicCamera;

}

4.4 自由摄像机

自由摄像机(Free Camera)是指摄像机可以自由地在场景中移动,不受角色或其他对象的限制。这种摄像机模式适用于探索游戏、模拟游戏等。

4.4.1 自由摄像机的实现

// C++ 代码示例

void AMyCharacter::SwitchToFreeCamera()

{
    
    

    bIsFreeCamera = true;

}



void AMyCharacter::SwitchToCharacterCamera()

{
    
    

    bIsFreeCamera = false;

}



void AMyCharacter::UpdateFreeCamera(float DeltaTime)

{
    
    

    // 获取当前输入

    float MoveForwardValue = GetInputAxisValue("MoveForward");

    float MoveRightValue = GetInputAxisValue("MoveRight");

    float TurnValue = GetInputAxisValue("Turn");

    float LookUpValue = GetInputAxisValue("LookUp");



    // 获取摄像机的位置和旋转

    APlayerCameraManager* CameraManager = UGameplayStatics::GetPlayerCameraManager(GetWorld(), 0);

    FVector CurrentCameraLocation = CameraManager->GetCameraLocation();

    FRotator CurrentCameraRotation = CameraManager->GetCameraRotation();



    // 计算新的位置和旋转

    FVector ForwardVector = CurrentCameraRotation.Vector();

    FVector RightVector = FVector::CrossProduct(ForwardVector, FVector::UpVector);

    FVector NewLocation = CurrentCameraLocation + ForwardVector * MoveForwardValue * CameraSpeed * DeltaTime + RightVector * MoveRightValue * CameraSpeed * DeltaTime;

    FRotator NewRotation = CurrentCameraRotation + FRotator(0.0f, TurnValue * CameraTurnSpeed * DeltaTime, 0.0f) + FRotator(LookUpValue * CameraLookUpSpeed * DeltaTime, 0.0f, 0.0f);



    // 设置新的位置和旋转

    CameraManager->SetCameraLocation(NewLocation);

    CameraManager->SetCameraRotation(NewRotation);

}



void AMyCharacter::Tick(float DeltaTime)

{
    
    

    Super::Tick(DeltaTime);



    if (bIsFreeCamera)

    {
    
    

        UpdateFreeCamera(DeltaTime);

    }

    else if (bIsFirstPerson)

    {
    
    

        UpdateFirstPersonCamera(DeltaTime);

    }

    else

    {
    
    

        UpdateCameraLocationWithObstacleAvoidance(DeltaTime);

    }

}



void AMyCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)

{
    
    

    Super::SetupPlayerInputComponent(PlayerInputComponent);



    PlayerInputComponent->BindAxis("MoveForward", this, &AMyCharacter::MoveForward);

    PlayerInputComponent->BindAxis("MoveRight", this, &AMyCharacter::MoveRight);

    PlayerInputComponent->BindAxis("Turn", this, &AMyCharacter::Turn);

    PlayerInputComponent->BindAxis("LookUp", this, &AMyCharacter::LookUp);



    PlayerInputComponent->BindAction("SwitchCamera", IE_Pressed, this, &AMyCharacter::SwitchCamera);

    PlayerInputComponent->BindAction("SwitchToFreeCamera", IE_Pressed, this, &AMyCharacter::SwitchToFreeCamera);

    PlayerInputComponent->BindAction("SwitchToCharacterCamera", IE_Pressed, this, &AMyCharacter::SwitchToCharacterCamera);

}

5. 摄像机的调试与优化

在Unreal Engine中,摄像机的调试与优化是非常重要的步骤,确保摄像机的行为符合玩家的预期,同时提高游戏的性能。

5.1 摄像机的调试

调试摄像机的行为可以通过多种方式进行,例如使用蓝图的事件图表、C++中的日志输出和调试视图等。

5.1.1 使用蓝图调试

在蓝图中,可以使用Print String节点来输出摄像机的位置、旋转和视野等信息,帮助开发者调试摄像机的行为。


// 蓝图节点示例

Event Tick

{

    CameraManager = GetPlayerCameraManager()

    CameraLocation = CameraManager.GetCameraLocation()

    CameraRotation = CameraManager.GetCameraRotation()

    CameraFOV = CameraManager.GetFOVAngle()



    Print String("Camera Location: " + CameraLocation.ToString())

    Print String("Camera Rotation: " + CameraRotation.ToString())

    Print String("Camera FOV: " + CameraFOV.ToString())

}

5.1.2 使用C++调试

在C++中,可以使用UE_LOG宏来输出摄像机的相关信息。


// C++ 代码示例

#include "Engine/World.h"

#include "GameFramework/PlayerCameraManager.h"

#include "Engine/Engine.h"



void AMyCharacter::Tick(float DeltaTime)

{
    
    

    Super::Tick(DeltaTime);



    // 获取摄像机的位置、旋转和视野

    APlayerCameraManager* CameraManager = UGameplayStatics::GetPlayerCameraManager(GetWorld(), 0);

    FVector CameraLocation = CameraManager->GetCameraLocation();

    FRotator CameraRotation = CameraManager->GetCameraRotation();

    float CameraFOV = CameraManager->GetFOVAngle();



    // 输出调试信息

    UE_LOG(LogTemp, Log, TEXT("Camera Location: %s"), *CameraLocation.ToString());

    UE_LOG(LogTemp, Log, TEXT("Camera Rotation: %s"), *CameraRotation.ToString());

    UE_LOG(LogTemp, Log, TEXT("Camera FOV: %f"), CameraFOV);

}

5.2 摄像机的优化

优化摄像机的行为可以提高游戏的性能和玩家的体验。常见的优化方法包括减少摄像机的更新频率、使用缓存和预计算等。

5.2.1 减少摄像机的更新频率

通过减少摄像机的更新频率,可以降低对性能的影响。例如,可以每几帧更新一次摄像机的位置和旋转。


// C++ 代码示例

void AMyCharacter::BeginPlay()

{
    
    

    Super::BeginPlay();



    // 设置更新频率

    UpdateFrequency = 0.1f; // 每0.1秒更新一次

    LastUpdateTime = 0.0f;

}



void AMyCharacter::Tick(float DeltaTime)

{
    
    

    Super::Tick(DeltaTime);



    // 检查是否需要更新摄像机

    float CurrentTime = GetWorld()->GetTimeSeconds();

    if (CurrentTime - LastUpdateTime >= UpdateFrequency)

    {
    
    

        LastUpdateTime = CurrentTime;



        if (bIsFirstPerson)

        {
    
    

            UpdateFirstPersonCamera(DeltaTime);

        }

        else if (bIsFreeCamera)

        {
    
    

            UpdateFreeCamera(DeltaTime);

        }

        else

        {
    
    

            UpdateCameraLocationWithObstacleAvoidance(DeltaTime);

        }

    }

}

5.2.2 使用缓存和预计算

通过使用缓存和预计算,可以减少每次更新时的计算量,从而提高性能。


// C++ 代码示例

void AMyCharacter::BeginPlay()

{
    
    

    Super::BeginPlay();



    // 缓存角色的初始位置和旋转

    InitialCharacterLocation = GetActorLocation();

    InitialCharacterRotation = GetActorRotation();

}



void AMyCharacter::UpdateFreeCamera(float DeltaTime)

{
    
    

    // 获取当前输入

    float MoveForwardValue = GetInputAxisValue("MoveForward");

    float MoveRightValue = GetInputAxisValue("MoveRight");

    float TurnValue = GetInputAxisValue("Turn");

    float LookUpValue = GetInputAxisValue("LookUp");



    // 使用缓存的位置和旋转

    FVector CurrentCameraLocation = CachedCameraLocation;

    FRotator CurrentCameraRotation = CachedCameraRotation;



    // 计算新的位置和旋转

    FVector ForwardVector = CurrentCameraRotation.Vector();

    FVector RightVector = FVector::CrossProduct(ForwardVector, FVector::UpVector);

    FVector NewLocation = CurrentCameraLocation + ForwardVector * MoveForwardValue * CameraSpeed * DeltaTime + RightVector * MoveRightValue * CameraSpeed * DeltaTime;

    FRotator NewRotation = CurrentCameraRotation + FRotator(0.0f, TurnValue * CameraTurnSpeed * DeltaTime, 0.0f) + FRotator(LookUpValue * CameraLookUpSpeed * DeltaTime, 0.0f, 0.0f);



    // 设置新的位置和旋转

    APlayerCameraManager* CameraManager = UGameplayStatics::GetPlayerCameraManager(GetWorld(), 0);

    CameraManager->SetCameraLocation(NewLocation);

    CameraManager->SetCameraRotation(NewRotation);



    // 更新缓存

    CachedCameraLocation = NewLocation;

    CachedCameraRotation = NewRotation;

}

6. 总结

虚拟摄像机的交互设计是Unreal Engine中非常重要的一个方面。通过理解摄像机的基本属性和控制方式,开发者可以设计出高效、自然的摄像机交互。同时,高级交互如摄像机的跟随、避障、平滑过渡和锁定等,可以进一步提升游戏的体验。最后,调试和优化摄像机的行为可以确保游戏的性能和稳定性。希望本文能帮助开发者更好地掌握虚拟摄像机的交互设计。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/chenlz2007/article/details/147031672