当前位置: 首页 > news >正文

UE4中的相机操控方案

UE4中的相机操控方案

https://blog.csdn.net/qq_33747722/article/details/81193894

 

在UE4中的相机操控方案可能会比U3D中的方式要稍微麻烦一点点,今天分享下UE4中相机的几种操控方式

在本文之前先创建一个继承自GameModeBase和一个继承自APawn类,在这里博主分别命名为CameraGameModeBase、CameraCharacter

在CameraGameModeBase构造函数里将CameraCharacter设置为默认Apawn,代码如下:

DefaultPawnClass = ACameraCharacter::StaticClass();

在CameraCharacter中重写SetupPlayerInputComponent函数,用于绑定本文需要绑定的操控输入事件

    // 调用绑定输入事件
    void ACameraCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
    {
        Super::SetupPlayerInputComponent(PlayerInputComponent);
     
        //向上滚轮
        UPlayerInput::AddEngineDefinedAxisMapping(FInputAxisKeyMapping("ScrollWheelUp", EKeys::MouseWheelAxis, 10));
        PlayerInputComponent->BindAxis("ScrollWheelUp", this, &ACameraCharacter::OnScrollWheelUpPress);
     
        //鼠标右键
        UPlayerInput::AddEngineDefinedAxisMapping(FInputAxisKeyMapping("MouseRightDrag", EKeys::RightMouseButton, 10));
        PlayerInputComponent->BindAxis("MouseRightDrag", this, &ACameraCharacter::OnMouseRightDrag);
     
        //键盘Shift键
        UPlayerInput::AddEngineDefinedActionMapping(FInputActionKeyMapping("KeyLeftShift", EKeys::LeftShift));
        PlayerInputComponent->BindAction("KeyLeftShift", IE_Pressed, this, &ACameraCharacter::OnKeyLeftShiftPress);
        PlayerInputComponent->BindAction("KeyLeftShift", IE_Released, this, &ACameraCharacter::OnKeyLeftShiftReleased);
     
        //鼠标位置(X,Y方向)
        UPlayerInput::AddEngineDefinedAxisMapping(FInputAxisKeyMapping("Turn", EKeys::MouseX, 1.0f));
        PlayerInputComponent->BindAxis("Turn", this, &ACameraCharacter::OnTurn);
        UPlayerInput::AddEngineDefinedAxisMapping(FInputAxisKeyMapping("LookAtRotate", EKeys::MouseY, 1.0f));
        PlayerInputComponent->BindAxis("LookAtRotate", this, &ACameraCharacter::OnLookAtRotate);
    }

有了前面的基础,博主要带领大家实现相机的三种操控方案

1.滚动鼠标滑轮,移动相机到鼠标点位置

需要跟随鼠标点移动的话,需要通过当前鼠标点的位置获取到一个世界坐标位置,UE4提供了这个方法,代码如下:

UGameplayStatics::DeprojectScreenToWorld(UGameplayStatics::GetPlayerController(GWorld, 0), CursorPos, WorldPos, MoveDirction);

第一个参数是指指定的的控制器

第二个参数是指当前鼠标位置

第三第四个参数是指引用返回世界位置点与鼠标点指向的世界方向射线(就是我们需要获取到的移动方向)

有了这个移动方向后,我们只需要在世界空间下,移动摄像机在世界空间下的方位就好了,这一功能代码如下:

    //滚动滑轮
    void ACameraCharacter::OnScrollWheelUpPress(float axisValue)
    {
        FVector2D CursorPos;
        FVector WorldPos;
        FVector MoveDirction = FVector::ZeroVector;
     
        if (FMath::Abs(axisValue) > KINDA_SMALL_NUMBER)
        {
            GetWorld()->GetFirstPlayerController()->GetMousePosition(CursorPos.X, CursorPos.Y);
            UGameplayStatics::DeprojectScreenToWorld(UGameplayStatics::GetPlayerController(GWorld, 0), CursorPos, WorldPos, MoveDirction);
        }
     
        ViewCamera->AddWorldOffset(MoveDirction*ScrollWheelSpeed*axisValue);
    }

2.按住Shift键,拖拽鼠标右键平移视野

通过当前帧鼠标在屏幕下的位置减去前一帧的鼠标位置得到一个位置向量

通过这个比例改变摄像机自身坐标系中的X,Y轴坐标 ,代码如下:

    //计算在屏幕中的MoveOffset(前一个鼠标点到当前鼠标点的向量)
    void ACameraCharacter::CalcCameraMoveDrogDirction()
    {
        if (FMath::Abs(FVector2D::Distance(FontCurorPos, CurrentCurcorPos)) < KINDA_SMALL_NUMBER)
        {
            GetWorld()->GetFirstPlayerController()->GetMousePosition(FontCurorPos.X, FontCurorPos.Y);
        }
        else
        {
            GetWorld()->GetFirstPlayerController()->GetMousePosition(CurrentCurcorPos.X, CurrentCurcorPos.Y);
            FVector2D MoveOffset = CurrentCurcorPos - FontCurorPos;
     
            FontCurorPos = CurrentCurcorPos;
     
            ViewCamera->AddLocalOffset(FVector(0, -MoveOffset.X, MoveOffset.Y));
        }
    }

3.按住鼠标右键,移动鼠标绕点旋转

实现这个操作可以让我们的CameraCharacter绑定一个弹簧手臂,然后再弹簧手臂上添加我们的摄像机

这样我们可以通过改变控制器的旋转进而带动摄像机手臂以及摄像机达到旋转的目的

绑定弹簧手臂方法如下

    // Sets default values
    ACameraCharacter::ACameraCharacter()
    {
        // Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
        PrimaryActorTick.bCanEverTick = true;
     
        RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("SceneComponent"));
     
        /*创建弹簧手臂和摄像机*/
         CameraSpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraSpringArm"));
         CameraSpringArm->SetupAttachment(RootComponent);
         CameraSpringArm->TargetArmLength = 500.f;
         CameraSpringArm->TargetOffset = FVector(100.f, 100.f, 100.f);
         CameraSpringArm->bUsePawnControlRotation = true;
        CameraSpringArm->SetWorldLocation(FVector::ZeroVector);
        
        //初始化摄像机
        ViewCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("ViewCamera"));
        ViewCamera->SetupAttachment(CameraSpringArm, USpringArmComponent::SocketName);
        ViewCamera->bUsePawnControlRotation = false;
        ViewCamera->SetActive(true);
    }

然后我们移动鼠标右键代码如下:

    void ACameraCharacter::OnTurn(float axisValue)
    {
        if (!IsRotateCameraState) return;
        if (IsRotateCameraState&&FMath::Abs(axisValue) > KINDA_SMALL_NUMBER)
        {
            AddControllerYawInput(-axisValue);
        }
    }
     
    void ACameraCharacter::OnLookAtRotate(float axisValue)
    {
        if (!IsRotateCameraState) return;
        if (IsRotateCameraState && FMath::Abs(axisValue) > KINDA_SMALL_NUMBER)
        {
            AddControllerPitchInput(-axisValue);
        }
    }

最后给大家贴出这个案例的完整代码:

    // Fill out your copyright notice in the Description page of Project Settings.
     
    #include "SCTCameraCharacter.h"
    #include "Camera/CameraComponent.h"
    #include "GameFramework/SpringArmComponent.h"
    #include "GameFramework/PlayerInput.h"
    #include "Kismet/GameplayStatics.h"
    #include "UnrealMathUtility.h"
    #include "Engine/Engine.h"
    #include "GameFramework/Controller.h"
    #include "GameFramework/Character.h"
    #include "Components/CapsuleComponent.h"
     
    // Sets default values
    ACameraCharacter::ACameraCharacter()
    {
        // Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
        PrimaryActorTick.bCanEverTick = true;
     
        RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("SceneComponent"));
     
        /*创建弹簧手臂和摄像机*/
         CameraSpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraSpringArm"));
         CameraSpringArm->SetupAttachment(RootComponent);
         CameraSpringArm->TargetArmLength = 500.f;
         CameraSpringArm->TargetOffset = FVector(100.f, 100.f, 100.f);
         CameraSpringArm->bUsePawnControlRotation = true;
        CameraSpringArm->SetWorldLocation(FVector::ZeroVector);
        
        //初始化摄像机
        ViewCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("ViewCamera"));
        ViewCamera->SetupAttachment(CameraSpringArm, USpringArmComponent::SocketName);
        ViewCamera->bUsePawnControlRotation = false;
        ViewCamera->SetActive(true);
    }
     
    // Called when the game starts or when spawned
    void ACameraCharacter::BeginPlay()
    {
        Super::BeginPlay();
     
        //初始化变量
        ScrollWheelSpeed = 2;
     
        CurrentCurcorPos = FontCurorPos = FVector2D::ZeroVector;
     
        IsBindShiftKey = false;
     
        IsRotateCameraState = false;
        IsMoveCameraState = false;
     
        FInputModeGameAndUI InputMode;
        InputMode.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock);
        InputMode.SetHideCursorDuringCapture(false);
        UGameplayStatics::GetPlayerController(GWorld, 0)->SetInputMode(InputMode);
     
        UGameplayStatics::GetPlayerController(GWorld, 0)->bShowMouseCursor = 1;
    }
     
    void ACameraCharacter::Tick(float DeltaTime)
    {
        Super::Tick(DeltaTime);
     
        if (IsMoveCameraState)
        {
            CalcCameraMoveDrogDirction();
        }
    }
     
    // 调用绑定输入事件
    void ACameraCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
    {
        Super::SetupPlayerInputComponent(PlayerInputComponent);
     
        //向上滚轮
        UPlayerInput::AddEngineDefinedAxisMapping(FInputAxisKeyMapping("ScrollWheelUp", EKeys::MouseWheelAxis, 10));
        PlayerInputComponent->BindAxis("ScrollWheelUp", this, &ACameraCharacter::OnScrollWheelUpPress);
     
        //鼠标右键
        UPlayerInput::AddEngineDefinedAxisMapping(FInputAxisKeyMapping("MouseRightDrag", EKeys::RightMouseButton, 10));
        PlayerInputComponent->BindAxis("MouseRightDrag", this, &ACameraCharacter::OnMouseRightDrag);
     
        //键盘Shift键
        UPlayerInput::AddEngineDefinedActionMapping(FInputActionKeyMapping("KeyLeftShift", EKeys::LeftShift));
        PlayerInputComponent->BindAction("KeyLeftShift", IE_Pressed, this, &ACameraCharacter::OnKeyLeftShiftPress);
        PlayerInputComponent->BindAction("KeyLeftShift", IE_Released, this, &ACameraCharacter::OnKeyLeftShiftReleased);
     
        //鼠标位置(X,Y方向)
        UPlayerInput::AddEngineDefinedAxisMapping(FInputAxisKeyMapping("Turn", EKeys::MouseX, 1.0f));
        PlayerInputComponent->BindAxis("Turn", this, &ACameraCharacter::OnTurn);
        UPlayerInput::AddEngineDefinedAxisMapping(FInputAxisKeyMapping("LookAtRotate", EKeys::MouseY, 1.0f));
        PlayerInputComponent->BindAxis("LookAtRotate", this, &ACameraCharacter::OnLookAtRotate);
    }
     
    //滚动滑轮
    void ACameraCharacter::OnScrollWheelUpPress(float axisValue)
    {
        FVector2D CursorPos;
        FVector WorldPos;
        FVector MoveDirction = FVector::ZeroVector;
     
        if (FMath::Abs(axisValue) > KINDA_SMALL_NUMBER)
        {
            GetWorld()->GetFirstPlayerController()->GetMousePosition(CursorPos.X, CursorPos.Y);
            UGameplayStatics::DeprojectScreenToWorld(UGameplayStatics::GetPlayerController(GWorld, 0), CursorPos, WorldPos, MoveDirction);
        }
     
        ViewCamera->AddWorldOffset(MoveDirction*ScrollWheelSpeed*axisValue);
    }
     
    //鼠标右键拖拽
    void ACameraCharacter::OnMouseRightDrag(float axisValue)
    {
        if (FMath::Abs(axisValue) < KINDA_SMALL_NUMBER)
        {
            CurrentCurcorPos = FontCurorPos = FVector2D::ZeroVector;
            IsRotateCameraState = false;
            IsMoveCameraState = false;
        }
        else
        {
            //按下左shift键,开始拖拽
            if (IsBindShiftKey)
            {
                //拖拽状态
                IsMoveCameraState = true;
            }
            //没有按下左Shift键时候绕鼠标点旋转
            else
            {
                IsRotateCameraState = true;
            }
        }
    }
     
    //计算在屏幕中的MoveOffset(前一个鼠标点到当前鼠标点的向量)
    void ACameraCharacter::CalcCameraMoveDrogDirction()
    {
        if (FMath::Abs(FVector2D::Distance(FontCurorPos, CurrentCurcorPos)) < KINDA_SMALL_NUMBER)
        {
            GetWorld()->GetFirstPlayerController()->GetMousePosition(FontCurorPos.X, FontCurorPos.Y);
        }
        else
        {
            GetWorld()->GetFirstPlayerController()->GetMousePosition(CurrentCurcorPos.X, CurrentCurcorPos.Y);
            FVector2D MoveOffset = CurrentCurcorPos - FontCurorPos;
     
            FontCurorPos = CurrentCurcorPos;
     
            ViewCamera->AddLocalOffset(FVector(0, -MoveOffset.X, MoveOffset.Y));
        }
    }
     
    void ACameraCharacter::OnKeyLeftShiftPress()
    {
        IsBindShiftKey = true;
    }
     
    void ACameraCharacter::OnKeyLeftShiftReleased()
    {
        IsBindShiftKey = false;
    }
     
    void ACameraCharacter::OnTurn(float axisValue)
    {
        if (!IsRotateCameraState) return;
        if (IsRotateCameraState&&FMath::Abs(axisValue) > KINDA_SMALL_NUMBER)
        {
            AddControllerYawInput(-axisValue);
        }
    }
     
    void ACameraCharacter::OnLookAtRotate(float axisValue)
    {
        if (!IsRotateCameraState) return;
        if (IsRotateCameraState && FMath::Abs(axisValue) > KINDA_SMALL_NUMBER)
        {
            AddControllerPitchInput(-axisValue);
        }
    }
     
     

除了以上这种方法还有一种方法,UE4在AActor类中提供给了一个虚方法,继承自AActor的类通过重写ClacCamera虚函数的OutResult引用变量可以改变摄像机位置和旋转,实现代码博主直接贴出来,有兴趣的朋友可以看看:

    // Fill out your copyright notice in the Description page of Project Settings.
     
    #include "CameraCharacter.h"
    #include "Camera/CameraComponent.h"
    #include "GameFramework/SpringArmComponent.h"
    #include "GameFramework/PlayerInput.h"
    #include "Kismet/GameplayStatics.h"
    #include "UnrealMathUtility.h"
    #include "Engine/Engine.h"
    #include "GameFramework/Controller.h"
    #include "GameFramework/Character.h"
    #include "Components/CapsuleComponent.h"
     
    // Sets default values
    ACameraCharacter::ACameraCharacter()
    {
        // Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
        PrimaryActorTick.bCanEverTick = true;
     
        GetCapsuleComponent()->SetEnableGravity(false);
     
        /*创建弹簧手臂和摄像机*/
        //摄像机手臂
        CameraSpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraSpringArm"));
        CameraSpringArm->SetupAttachment(RootComponent);
        //设置距离
        CameraSpringArm->TargetArmLength = 300.f;
        //设置偏移
        CameraSpringArm->TargetOffset = FVector(0.f, 0.f, 0.f);
        //绑定Controller的旋转
        CameraSpringArm->bUsePawnControlRotation = true;
        //初始化第三人称摄像机
        ViewCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("ViewCamera"));
        //将相机绑定到摄像机手臂
        ViewCamera->SetupAttachment(CameraSpringArm, USpringArmComponent::SocketName);
        //设置ThirdCamera不跟随控制器的旋转
        ViewCamera->bUsePawnControlRotation = false;
        //处于激活状态
        ViewCamera->SetActive(true);
    }
     
    // Called when the game starts or when spawned
    void ACameraCharacter::BeginPlay()
    {
        Super::BeginPlay();
     
        //初始化变量
        MoveDirction = FVector::ZeroVector;
        CameraLocation = ViewCamera->GetSocketLocation(USpringArmComponent::SocketName);
        ScrollWheelSpeed = 50;
     
        CurrentCurcorPos = FontCurorPos = FVector2D::ZeroVector;
     
        IsBindShiftKey = false;
     
        IsRotateCameraState = false;
     
        RoundCameraDistTarget = 1000.f;
        RoundCameraTargetOffset = FVector::ZeroVector;
        RoundCameraDistCur = 1000.f;
     
        CameraOriginLocation = FVector::ZeroVector;
        CameraOriginRotate = FRotator::ZeroRotator;
    }
     
    void ACameraCharacter::CalcCamera(float DeltaTime, struct FMinimalViewInfo& OutResult)
    {
        if (ViewCamera->IsVisible())
        {
            if (bFindCameraComponentWhenViewTarget)
            {
                ViewCamera->GetCameraView(DeltaTime, OutResult);
            }
        }
        else
        {
            GetActorEyesViewPoint(OutResult.Location, OutResult.Rotation);
        }
     
        if (CameraOriginLocation != FVector::ZeroVector&&CameraOriginRotate != FRotator::ZeroRotator)
        {
            OutResult.Location = CameraOriginLocation;
            OutResult.Rotation = CameraOriginRotate;
        }
     
        if (IsRotateCameraState)
        {
            OutResult.Rotation.Yaw = GetControlRotation().Yaw;
            OutResult.Rotation.Pitch = GetControlRotation().Pitch;
            OutResult.Rotation.Roll = 0;
            OutResult.Location = RoundCameraTargetOffset;
            OutResult.Location -= OutResult.Rotation.Vector() * RoundCameraDistCur;
            RoundCameraDistCur = FMath::FInterpTo(RoundCameraDistCur, RoundCameraDistTarget, DeltaTime, 20.f);
     
            CameraLocation = OutResult.Location;
        }
        else
        {
            //滚动位置变化
            CameraLocation += MoveDirction*ScrollWheelSpeed;
            //平移位置变化
            CameraLocation += FVector(0, MoveOffset.X, -MoveOffset.Y);
            if (CameraLocation != FVector::ZeroVector)
            {
                OutResult.Location = CameraLocation;
            }
        }
     
        CameraOriginLocation = OutResult.Location;
        CameraOriginRotate = OutResult.Rotation;
    }
     
    void ACameraCharacter::Tick(float DeltaTime)
    {
        Super::Tick(DeltaTime);
     
        if (OnStartMoveCamera.IsBound())
        {
            OnStartMoveCamera.ExecuteIfBound();
        }
     
        if (OnStartRotateAroundCamera.IsBound())
        {
            OnStartRotateAroundCamera.ExecuteIfBound();
        }
    }
     
    // 调用绑定输入事件
    void ACameraCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
    {
        Super::SetupPlayerInputComponent(PlayerInputComponent);
     
        //向上滚轮
        UPlayerInput::AddEngineDefinedAxisMapping(FInputAxisKeyMapping("ScrollWheelUp", EKeys::MouseWheelAxis, 10));
        PlayerInputComponent->BindAxis("ScrollWheelUp", this, &ACameraCharacter::OnScrollWheelUpPress);
     
        //鼠标右键
        UPlayerInput::AddEngineDefinedAxisMapping(FInputAxisKeyMapping("MouseRightDrag", EKeys::RightMouseButton, 10));
        PlayerInputComponent->BindAxis("MouseRightDrag", this, &ACameraCharacter::OnMouseRightDrag);
     
        //键盘Shift键
        UPlayerInput::AddEngineDefinedActionMapping(FInputActionKeyMapping("KeyLeftShift", EKeys::LeftShift));
        PlayerInputComponent->BindAction("KeyLeftShift", IE_Pressed, this, &ACameraCharacter::OnKeyLeftShiftPress);
        PlayerInputComponent->BindAction("KeyLeftShift", IE_Released, this, &ACameraCharacter::OnKeyLeftShiftReleased);
     
        //鼠标位置(X,Y方向)
        UPlayerInput::AddEngineDefinedAxisMapping(FInputAxisKeyMapping("Turn", EKeys::MouseX, 10));
        PlayerInputComponent->BindAxis("Turn", this, &ACameraCharacter::OnTurn);
        UPlayerInput::AddEngineDefinedAxisMapping(FInputAxisKeyMapping("LookAtRotate", EKeys::MouseY, 10));
        PlayerInputComponent->BindAxis("LookAtRotate", this, &ACameraCharacter::OnLookAtRotate);
    }
     
    //滚动滑轮
    void ACameraCharacter::OnScrollWheelUpPress(float axisValue)
    {
        FVector2D CursorPos;
        FVector WorldPos;
        MoveDirction = FVector::ZeroVector;
     
        if (axisValue != 0)
        {
            GetWorld()->GetFirstPlayerController()->GetMousePosition(CursorPos.X, CursorPos.Y);
            UGameplayStatics::DeprojectScreenToWorld(GetWorld()->GetFirstPlayerController(), CursorPos, WorldPos, MoveDirction);
     
            if (axisValue < 0)
            {
                MoveDirction = -MoveDirction;
            }
     
            GEngine->AddOnScreenDebugMessage(-1, 0.5f, FColor::White, MoveDirction.ToString());
        }
    }
     
    //鼠标右键拖拽
    void ACameraCharacter::OnMouseRightDrag(float axisValue)
    {
        if (axisValue == 0)
        {
            CurrentCurcorPos = FontCurorPos = FVector2D::ZeroVector;
            MoveOffset = FVector2D::ZeroVector;
            IsRotateCameraState = false;
     
            OnStartMoveCamera.Unbind();
        }
        else
        {
            //按下左shift键,开始拖拽
            if (IsBindShiftKey)
            {
                //拖拽状态
                OnStartMoveCamera.BindUObject(this, &ACameraCharacter::CalcCameraMoveDrogDirction);
            }
            //没有按下左Shift键时候绕鼠标点旋转
            else
            {
                IsRotateCameraState = true;
            }
        }
    }
     
    //计算在屏幕中的MoveOffset(前一个鼠标点到当前鼠标点的向量)
    void ACameraCharacter::CalcCameraMoveDrogDirction()
    {
        if (FVector2D::Distance(FontCurorPos, CurrentCurcorPos) == 0)
        {
            GetWorld()->GetFirstPlayerController()->GetMousePosition(FontCurorPos.X, FontCurorPos.Y);
        }
        else
        {
            GetWorld()->GetFirstPlayerController()->GetMousePosition(CurrentCurcorPos.X, CurrentCurcorPos.Y);
            MoveOffset = CurrentCurcorPos - FontCurorPos;
     
            FontCurorPos = CurrentCurcorPos;
        }
    }
     
     
    void ACameraCharacter::OnKeyLeftShiftPress()
    {
        IsBindShiftKey = true;
    }
     
    void ACameraCharacter::OnKeyLeftShiftReleased()
    {
        IsBindShiftKey = false;
    }
     
    void ACameraCharacter::OnTurn(float axisValue)
    {
        if (!IsRotateCameraState) return;
        //if (axisValue>0)
        {
            AddControllerYawInput(axisValue);
            RoundCameraTargetOffset += FRotator(0, 90, 0).Vector() * axisValue * 160.f * GetWorld()->GetDeltaSeconds() * RoundCameraDistTarget / 500.f;
        }
    }
     
     
    void ACameraCharacter::OnLookAtRotate(float axisValue)
    {
        if (!IsRotateCameraState) return;
        //if (axisValue > 0)
        {
            AddControllerPitchInput(axisValue);
            RoundCameraTargetOffset += FRotator(0, 0, 0).Vector() * axisValue * 160.f * GetWorld()->GetDeltaSeconds() * RoundCameraDistTarget / 500.f;
        }
    }
     
     

备注:在创建一个继承自ACharacter的类会自带一个默认的摄像机,当在其添加了一个摄像机组件后替换这个摄像机

结语:博主今后会持续更新UE4、U3D的学习内容,大家多多支持!

博客地址:blog.liujunliang.com.cn
————————————————
版权声明:本文为CSDN博主「即步」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_33747722/article/details/81193894

 

 

 

 

 

相关文章:

  • 对ue4 sequence的学习和理解
  • [gdc19]《战神4》中的全局光照技术
  • 5 种避免使用 C# lock 关键字的方法
  • [玩转UE4动画系统>功能模块] 之 Advanced Locomotion System V4 的工具函数及工具宏详解
  • Lua5.4新特性
  • 探究光线追踪技术及UE4的实现 -- good
  • Unity游戏项目性能优化总结
  • 【UE4源代码观察】观察DDC(DerivedDataCache)
  • Chrome 抓包
  • float.Parse 在不同区域小数表示是不一样的
  • C# GC 垃圾回收
  • Android Studio NDk调试(基于gradle-experimental插件与LLDB)
  • android studio调试c/c++代码
  • 在开发过程中使用 git rebase 还是 git merge,优缺点分别是什么?
  • Visual Studio 2019 远程调试工具(Remote Debugger)使用方法
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • 【从零开始安装kubernetes-1.7.3】2.flannel、docker以及Harbor的配置以及作用
  • iOS 系统授权开发
  • iOS 颜色设置看我就够了
  • JavaScript服务器推送技术之 WebSocket
  • JavaScript设计模式系列一:工厂模式
  • Java面向对象及其三大特征
  • JSDuck 与 AngularJS 融合技巧
  • linux安装openssl、swoole等扩展的具体步骤
  • Node.js 新计划:使用 V8 snapshot 将启动速度提升 8 倍
  • nodejs调试方法
  • Redis字符串类型内部编码剖析
  • Vim Clutch | 面向脚踏板编程……
  • vue.js框架原理浅析
  • vue脚手架vue-cli
  • WinRAR存在严重的安全漏洞影响5亿用户
  • 翻译:Hystrix - How To Use
  • 分享几个不错的工具
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 和 || 运算
  • 类orAPI - 收藏集 - 掘金
  • 前言-如何学习区块链
  • 通信类
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • Spark2.4.0源码分析之WorldCount 默认shuffling并行度为200(九) ...
  • 教程:使用iPhone相机和openCV来完成3D重建(第一部分) ...
  • 资深实践篇 | 基于Kubernetes 1.61的Kubernetes Scheduler 调度详解 ...
  • #gStore-weekly | gStore最新版本1.0之三角形计数函数的使用
  • #Linux(帮助手册)
  • #单片机(TB6600驱动42步进电机)
  • #预处理和函数的对比以及条件编译
  • (0)Nginx 功能特性
  • (Git) gitignore基础使用
  • (zt)最盛行的警世狂言(爆笑)
  • (附源码)spring boot北京冬奥会志愿者报名系统 毕业设计 150947
  • (离散数学)逻辑连接词
  • (四)图像的%2线性拉伸
  • (一)Spring Cloud 直击微服务作用、架构应用、hystrix降级
  • (幽默漫画)有个程序员老公,是怎样的体验?
  • (转)iOS字体