当前位置:   article > 正文

【UE4/蓝图/C++】简易FPS武器视角随动效果_蓝图fps

蓝图fps

一、演示

UE4/蓝图/C++】简易FPS武器视角随动效果

二、简要说明

主要是实现了一个简单的第一人称的手臂跟随相机反方向移动(也可改成同方向),用蓝图和C++分别实现了同样功能

一共需要一个继承自Character的类,类内有一个Camera组件,和一个挂载在Camera组件下的手臂网格体组件,称为Arm Mesh

一共创建了四个变量进行控制:

  • Init Arm Mesh Relative Location:在BeginPlay中初始化,负责记录手臂初始的相对位置
  • Arm Move Speed:手臂随摄像机移动的速度,默认是-0.1,负值意味着与相机移动的相反方向移动
  • Arm Move Range:手臂位移的最大半径范围,若超出此范围则会阻止继续远离的运动
  • Arm Return Speed:手臂的回中速度,在鼠标输入慢下来或者停止时,会自动回中

三、蓝图实现

1.准备

        首先在Character下创建Camera组件和Skeleton Mesh组件(此处已命名为Arm Mesh),相关美术资源和基础输入的配置此处忽略

        然后依次创建下列四个变量,其默认值分别为:

  •         Init Arm Mesh Relative Location        无需默认值
  •         Arm Move Speed        -0.1
  •         Arm Move Range        10
  •         Arm Return Speed        5

2.BeginPlay

在BeginPlay中对Init Arm Mesh Relative Location向量赋值,目的是在运行前在类中对其位置的修改都能够在游戏开始时被记录下来

3.Tick

Tick中大致由两部分构成,一边是跟随相机的偏移效果,一边是回中的效果

具体细节如下:

1.判断条件

LookTurn和LookUp分别是鼠标X轴和鼠标Y轴的轴值,当它们同时大致等于0的时候则会走入True分支(回中),否则走False分支(偏移)

2.回中

回中中首先进行了一次判断,若手臂当前的位置和其初始位置过于接近,则什么操作也不做

否则说明二者不接近,使用向量插值节点,从当前位置到初始位置进行插值,Interp Speed即我们的Arm Return Speed参数,最后将得到的值直接赋值给Arm Mesh的相对位置即可

3.偏移

偏移操作首先进行了一次判断,这个判断用OR连接,OR上第一个的意思是,首先用当前位置向量减去默认位置向量,得到的向量的长度是这二者的距离,再加上一个由鼠标输入轴值构建的向量,就可以预测得到移动后的位置,此向量的长度也就是预测的向量长度,其如果在允许的范围内,OR的第一个会变为true,就会直接根据鼠标输入加上Arm Move Speed的缩放执行添加相对位置。

如果在范围外,则会接着执行OR的第二个条件,将预测的距离与当前位置和默认位置的距离进行对比,若小于,则说明运动趋势是向初始位置移动的,故也运行添加相对位置。

自此功能完成。

四、C++实现

首先在继承的Character的头文件中创建相应的组件,再在构造函数中为其初始化

  1. //.h
  2. UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Component", meta = (AllowPrivateAccess = "true"))
  3. UCameraComponent* Camera;
  4. UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Component", meta = (AllowPrivateAccess = "true"))
  5. USkeletalMeshComponent* ArmMesh;
  6. //.cpp
  7. Camera = CreateDefaultSubobject<UCameraComponent>("Camera");
  8. Camera->SetupAttachment(GetRootComponent());
  9. Camera->bUsePawnControlRotation = true;
  10. ArmMesh = CreateDefaultSubobject<USkeletalMeshComponent>("ArmMesh");
  11. ArmMesh->SetupAttachment(Camera);

初始化完成后,创建所需的在Tick中执行的函数和相关变量

  1. void ArmMeshServo(const float& DeltaTime); //手臂跟随视角转动进行随动的函数,在Tick函数中调用
  2. FVector InitArmMeshRelativeLocation; //在BeginPlay中初始化,负责记录ArmMesh的初始相对位置
  3. UPROPERTY(EditAnywhere, Category="Settings|ArmMeshServo")
  4. float ArmMoveSpeed = -0.1; //手臂随动速度,负值意味着将向与相机相反的方向移动
  5. UPROPERTY(EditAnywhere, Category="Settings|ArmMeshServo")
  6. float ArmMoveRange = 10; //手臂移动的最大范围
  7. UPROPERTY(EditAnywhere, Category="Settings|ArmMeshServo")
  8. float ArmReturnSpeed = 5; //手臂回中速度

函数实现:

  1. //先在BeginPlay中对InitArmMeshRelativeLocation 进行初始化
  2. void AFPSBaseCharacter::BeginPlay()
  3. {
  4. Super::BeginPlay();
  5. InitArmMeshRelativeLocation = ArmMesh->GetRelativeLocation();
  6. }
  7. //手臂随动函数的实现
  8. void AFPSBaseCharacter::ArmMeshServo(const float& DeltaTime)
  9. {
  10. FVector CurrentRelativeLocation = ArmMesh->GetRelativeLocation(); //获取当前相对位置
  11. float XInput = GetInputAxisValue("LookTurn"); //获取鼠标X轴的输入轴值
  12. float YInput = GetInputAxisValue("LookUp"); //获取鼠标Y轴的输入轴值
  13. if (FMath::IsNearlyZero(XInput, 0.2f) && FMath::IsNearlyZero(YInput, 0.2f)) //若视角转动过慢或静止,则会进行回中
  14. {
  15. if ((CurrentRelativeLocation - InitArmMeshRelativeLocation).IsNearlyZero()) return; //若已接近默认位置,则返回
  16. FVector DeltaVector = UKismetMathLibrary::VInterpTo(CurrentRelativeLocation, InitArmMeshRelativeLocation, DeltaTime, ArmReturnSpeed); //通过插值函数获取所需差量
  17. ArmMesh->SetRelativeLocation(DeltaVector); //设置其相对位置
  18. }
  19. else
  20. {
  21. FVector NewRelativeLocation = CurrentRelativeLocation - InitArmMeshRelativeLocation + FVector(0, XInput * ArmMoveSpeed, YInput * ArmMoveSpeed); //计算新位置
  22. //检查新位置是否在允许的范围内,如不在,则检查新位置是否能比当前位置更靠近默认位置
  23. if (NewRelativeLocation.Size() <= ArmMoveRange || NewRelativeLocation.Size() < (CurrentRelativeLocation - InitArmMeshRelativeLocation).Size())
  24. {
  25. ArmMesh->AddRelativeLocation(FVector(0, XInput * ArmMoveSpeed, YInput * ArmMoveSpeed)); //在则添加相对位置
  26. }
  27. }
  28. }

然后在Tick函数中调用

  1. void AFPSBaseCharacter::Tick(float DeltaTime)
  2. {
  3. Super::Tick(DeltaTime);
  4. ArmMeshServo(DeltaTime);
  5. }

自此C++功能亦实现

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号