项目设置里创建三个动作:上下,前后,旋转
2.在头文件里,添加两个public的变量
//向上加速度
UPROPERTY(EditAnywhere , BlueprintReadWrite , Category = "init")
float LiftAcc = 100.0f;
//最大向上推力
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "init")
float LiftThrustMax = 2000.0f;
3.三个输入相关的函数
private:
UFUNCTION()
void Lift( float val);
UFUNCTION()
void Forward(float val);
UFUNCTION()
void Turn(float val);
4.进入无人机的源文件
引入头文件
#include "Kismet/KismetMathLibrary.h"
#include "Kismet/KismetSystemLibrary.h"
5.在void ADrone::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)函数中进行绑定,输入函数
PlayerInputComponent->BindAxis(TEXT("Lift"), this, &ADrone::Lift);
PlayerInputComponent->BindAxis(TEXT("Forward"), this, &ADrone::Forward);
PlayerInputComponent->BindAxis(TEXT("Turn"), this, &ADrone::Turn);
6.定义list函数
void ADrone:: Lift(float val)
{
//推进力变化
UpThruster->ThrustStrength += val * LiftAcc * GetWorld()->DeltaTimeSeconds;
//限制推进力变化
UpThruster->ThrustStrength = FMath::Clamp(UpThruster->ThrustStrength, -LiftThrustMax, LiftThrustMax);
//打印推进力
FString::SanitizeFloat(UpThruster->ThrustStrength);
UKismetSystemLibrary::PrintString(this,FString::SanitizeFloat(UpThruster->ThrustStrength));
}
7.添加向前的加速度,和最大力量
//向前加速度
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "init")
float ForwardAcc = 1000.0f;
//最大向前推力
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "init")
float ForwardThrustMax = 2000.0f;
8.在源文件中定义向前函数
void ADrone::Forward(float val)
{
//推进力变化
ForwardThruster->ThrustStrength += val * LiftAcc * GetWorld()->DeltaTimeSeconds;
//限制推进力变化
ForwardThruster->ThrustStrength = FMath::Clamp(ForwardThruster->ThrustStrength, -ForwardThrustMax, ForwardThrustMax);
}
9.头文件添加一个转向力
//转向力
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "init")
float TurnThrust = 5000.0f;
10.定义转向函数
void ADrone::Turn(float val)
{
OutCollision->AddTorqueInDegrees(this->GetActorUpVector() * val * TurnThrust);
}
11.当我们松开键盘,推进力应该恢复初始状态,这个功能在每帧函数里实现
if (InputComponent->GetAxisValue(TEXT("Lift")) == 0.0f)
{
UpThruster->ThrustStrength = 980.0f;
}
if (InputComponent->GetAxisValue(TEXT("Forward")) == 0.0f)
{
ForwardThruster->ThrustStrength = 0.0f;
}
12.点击场景中的无人机,进行设置操作权限
13.添加弹簧臂和相机 ,更容易观察
14.设置臂长
15.再添加两个输入
16.接下来用蓝图实现弹簧臂的摇动
17.设置弹簧臂
18.测试成功。
==========================================
让螺旋桨动起来
1.添加一个数组容器和一个函数,权限是private
private:
//TArray 是虚幻引擎中最常用的容器类。
TArray<UStaticMeshComponent *> paddles;
void RotatePaddle(float Delta);
2.在构造函数中将四个螺旋桨的指针存入容器
//将螺旋桨放入容器
paddles.Add(Paddle1);
paddles.Add(Paddle2);
paddles.Add(Paddle3);
paddles.Add(Paddle4);
3.添加一个螺旋桨旋转速度变量,public权限
//螺旋桨旋转速度
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "init")
float PaddleRotateSpeed = 1500.0f;
4.定义RotatePaddle函数
void ADrone::RotatePaddle(float Delta)
{
for (auto Paddle : paddles)
{
Paddle->AddRelativeRotation(FRotator(.0f, Delta*PaddleRotateSpeed, .0f));
}
}
5.在每帧函数里调用这个函数
RotatePaddle(DeltaTime);
==================================
前进和后退时,设置机身倾斜
1.在Forward函数里面,得到机身实时的前倾角度值,如果倾斜度小于30,就允许倾斜
//获得机身实时前倾角度
float pitch = Mesh->GetRelativeRotation().Pitch;
//如果倾斜度小于30,就允许倾斜
if (FMath::Abs(pitch) < 30.0f)
{
Mesh->AddRelativeRotation(FRotator(100.0f * GetWorld()->DeltaTimeSeconds * val, .0f, .0f));
}
2.在每帧函数里,当不向前(向后)的时候,从倾斜状态恢复水平状态
void ADrone::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (InputComponent->GetAxisValue(TEXT("Lift")) == 0.0f)
{
UpThruster->ThrustStrength = 980.0f;
}
if (InputComponent->GetAxisValue(TEXT("Forward")) == 0.0f)
{
//推力清零
ForwardThruster->ThrustStrength = 0.0f;
//检测倾斜状态
if (Mesh->GetRelativeRotation().Pitch != 0.0f)
{
//此时的倾斜量
float CurrentPitch = Mesh->GetRelativeRotation().Pitch;
FString::SanitizeFloat(CurrentPitch);
UKismetSystemLibrary::PrintString(this, FString::SanitizeFloat(CurrentPitch));
//向反方向进行倾斜
Mesh->AddRelativeRotation(FRotator(-CurrentPitch * DeltaTime, .0f, .0f));
//避免机身抖动
if (FMath::Abs(Mesh->GetRelativeRotation().Pitch) <= KINDA_SMALL_NUMBER)
{
Mesh->SetRelativeRotation(FRotator(.0f, .0f, .0f));
}
}
}
//旋转螺旋桨
RotatePaddle(DeltaTime);
}