YoYo_db1212 2025-07-18 22:54 采纳率: 0%
浏览 7

UE 如何使用手柄控制电影摄影机组件?

在UE建立了一个电影相机实例,实例中的scenecomponent组件的位置、旋转、缩放读取的是位置传感器freed数据,可以实现真实摄像机摇动时场景跟着动,这个已经实现了。
但是,我现在需要调整摄影机实例出现的初始位置(或者说需要调整scenecomponent组件下一层的Cameracomponent组件的位置、旋转、缩放来实现)。我想用手柄来控制Cameracomponent组件的位置、旋转、缩放,目前已经在项目设置里映射了手柄键位,但是不知道怎么关联到Cameracomponent组件的位置、旋转、缩放上来,还不影响上一层通过freed的控制。

img

img

  • 写回答

5条回答 默认 最新

  • 檀越@新空间 2025-07-18 22:55
    关注

    晚上好🌙🌙🌙
    本答案参考通义千问

    在Unreal Engine(UE)中,如果你已经通过 Freed 传感器控制了 SceneComponent 的位置、旋转和缩放,并且现在希望额外用手柄控制 CameraComponent 的位置、旋转和缩放,同时不影响 SceneComponent 的控制逻辑,可以通过以下方式实现。


    ✅ 问题分析

    • SceneComponent 是父级组件,它由 Freed 控制;
    • CameraComponentSceneComponent 的子组件;
    • 你希望通过手柄控制 CameraComponent 的位置、旋转、缩放;
    • 要求:不干扰 SceneComponent 的控制逻辑

    🛠 解决方案

    1. 创建自定义蓝图或C++类来处理手柄输入

    你可以创建一个蓝图类(如 CameraController),用于接收手柄输入并修改 CameraComponent 的属性。

    ✅ 步骤:

    1. 创建一个新的蓝图类,继承自 ActorCharacter(根据你的需求选择)。
    2. 在蓝图中添加 CameraComponent 作为子组件(如果还没有)。
    3. 添加 Input Mapping(已经在项目设置中完成)。
    4. 编写事件图表逻辑,根据手柄输入调整 CameraComponent 的位置、旋转等。

    2. 使用蓝图节点控制 CameraComponent

    ✅ 示例蓝图逻辑(事件图表):

    Event Tick
       |
       +-- Get Player Controller (或者直接获取 CameraComponent)
       |
       +-- Get Input Axis Value (例如 "MoveX", "MoveY", "Rotate")
       |
       +-- Calculate movement based on input
       |
       +-- Set World Location of CameraComponent (偏移)
       |
       +-- Set World Rotation of CameraComponent (旋转)
       |
       +-- Set Relative Scale3D of CameraComponent (缩放)
    

    注意: 使用 Set World LocationSet World Rotation 会直接改变组件的世界坐标,而 Set Relative Location 则是相对于父组件的局部坐标。根据你的需求选择合适的方式。


    3. C++ 实现(可选)

    如果你更喜欢用 C++ 来实现,可以创建一个 Actor 类,并在 Tick 函数中处理输入。

    ✅ 示例代码(C++):

    // MyCameraController.h
    #pragma once
    
    #include "CoreMinimal.h"
    #include "GameFramework/Actor.h"
    #include "MyCameraController.generated.h"
    
    UCLASS()
    class MYPROJECT_API AMyCameraController : public AActor
    {
        GENERATED_BODY()
    
    public:
        // Sets default values for this actor's properties
        AMyCameraController();
    
    protected:
        // Called when the game starts or when spawned
        virtual void BeginPlay() override;
    
        // Called every frame
        virtual void Tick(float DeltaTime) override;
    
    public:
        UPROPERTY(EditAnywhere, Category = "Camera")
        UCameraComponent* CameraComponent;
    
        float MoveSpeed = 100.0f;
        float RotateSpeed = 50.0f;
    };
    
    // MyCameraController.cpp
    #include "MyCameraController.h"
    #include "GameFramework/PlayerController.h"
    #include "Kismet/GameplayStatics.h"
    
    AMyCameraController::AMyCameraController()
    {
        PrimaryActorTick.bCanEverTick = true;
    }
    
    void AMyCameraController::BeginPlay()
    {
        Super::BeginPlay();
        
        // 确保 CameraComponent 已经初始化
        if (!CameraComponent)
        {
            CameraComponent = FindComponentByClass<UCameraComponent>();
        }
    }
    
    void AMyCameraController::Tick(float DeltaTime)
    {
        Super::Tick(DeltaTime);
    
        // 获取玩家控制器
        APlayerController* PlayerController = UGameplayStatics::GetPlayerController(this, 0);
        if (!PlayerController)
            return;
    
        // 获取手柄输入
        float MoveX = PlayerController->GetAxisValue("MoveX");
        float MoveY = PlayerController->GetAxisValue("MoveY");
        float Rotate = PlayerController->GetAxisValue("Rotate");
    
        // 移动相机
        FVector NewLocation = CameraComponent->GetComponentLocation() + 
                              (PlayerController->GetControlRotation().Vector() * MoveX * MoveSpeed * DeltaTime) +
                              (PlayerController->GetControlRotation().RightVector() * MoveY * MoveSpeed * DeltaTime);
        CameraComponent->SetWorldLocation(NewLocation);
    
        // 旋转相机
        FRotator NewRotation = CameraComponent->GetComponentRotation() + 
                               FRotator(0, Rotate * RotateSpeed * DeltaTime, 0);
        CameraComponent->SetWorldRotation(NewRotation);
    }
    

    注意: 你需要在项目设置中确保手柄键位映射正确(如 "MoveX", "MoveY", "Rotate")。


    4. 将控制器与场景绑定

    • 在编辑器中,将你的 MyCameraController 放入场景中;
    • 确保 CameraComponent 已经被正确附加到该控制器上;
    • 运行游戏后,手柄输入将只影响 CameraComponent,不会影响 SceneComponent 的控制。

    ✅ 总结:关键步骤

    1. 创建一个独立的控制器类(蓝图或C++),用于控制 CameraComponent
    2. 在 Tick 中读取手柄输入,并据此调整 CameraComponent 的位置、旋转、缩放。
    3. 确保不干扰 SceneComponent 的控制逻辑,避免冲突。
    4. 测试并调试,确保手柄控制与 Freed 控制互不干扰。

    📌 注意事项

    • 如果你使用的是 Movie Camera,请确保你操作的是其内部的 Camera Component,而不是整个 Movie Camera 的 Transform。
    • 若需要更精细的控制,可以考虑使用 Blueprint GraphC++ 结合 Input Axis Mappings 实现。

    如果你有具体的蓝图结构或代码片段,我可以进一步帮你优化和定制逻辑。

    评论

报告相同问题?

问题事件

  • 创建了问题 7月18日