虚幻C+++基础 day2

角色移动与视角控制

Character类与相关API

  • 创建Character子类
  • MainPlayer.h
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "MainPlayer.generated.h"UCLASS()
class UEGAME_API AMainPlayer : public ACharacter
{GENERATED_BODY()public:// Sets default values for this character's propertiesAMainPlayer();//新建一个SpringArmUPROPERTY(visibleAnywhere,BlueprintReadOnly)class USpringArmComponent* SpringArm;//新建一个CameraUPROPERTY(visibleAnywhere, BlueprintReadOnly)class UCameraComponent* FollowCamera;protected:// Called when the game starts or when spawnedvirtual void BeginPlay() override;public:	// Called every framevirtual void Tick(float DeltaTime) override;// Called to bind functionality to inputvirtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;};
  • MianPlayer.cpp
// Fill out your copyright notice in the Description page of Project Settings.#include "MainPlayer.h"
#include "GameFramework/SpringArmComponent.h"
#include "Camera/CameraComponent.h"// Sets default values
AMainPlayer::AMainPlayer()
{// 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;SpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArm"));SpringArm->SetupAttachment(GetRootComponent());//设置SPringArm无碰撞臂长SpringArm->TargetArmLength = 600.f;FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));FollowCamera->SetupAttachment(SpringArm, NAME_None);}// Called when the game starts or when spawned
void AMainPlayer::BeginPlay()
{Super::BeginPlay();}// Called every frame
void AMainPlayer::Tick(float DeltaTime)
{Super::Tick(DeltaTime);}// Called to bind functionality to input
void AMainPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{Super::SetupPlayerInputComponent(PlayerInputComponent);}
  • 运行结果
    在这里插入图片描述

指定骨骼模型并调整胶囊体

  • 指定骨骼模型

在这里插入图片描述

  • C++硬编码给出默认值

  • 头文件胶囊体#include “Components/CapsuleComponent.h”

//设置胶囊体的默认宽高
GetCapsuleComponent()->SetCapsuleSize(35.f, 100.f);

在这里插入图片描述

创建轴映射与GameMode

  • 创建关卡GameMode子类

在这里插入图片描述

  • 设置玩家使用默认类

在这里插入图片描述

在这里插入图片描述

  • 轴映射

在这里插入图片描述

基本简单移动与旋转控制

  • AddMovementInput:沿着给定的世界方向向量(通常是标准化的)添加移动输入,并按“ScaleValue”进行缩放。如果ScaleValue < 0,则移动方向相反。基础Pawn类不会自动应用移动,这取决于用户在Tick事件中这样做。像Character和DefaultPawn这样的子类会自动处理这些输入并移动。

在这里插入图片描述

  • GetActorForwardVector:获取Actor,X轴正向的向量

  • GetActorRightVector:获取Actor,Y轴正向的向量

MainPlayer.cpp

// Fill out your copyright notice in the Description page of Project Settings.#include "MainPlayer.h"
#include "GameFramework/SpringArmComponent.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "Components/InputComponent.h"
// Sets default values
AMainPlayer::AMainPlayer()
{// 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;SpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArm"));SpringArm->SetupAttachment(GetRootComponent());//设置SPringArm无碰撞臂长SpringArm->TargetArmLength = 600.f;SpringArm->bUsePawnControlRotation = true;//硬编码SpringArm继承controlller旋转为真FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));FollowCamera->SetupAttachment(SpringArm, NAME_None);FollowCamera->bUsePawnControlRotation = false;//硬编码FollowCamera继承controlller旋转为假//设置胶囊体的默认宽高GetCapsuleComponent()->SetCapsuleSize(35.f, 100.f);
}// Called when the game starts or when spawned
void AMainPlayer::BeginPlay()
{Super::BeginPlay();}// Called every frame
void AMainPlayer::Tick(float DeltaTime)
{Super::Tick(DeltaTime);}// Called to bind functionality to input
void AMainPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{Super::SetupPlayerInputComponent(PlayerInputComponent);//检查PlayerInputComponent指针,check函数只能在这使用check(PlayerInputComponent);//绑定轴映射事件PlayerInputComponent->BindAxis("MoveForward", this, &AMainPlayer::MoveForward);PlayerInputComponent->BindAxis("MoveRigth", this, &AMainPlayer::MoveRigth);//绑定Controller控制器去管理视角旋转PlayerInputComponent->BindAxis("Turn", this, &ACharacter::AddControllerYawInput);PlayerInputComponent->BindAxis("LookUp", this, &ACharacter::AddControllerPitchInput);}void AMainPlayer::MoveForward(float value)
{//沿着给定的世界方向向量(通常是标准化的)添加移动输入AddMovementInput(GetActorForwardVector(), value);
}void AMainPlayer::MoveRigth(float value)
{AddMovementInput(GetActorRightVector(), value);
}

控制角色旋转

  • 相机的选择和角色的旋转应该是两个独立的事件
  • 我们需要分离控制相机的鼠标控制旋转(ControlRotation)和角色旋转(Pawn Rotation)。
  • 在UE中XYZ轴的正向分别对应前方、右方和上方,显示的箭头颜色分别为红色、绿色和蓝色(三基色的习惯顺序)。
  • 头文件 #include “GameFramework/PlayerController.h”
  • Controller:这是Character类中自己声明的AController* 属性,用与获取该Actor的控制器
    在这里插入图片描述
// Fill out your copyright notice in the Description page of Project Settings.#include "MainPlayer.h"
#include "GameFramework/SpringArmComponent.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "Components/InputComponent.h"
#include "GameFramework/PlayerController.h"// Sets default values
AMainPlayer::AMainPlayer()
{// 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;SpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArm"));SpringArm->SetupAttachment(GetRootComponent());//设置SPringArm无碰撞臂长SpringArm->TargetArmLength = 600.f;SpringArm->bUsePawnControlRotation = true;//硬编码SpringArm继承controlller旋转为真FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));FollowCamera->SetupAttachment(SpringArm, NAME_None);FollowCamera->bUsePawnControlRotation = false;//硬编码FollowCamera继承controlller旋转为假//设置胶囊体的默认宽高GetCapsuleComponent()->SetCapsuleSize(35.f, 100.f);//对Character的Pawn进行硬编码bUseControllerRotationPitch = false;bUseControllerRotationYaw = false;bUseControllerRotationRoll = false;}// Called when the game starts or when spawned
void AMainPlayer::BeginPlay()
{Super::BeginPlay();}// Called every frame
void AMainPlayer::Tick(float DeltaTime)
{Super::Tick(DeltaTime);}// Called to bind functionality to input
void AMainPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{Super::SetupPlayerInputComponent(PlayerInputComponent);//检查PlayerInputComponent指针,check函数只能在这使用check(PlayerInputComponent);//绑定轴映射事件PlayerInputComponent->BindAxis("MoveForward", this, &AMainPlayer::MoveForward);PlayerInputComponent->BindAxis("MoveRigth", this, &AMainPlayer::MoveRigth);//绑定Controller控制器去管理视角旋转PlayerInputComponent->BindAxis("Turn", this, &ACharacter::AddControllerYawInput);PlayerInputComponent->BindAxis("LookUp", this, &ACharacter::AddControllerPitchInput);}void AMainPlayer::MoveForward(float value)
{//获取到Control旋转FRotator Rotation = Controller->GetControlRotation();//转向只关注水平Yaw方向,因此置0防止影响FRotator YowRotation = FRotator(0.0f, Rotation.Yaw, 0.0f);//获取相机(鼠标控制器的朝向),并且朝这个轴的方向移动FVector Direction = FRotationMatrix(YowRotation).GetUnitAxis(EAxis::X);AddMovementInput(Direction, value);
}void AMainPlayer::MoveRigth(float value)
{//获取到Controller旋转FRotator Rotation = Controller->GetControlRotation();//转向只关注水平Yaw方向,因此置0防止影响FRotator YowRotation = FRotator(0.0f, Rotation.Yaw, 0.0f);//获取相机(鼠标控制器的朝向),并且朝这个轴的方向移动FVector Direction = FRotationMatrix(YowRotation).GetUnitAxis(EAxis::Y);AddMovementInput(Direction, value);
}

使角色自动面向移动方向

  • CharacterMovement非常强大,我们打开CharacterMovement的Orient Rotation to Movement就开启自动面向旋转

在这里插入图片描述

  • 头文件:#include “GameFramework/CharacterMovementComponent.h”
	//硬编码orient Rotation to Movement,给个默认转向速率GetCharacterMovement()->bOrientRotationToMovement = true;GetCharacterMovement()->RotationRate = FRotator(0.f, 500.f, 0.f);
  • 运行结果

在这里插入图片描述

创建键盘与手柄使用的视角与旋转函数

  • 新建两个float变量来控制上下左右转向的速率,注意旋转时要乘以DeltaTime避免高低性能差值
	float BaseTurnRate;		//使用键盘X转向的速率float BaseLookUpRate;	//使用键盘Y转向的速率//给键盘控制转向的速率变量赋初值BaseTurnRate = 21.f;BaseLookUpRate = 21.f;
  • 因为可能要修改视角限制,新建Turn与LookUp绑定Controller控制器去管理视角旋转函数,新建绑定键盘鼠标轴映射事件函数
private:void MoveForward(float value);void MoveRight(float value);void Turn(float Value);void LookUp(float Value);void TurnRate(float Rate);void LookUpRate(float Rate);
// Called to bind functionality to input
void AMainPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{Super::SetupPlayerInputComponent(PlayerInputComponent);//检查PlayerInputComponent指针,check函数只能在这使用check(PlayerInputComponent);//绑定移动轴映射事件PlayerInputComponent->BindAxis("MoveForward", this, &AMainPlayer::MoveForward);PlayerInputComponent->BindAxis("MoveRight", this, &AMainPlayer::MoveRight);//绑定Controller控制器去管理视角旋转PlayerInputComponent->BindAxis("Turn", this, &AMainPlayer::Turn);PlayerInputComponent->BindAxis("LookUp", this, &AMainPlayer::LookUp);//绑定键盘鼠标轴映射事件PlayerInputComponent->BindAxis("TurnRate", this, &AMainPlayer::TurnRate);PlayerInputComponent->BindAxis("LookUpRate", this, &AMainPlayer::LookUpRate);}
void AMainPlayer::Turn(float Value)
{if (Value != 0.f){AddControllerYawInput(Value);}}void AMainPlayer::LookUp(float Value)
{if (Value != 0.f){AddControllerPitchInput(Value);}}void AMainPlayer::TurnRate(float Rate)
{//要乘以一个DeltaTime这样就可以避免高帧底帧差值问题float Value = Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds();if (Value != 0.f){AddControllerYawInput(Value);}
}void AMainPlayer::LookUpRate(float Rate)
{//要乘以一个DeltaTime这样就可以避免高帧底帧差值问题float Value = Rate * BaseLookUpRate * GetWorld()->GetDeltaSeconds();if (Value != 0.f){AddControllerPitchInput(Value);}
}

限制角色上下视角旋转的范围

  • 思路当旋转区域不是理想的范围就直接不要

在这里插入图片描述

void AMainPlayer::LookUp(float Value)
{//UE_LOG(LogTemp, Warning, TEXT("%f"), GetControlRotation().Pitch);// //控制视角if (GetControlRotation().Pitch < 270.f && GetControlRotation().Pitch >180.f && Value > 0.f){return;}else if (GetControlRotation().Pitch < 180.f && GetControlRotation().Pitch >45.f && Value < 0.f){return;}AddControllerPitchInput(Value);
}
  • MainPlayer.cpp
// Fill out your copyright notice in the Description page of Project Settings.#include "MainPlayer.h"
#include "GameFramework/SpringArmComponent.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "Components/InputComponent.h"
#include "GameFramework/PlayerController.h"
#include "GameFramework/CharacterMovementComponent.h"// Sets default values
AMainPlayer::AMainPlayer()
{// 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;SpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArm"));SpringArm->SetupAttachment(GetRootComponent());//设置SPringArm无碰撞臂长SpringArm->TargetArmLength = 600.f;SpringArm->bUsePawnControlRotation = true;//硬编码SpringArm继承controlller旋转为真FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));FollowCamera->SetupAttachment(SpringArm, NAME_None);FollowCamera->bUsePawnControlRotation = false;//硬编码FollowCamera继承controlller旋转为假//设置胶囊体的默认宽高GetCapsuleComponent()->SetCapsuleSize(35.f, 100.f);//对Character的Pawn进行硬编码bUseControllerRotationPitch = false;bUseControllerRotationYaw = false;bUseControllerRotationRoll = false;//硬编码orient Rotation to Movement,给个默认转向速率GetCharacterMovement()->bOrientRotationToMovement = true;GetCharacterMovement()->RotationRate = FRotator(0.f, 500.f, 0.f);//给键盘控制转向的速率变量赋初值BaseTurnRate = 21.f;BaseLookUpRate = 21.f;
}// Called when the game starts or when spawned
void AMainPlayer::BeginPlay()
{Super::BeginPlay();}// Called every frame
void AMainPlayer::Tick(float DeltaTime)
{Super::Tick(DeltaTime);}// Called to bind functionality to input
void AMainPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{Super::SetupPlayerInputComponent(PlayerInputComponent);//检查PlayerInputComponent指针,check函数只能在这使用check(PlayerInputComponent);//绑定移动轴映射事件PlayerInputComponent->BindAxis("MoveForward", this, &AMainPlayer::MoveForward);PlayerInputComponent->BindAxis("MoveRight", this, &AMainPlayer::MoveRight);//绑定Controller控制器去管理视角旋转PlayerInputComponent->BindAxis("Turn", this, &AMainPlayer::Turn);PlayerInputComponent->BindAxis("LookUp", this, &AMainPlayer::LookUp);//绑定键盘鼠标轴映射事件PlayerInputComponent->BindAxis("TurnRate", this, &AMainPlayer::TurnRate);PlayerInputComponent->BindAxis("LookUpRate", this, &AMainPlayer::LookUpRate);}void AMainPlayer::MoveForward(float value)
{if (Controller != nullptr && value != 0.f){//获取到Control旋转FRotator Rotation = Controller->GetControlRotation();//转向只关注水平Yaw方向,因此置0防止影响FRotator YowRotation = FRotator(0.0f, Rotation.Yaw, 0.0f);//获取相机(鼠标控制器的朝向),并且朝这个轴的方向移动FVector Direction = FRotationMatrix(YowRotation).GetUnitAxis(EAxis::X);AddMovementInput(Direction, value);}}void AMainPlayer::MoveRight(float value)
{if (Controller != nullptr && value != 0.f){//获取到Controller旋转FRotator Rotation = Controller->GetControlRotation();//转向只关注水平Yaw方向,因此置0防止影响FRotator YowRotation = FRotator(0.0f, Rotation.Yaw, 0.0f);//获取相机(鼠标控制器的朝向),并且朝这个轴的方向移动FVector Direction = FRotationMatrix(YowRotation).GetUnitAxis(EAxis::Y);AddMovementInput(Direction, value);}
}void AMainPlayer::Turn(float Value)
{if (Value != 0.f){AddControllerYawInput(Value);}}void AMainPlayer::LookUp(float Value)
{//UE_LOG(LogTemp, Warning, TEXT("%f"), GetControlRotation().Pitch);// //控制视角if (GetControlRotation().Pitch < 270.f && GetControlRotation().Pitch >180.f && Value > 0.f){return;}else if (GetControlRotation().Pitch < 180.f && GetControlRotation().Pitch >45.f && Value < 0.f){return;}AddControllerPitchInput(Value);
}void AMainPlayer::TurnRate(float Rate)
{//要乘以一个DeltaTime这样就可以避免高帧底帧差值问题float Value = Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds();if (Value != 0.f){AddControllerYawInput(Value);}
}void AMainPlayer::LookUpRate(float Rate)
{//要乘以一个DeltaTime这样就可以避免高帧底帧差值问题float Value = Rate * BaseLookUpRate * GetWorld()->GetDeltaSeconds();//控制视角if (GetControlRotation().Pitch < 270.f && GetControlRotation().Pitch >180.f && Value > 0.f){return;}else if (GetControlRotation().Pitch < 180.f && GetControlRotation().Pitch >45.f && Value < 0.f){return;}AddControllerPitchInput(Value);}

角色跳跃与空中控制

  • 直接重写Character类中的Jump方法,然后绑定轴映射到空格跳跃

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

	//重新Character类中的Jump方法void Jump() override;
	//绑定跳跃轴映射事件PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &AMainPlayer::Jump);//按下空格PlayerInputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping);//抬起空格
void AMainPlayer::Jump()
{//继承父类的方法Super::Jump();
}
  • 设置跳跃的默认跳跃初始值与在空中的坠落时横向运动控制量(硬编码)
	//设置跳跃初始值与在空中的坠落时横向运动控制量GetCharacterMovement()->JumpZVelocity = 600.f;GetCharacterMovement()->AirControl = 0.15f;

在这里插入图片描述

  • MainPlayer.h
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "MainPlayer.generated.h"UCLASS()
class UEGAME_API AMainPlayer : public ACharacter
{GENERATED_BODY()public:// Sets default values for this character's propertiesAMainPlayer();//新建一个SpringArmUPROPERTY(visibleAnywhere,BlueprintReadOnly)class USpringArmComponent* SpringArm;//新建一个CameraUPROPERTY(visibleAnywhere, BlueprintReadOnly)class UCameraComponent* FollowCamera;float BaseTurnRate;		//使用键盘X转向的速率float BaseLookUpRate;	//使用键盘Y转向的速率protected:// Called when the game starts or when spawnedvirtual void BeginPlay() override;public:	// Called every framevirtual void Tick(float DeltaTime) override;// Called to bind functionality to inputvirtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;//重新Character类中的Jump方法void Jump() override;void MoveForward(float value);void MoveRight(float value);void Turn(float Value);void LookUp(float Value);void TurnRate(float Rate);void LookUpRate(float Rate);
};
  • MainPlayer.cpp
// Fill out your copyright notice in the Description page of Project Settings.#include "MainPlayer.h"
#include "GameFramework/SpringArmComponent.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "Components/InputComponent.h"
#include "GameFramework/PlayerController.h"
#include "GameFramework/CharacterMovementComponent.h"// Sets default values
AMainPlayer::AMainPlayer()
{// 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;SpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArm"));SpringArm->SetupAttachment(GetRootComponent());//设置SPringArm无碰撞臂长SpringArm->TargetArmLength = 600.f;SpringArm->bUsePawnControlRotation = true;//硬编码SpringArm继承controlller旋转为真FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));FollowCamera->SetupAttachment(SpringArm, NAME_None);FollowCamera->bUsePawnControlRotation = false;//硬编码FollowCamera继承controlller旋转为假//设置胶囊体的默认宽高GetCapsuleComponent()->SetCapsuleSize(35.f, 100.f);//对Character的Pawn进行硬编码bUseControllerRotationPitch = false;bUseControllerRotationYaw = false;bUseControllerRotationRoll = false;//硬编码orient Rotation to Movement,给个默认转向速率GetCharacterMovement()->bOrientRotationToMovement = true;GetCharacterMovement()->RotationRate = FRotator(0.f, 500.f, 0.f);//设置跳跃初始值与在空中的坠落时横向运动控制量GetCharacterMovement()->JumpZVelocity = 600.f;GetCharacterMovement()->AirControl = 0.15f;//给键盘控制转向的速率变量赋初值BaseTurnRate = 21.f;BaseLookUpRate = 21.f;
}// Called when the game starts or when spawned
void AMainPlayer::BeginPlay()
{Super::BeginPlay();}// Called every frame
void AMainPlayer::Tick(float DeltaTime)
{Super::Tick(DeltaTime);}// Called to bind functionality to input
void AMainPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{Super::SetupPlayerInputComponent(PlayerInputComponent);//检查PlayerInputComponent指针,check函数只能在这使用check(PlayerInputComponent);//绑定跳跃轴映射事件PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &AMainPlayer::Jump);//按下空格PlayerInputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping);//抬起空格//绑定移动轴映射事件PlayerInputComponent->BindAxis("MoveForward", this, &AMainPlayer::MoveForward);PlayerInputComponent->BindAxis("MoveRight", this, &AMainPlayer::MoveRight);//绑定Controller控制器去管理视角旋转PlayerInputComponent->BindAxis("Turn", this, &AMainPlayer::Turn);PlayerInputComponent->BindAxis("LookUp", this, &AMainPlayer::LookUp);//绑定键盘鼠标轴映射事件PlayerInputComponent->BindAxis("TurnRate", this, &AMainPlayer::TurnRate);PlayerInputComponent->BindAxis("LookUpRate", this, &AMainPlayer::LookUpRate);}void AMainPlayer::Jump()
{//继承父类的方法Super::Jump();
}void AMainPlayer::MoveForward(float value)
{if (Controller != nullptr && value != 0.f){//获取到Control旋转FRotator Rotation = Controller->GetControlRotation();//转向只关注水平Yaw方向,因此置0防止影响FRotator YowRotation = FRotator(0.0f, Rotation.Yaw, 0.0f);//获取相机(鼠标控制器的朝向),并且朝这个轴的方向移动FVector Direction = FRotationMatrix(YowRotation).GetUnitAxis(EAxis::X);AddMovementInput(Direction, value);}}void AMainPlayer::MoveRight(float value)
{if (Controller != nullptr && value != 0.f){//获取到Controller旋转FRotator Rotation = Controller->GetControlRotation();//转向只关注水平Yaw方向,因此置0防止影响FRotator YowRotation = FRotator(0.0f, Rotation.Yaw, 0.0f);//获取相机(鼠标控制器的朝向),并且朝这个轴的方向移动FVector Direction = FRotationMatrix(YowRotation).GetUnitAxis(EAxis::Y);AddMovementInput(Direction, value);}
}void AMainPlayer::Turn(float Value)
{if (Value != 0.f){AddControllerYawInput(Value);}}void AMainPlayer::LookUp(float Value)
{//UE_LOG(LogTemp, Warning, TEXT("%f"), GetControlRotation().Pitch);// //控制视角if (GetControlRotation().Pitch < 270.f && GetControlRotation().Pitch >180.f && Value > 0.f){return;}else if (GetControlRotation().Pitch < 180.f && GetControlRotation().Pitch >45.f && Value < 0.f){return;}AddControllerPitchInput(Value);
}void AMainPlayer::TurnRate(float Rate)
{//要乘以一个DeltaTime这样就可以避免高帧底帧差值问题float Value = Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds();if (Value != 0.f){AddControllerYawInput(Value);}
}void AMainPlayer::LookUpRate(float Rate)
{//要乘以一个DeltaTime这样就可以避免高帧底帧差值问题float Value = Rate * BaseLookUpRate * GetWorld()->GetDeltaSeconds();//控制视角if (GetControlRotation().Pitch < 270.f && GetControlRotation().Pitch >180.f && Value > 0.f){return;}else if (GetControlRotation().Pitch < 180.f && GetControlRotation().Pitch >45.f && Value < 0.f){return;}AddControllerPitchInput(Value);}

混合空间(BlendSpace)

  • 创建BlendSpace1D,并给出相应的骨骼

在这里插入图片描述

  • 将相应的行走、奔跑、动画添加上去

在这里插入图片描述

动画蓝图的创建

  • 创建动画蓝图,选择自己的骨骼
    在这里插入图片描述
    在这里插入图片描述

创建给动画蓝图提供逻辑的AnimInstance子类

  • 创建AnimInstance子类
    在这里插入图片描述
  • 写入判断是否奔跑与跳跃的变量,MainPlayer类的指针方便到时候好获取参数参与UE反射,重写NativeInitializeAnimation,这个函数类似与BeginPlay,然后加入一个实时更新的函数在Animation蓝图中使用
  • MainPlayerAnimation.h
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "Animation/AnimInstance.h"
#include "MainPlayerAnimInstance.generated.h"/*** */
UCLASS()
class UEGAME_API UMainPlayerAnimInstance : public UAnimInstance
{GENERATED_BODY()public:UPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category="Animation Properties")float Speed;//判断速度是否达到奔跑UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Animation Properties")bool bIsAir;//判断是否跳跃UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Animation Properties")class AMainPlayer* Player;virtual void NativeInitializeAnimation() override; //类似与BeginPlayUFUNCTION(BlueprintCallable, Category = "Animation Properties")void UpdataAnimationProperties();//实时更新
};
  • MainPlayerAnimtion.cpp
// Fill out your copyright notice in the Description page of Project Settings.#include "MainPlayerAnimInstance.h"void UMainPlayerAnimInstance::NativeInitializeAnimation()
{}void UMainPlayerAnimInstance::UpdataAnimationProperties()
{}

编写动画参数更新逻辑并给动画蓝图指定父类

  • MainPlayerAnimtion.cpp
  • TryGetPawnOwner:获取角色的Pawn类
  • GetVelocity:获取速度
// Fill out your copyright notice in the Description page of Project Settings.#include "MainPlayerAnimInstance.h"
#include "Characters/Player/MainPlayer.h"
#include "GameFramework/CharacterMovementComponent.h"
void UMainPlayerAnimInstance::NativeInitializeAnimation()
{Player = Cast<AMainPlayer>(TryGetPawnOwner());//获取角色的Pawn类
}void UMainPlayerAnimInstance::UpdataAnimationProperties()
{//防御性编程if (Player){//移动只需要平面的速度FVector SpeedVector = Player->GetVelocity();FVector PlanarSpeed = FVector(SpeedVector.X, SpeedVector.Y, 0.f);//将移动的向量传给speed即可Speed = PlanarSpeed.Size();bIsAir = Player->GetMovementComponent()->IsFalling();//判断Player是否在下落}else {Player = Cast<AMainPlayer>(TryGetPawnOwner());//获取角色的Pawn类}}
  • 给动画蓝图指定父类
    在这里插入图片描述

制作移动动画设置到角色

  • 连接我们的更新函数
    在这里插入图片描述
  • 新建一个状态机
    在这里插入图片描述
  • 在状态机里面在添加一个状态
    在这里插入图片描述
  • 然后再到此状态里面把混合空间与编码的speed加上
    在这里插入图片描述
  • 返回最开始的动画图表连接上最终动画
    在这里插入图片描述
  • 最后将混合空间添加到角色蓝图Mesh的Animation中就可
    在这里插入图片描述

制作跳跃动画设置到角色

  • 将跳跃的三个状态添加到状态机中
    在这里插入图片描述

  • 首先判断是否起跳,用C++编写好的变量进行判断
    在这里插入图片描述

  • 监测起跳动作,当跳跃动作快播放完了的时候就得开始切换,一般我们常用这个Timer Remaining(ratio):剩余计时器(比例)来进行使用判断监测
    在这里插入图片描述

  • 判断是否落下
    在这里插入图片描述

  • 监测落下动作,当跳跃动作快播放完了的时候就得开始切换,一般我们常用这个Timer Remaining(ratio):剩余计时器(比例)来进行使用判断监测
    在这里插入图片描述

  • 运行结果
    请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/161325.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux学习第32天:Linux INPUT 子系统实验(一):接纳

Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长 题目中用了“接纳”俩字。其实学习就是一个接纳的过程。接纳新的知识&#xff0c;从而转化为自己知识宝库的一部分。那今天学习的input子系统和今天的主题接纳有…

C++入门指南:string类文档详细解析(非常经典,建议收藏)

C入门指南&#xff1a;string类 一、 string类解读二、 string类的常用接口说明2.1 string类对象的常见构造2.2 string类对象的容量操作2.3 string类对象的访问及遍历操作2.4 string类对象的修改操作2.5 string类非成员函数 一、 string类解读 string类文档 具体如下&#xff…

论文阅读——What Can Human Sketches Do for Object Detection?(cvpr2023)

论文&#xff1a;https://openaccess.thecvf.com/content/CVPR2023/papers/Chowdhury_What_Can_Human_Sketches_Do_for_Object_Detection_CVPR_2023_paper.pdf 代码&#xff1a;What Can Human Sketches Do for Object Detection? (pinakinathc.me) 一、 Baseline SBIR Fram…

eBPF BCC开源工具简介

目录 官方链接 编译安装 ubuntu版本 安装 examples tools hello_world.py demo 运行报错 网上目前的解决办法 错误分析过程 python版本检测 libbcc库检查 python3 bcc库检查 正常输出 监控进程切换 运行输出 监控CPU直方图 缓存命中率监控&#xff1a;caches…

uni-app学习笔记

目录 一、前期准备 1、项目认识 2、pages.json基本配置 3、创建页面 二、tabBar 1、获取图标 2、代码配置 三、基础认识 1、页面生命周期 2、App.vue应用生命周期 四、基础组件 1、scroll-view可滚动视图区域 2、提示框 3、swiper滑块视图容器 4、form表单组件 一…

5.数据表基本操作

目录 1.创建数据表 创建数据表的语法格式&#xff1a; 查看当前数据库的表&#xff1a; 主键 1.单字段主键 (1)在定义列的同时指定主键&#xff0c;语法规则如下&#xff1a; (2)在定义完所有列之后指定主键。 2.多字段联合主键 外键&#xff1a; 非空约束&#xff1…

uniapp: 前端利用百度云OCR实现文字识别(身份证识别功能,别的功能类似)

第一章 前言 介绍如何使用百度智能云实现我们想要的效果&#xff0c;需要在下面这个网址注册账号&#xff1a; 百度智能云-云智一体深入产业 使用文档在该网址上&#xff1a; 简介 - 文字识别OCR 请求成功的效果&#xff0c;如下图&#xff1a; 搜索产品&#xff08;例如文字…

python脚本-网页爬虫获取网页图片

python脚本-网页爬虫获取网页图片 代码 import requests import re import time url"http://10.9.47.154/python-spider/" # 爬取网站的url headers {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like …

Linux中的高级IO

文章目录 1.IO1.1基本介绍1.2基础io的低效性1.3如何提高IO效率1.4五种IO模型1.5非阻塞模式的设置 2.IO多路转接之Select2.1函数的基本了解2.2fd_set理解2.3完整例子代码&#xff08;会在代码中进行讲解&#xff09;2.4优缺点 3.多路转接之poll3.1poll函数的介绍3.2poll服务器3.…

51单片机汇编-点亮一个led

文章目录 前言1.打开IDE2.设置编辑器3.设置输出4. 原理图5.编写代码6 编译7.下载8.其它代码1.LED闪烁2.跑马灯 前言 51单片机基础 本章主要介绍打开一个led,具体采用51汇编 1.打开IDE 选择STC89C52RC 后缀是.asm 2.设置编辑器 3.设置输出 4. 原理图 5.编写代码 ORG 00H;伪代…

linux之按键中断

查看原理图确认引脚 可以看到按键有两个&#xff0c;分别对应GPIO5_1和GPIO4_14 配置pinctrl&#xff0c;配置成GPIO模式 1.使用官方工具&#xff0c;配置下引脚 2.将生成的代码复制到设备树里 创建设备节点 生成二进制设备树文件 在工具链表下使用 make dtbs 或者使…

加法运算、 || 、 赋值运算

一、加法运算 在这里插入图片描述 二、&& || 三、赋值运算 四、js类型就八种&#xff1a; 五、css权重、 六&#xff1a;布局&#xff0c;尽量使用块盒。 七、小数精度存储的问题&#xff1a;存的不精确&#xff0c;算的肯定也是有问题的。 八、找单身狗算法题…