.vs
这个缓存文件夹,和这三个Binaries,Intermediate,项目名.sln文件
文件,然后右键项目名.uproject文件
,里面会有重新构建项目的选项,重新构建项目除错#include "Engine/Engine.h"
#include "UObject/ConstructorHelpers.h"
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Properties")
class UStaticMeshComponent* StaticMesh;
//上面是.h中Public的内容-------------------------------------------------------------------------------------------------------
#include "MyActor_One.h"
#include "Engine/Engine.h"
#include "UObject/ConstructorHelpers.h"
#include "Components/StaticMeshComponent.h"
// Sets default values
AMyActor_One::AMyActor_One()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
StaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMesh"));
RootComponent = StaticMesh;
//硬编码材质与网格
ConstructorHelpers::FObjectFinder<UStaticMesh> StaticMeshAsset(TEXT("/Script/Engine.StaticMesh'/Engine/BasicShapes/Sphere.Sphere'"));
ConstructorHelpers::FObjectFinder<UMaterialInterface> MaterialAsset(TEXT("/Script/Engine.Material'/Engine/BasicShapes/BasicShapeMaterial.BasicShapeMaterial'"));
if (StaticMeshAsset.Succeeded() && MaterialAsset.Succeeded())
{
StaticMesh->SetStaticMesh(StaticMeshAsset.Object);
StaticMesh->SetMaterial(0, MaterialAsset.Object);
}
}
// Called when the game starts or when spawned
void AMyActor_One::BeginPlay()
{
Super::BeginPlay();
UE_LOG(LogTemp, Warning, TEXT("Hello World"));
UE_LOG(LogTemp, Warning, TEXT("Hello World"));
UE_LOG(LogTemp, Error, TEXT("Hello World"));
//这里的-1可以使用INDEX_NONE,INDEX_NONE也是-1,UE的宏
GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("Hello World")));
}
UPROPERTY()
VisibleAnywhere
:在蓝图中与视口中都可见VisibleDefaultsOnly
:只在蓝图中可见VisibleInstanceOnly
:只在视口中可见EditAnywhere
:在蓝图中与视口中都可编辑EditDefultsOnly
:在蓝图中可编辑EditInstanceOnly
:在视口中可编辑BlueprintReadOnly
:在蓝图中可读BlueprintReadWrite
:在蓝图中可读可写Category
:标签meta = (MakeEditWidget = "true")
:这是一个可选的元标记(Metadata),用于添加额外的属性信息。在这种情况下,MakeEditWidget 被设置为 “true”,这表示该属性可以在编辑器中作为一个小部件进行编辑。这通常用于自定义编辑器小部件以提供更直观的属性编辑体验。meta
=(ClampMin
= -10,ClampMax
= 10, UIMin
= -10, UIMax
= 10)):clamp:键盘输入值控制,ui:鼠标拉动值控制meta = (AllowPrivateAccess = "true")
:可以让内部的其他成员访问UFUNCTION()
BlueprintNativeEvent
:BlueprintNativeEvent关键词允许在Unreal Engine蓝图中声明本地事件,并通过C++进行实现和扩展。在C++中实现一个蓝图本地事件时,需要在函数名后添加_Implementation
作为后缀。这是为了区分虚函数和其实现函数,并保持代码的一致性和清晰度,总的来说就是会在C++中提供一个默认的实现,然后蓝图中去覆盖它改写它,在蓝图中实现这个函数时,如果调用一个父类的版本,它会先调用C++里面加了
_Implementation这个函数,然后再去做蓝图其他的操作
BlueprintCallable
:允许函数在蓝图中进行调用BlueprintImplementableEvent
:会把函数变成一个事件,把函数提升为事件后,就不能去初始化函数了,因为这个是在蓝图调用的事件Category
:标签项目名.Build.cs
里面,这个完成后,最好是删除那几个文件重新构建一下避免一下后续的bug,项目目录探索那章
FInputActionValue
的结构体要添加头文件#include "InputActionValue.h"
在当前.h
文件中public:
//映射绑定
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input", meta = (AllPrivateAccess = "true"))
class UInputMappingContext* DefaultMappingContext;
//移动绑定
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input", meta = (AllPrivateAccess = "true"))
class UInputAction* MoveAction;
protected:
void CharacterMove(const FInputActionValue& value);
void AMyCharacter::CharacterMove(const FInputActionValue& value)
{
FVector2D MovementVector = value.Get<FVector2D>();//获取速度
if (Controller!=nullptr)
{
FRotator Rotation = Controller->GetControlRotation();
FRotator YawRotation = FRotator(0, Rotation.Yaw, 0);
//获取到前后单位向量
FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
//获取左右单位向量
FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
AddMovementInput(ForwardDirection, MovementVector.Y);
AddMovementInput(RightDirection, MovementVector.X);
}
}
已知虚幻中的X:Pitch,Y:Yaw,Z:Roll
我们获取到FInputActionValue
这个结构体中的FVector2D,注意这里是FVector2D,这是数学平面坐标系
FVector2D MovementVector = value.Get
而在UE三维移动中,我们只需要关注Yaw(也就是Y)
FRotator YawRotation = FRotator(0, Rotation.Yaw, 0);
然后在虚幻中默认为右方向以角色右手为正方向,所以那平面坐标系里面X是不是就是前后了,Y是左右
FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
此时我们已经得到了前后左右的单位向量后,回到开始的逻辑因为UE5增强输入系统传入的是FInputActionValue
结构体了,然后获取的是FVector2D这是个数学平面坐标系,所以添加到角色移动中,这里前后就是数学平面坐标系的Y了,左右就是X了
AddMovementInput(ForwardDirection, MovementVector.Y);
AddMovementInput(RightDirection, MovementVector.X);
PlayerInputComponent转换为UEnhancedInputComponent
,然后进行绑定为了增强型输入系统,这里需要头文件#include "EnhancedInputComponent.h"
来使用UEnhancedInputComponent
组件BindAction(MoveAction, ETriggerEvent::Triggered, this, &AMyCharacter::CharacterMove);
MoveAction
:之前定义的移动绑定UInputAction
类ETriggerEvent::Triggered
:触发发生在一个或多个处理节拍之后,一般用Triggered比较多,其他不常用this
:自身来进行绑定&AMyCharacter::CharacterMove
:处理函数// Called to bind functionality to input
void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(PlayerInputComponent);
if (EnhancedInputComponent)
{
//移动绑定
EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AMyCharacter::CharacterMove);
}
}
Controller转换为APlayerController
,成功后使用UEnhancedInputLocalPlayerSubsystem
将本地玩家使用增强型输入系统需要使用头文件:#include "EnhancedInputSubsystems.h"
,成功后就绑定映射// Called when the game starts or when spawned
void AMyCharacter::BeginPlay()
{
Super::BeginPlay();
APlayerController* PlayerController = Cast<APlayerController>(Controller);
if (PlayerController)
{
UEnhancedInputLocalPlayerSubsystem* Subsystem =
ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer());
if (Subsystem)
{
//映射到上下文
Subsystem->AddMappingContext(DefaultMappingContext, 0);
}
}
}
//视角绑定
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input", meta = (AllPrivateAccess = "true"))
class UInputAction* LookAction;
void CharacterLook(const FInputActionValue& value);
void AMyCharacter::CharacterLook(const FInputActionValue& value)
{
FVector2D LookAxisVector = value.Get<FVector2D>();
if (Controller != nullptr)
{
AddControllerPitchInput(LookAxisVector.Y);
AddControllerYawInput(LookAxisVector.X);
}
}
// Called to bind functionality to input
void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(PlayerInputComponent);
if (EnhancedInputComponent)
{
//移动绑定
EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AMyCharacter::CharacterMove);
EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &AMyCharacter::CharacterLook);
}
}
FInputActionValue
结构体中的FVector2D
二维向量void AMyCharacter::CharacterLook(const FInputActionValue& value)
{
FVector2D LookAxisVector = value.Get<FVector2D>();
if (Controller != nullptr)
{
GEngine->AddOnScreenDebugMessage(1, 10, FColor::Red, FString::Printf(TEXT("%f"),(GetControlRotation().Pitch)));
AddControllerYawInput(LookAxisVector.X);
if (GetControlRotation().Pitch < 270.f && GetControlRotation().Pitch>180.f && LookAxisVector.Y > 0.f)
{
return;
}
if (GetControlRotation().Pitch < 180.f && GetControlRotation().Pitch>45.f && LookAxisVector.Y < 0.f)
{
return;
}
AddControllerPitchInput(LookAxisVector.Y);
}
}
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "InputActionValue.h"
#include "MyCharacter.generated.h"
UCLASS()
class MYOBJECTUE5_API AMyCharacter : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
AMyCharacter();
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera", meta = (AllPrivateAccess = "true"))
class USpringArmComponent* SpringArm;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera", meta = (AllPrivateAccess = "true"))
class UCameraComponent* MyCamera;
//映射绑定
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input", meta = (AllPrivateAccess = "true"))
class UInputMappingContext* DefaultMappingContext;
//移动绑定
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input", meta = (AllPrivateAccess = "true"))
class UInputAction* MoveAction;
//视角绑定
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input", meta = (AllPrivateAccess = "true"))
class UInputAction* LookAction;
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
void CharacterMove(const FInputActionValue& value);
void CharacterLook(const FInputActionValue& value);
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "MyCharacter.h"
#include "Camera/CameraComponent.h"
#include "GameFramework/SpringArmComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"
#include "Engine/Engine.h"
// Sets default values
AMyCharacter::AMyCharacter()
{
// 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;
GetCharacterMovement()->bOrientRotationToMovement = true;
GetCharacterMovement()->RotationRate = FRotator(0.f, 500.f, 0.f);
GetCharacterMovement()->MaxWalkSpeed = 500.f;
GetCharacterMovement()->MinAnalogWalkSpeed = 20.f;
GetCharacterMovement()->BrakingDecelerationWalking = 2000.f;
//相机臂
SpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArm"));
SpringArm->SetupAttachment(GetRootComponent());
SpringArm->TargetArmLength = 400.f;
SpringArm->bUsePawnControlRotation = true;
//相机
MyCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("MyCamera"));
MyCamera->SetupAttachment(SpringArm, USpringArmComponent::SocketName);//附加到末尾
MyCamera->bUsePawnControlRotation = false;
}
// Called when the game starts or when spawned
void AMyCharacter::BeginPlay()
{
Super::BeginPlay();
APlayerController* PlayerController = Cast<APlayerController>(Controller);
if (PlayerController)
{
UEnhancedInputLocalPlayerSubsystem* Subsystem =
ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer());
if (Subsystem)
{
//映射到上下文
Subsystem->AddMappingContext(DefaultMappingContext, 0);
}
}
}
void AMyCharacter::CharacterMove(const FInputActionValue& value)
{
FVector2D MovementVector = value.Get<FVector2D>();//获取速度
if (Controller!=nullptr)
{
FRotator Rotation = Controller->GetControlRotation();
FRotator YawRotation = FRotator(0, Rotation.Yaw, 0);
//获取到前后单位向量
FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
//获取左右单位向量
FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
AddMovementInput(ForwardDirection, MovementVector.Y);
AddMovementInput(RightDirection, MovementVector.X);
}
}
void AMyCharacter::CharacterLook(const FInputActionValue& value)
{
FVector2D LookAxisVector = value.Get<FVector2D>();
if (Controller != nullptr)
{
GEngine->AddOnScreenDebugMessage(1, 10, FColor::Red, FString::Printf(TEXT("%f"),(GetControlRotation().Pitch)));
AddControllerYawInput(LookAxisVector.X);
if (GetControlRotation().Pitch < 270.f && GetControlRotation().Pitch>180.f && LookAxisVector.Y > 0.f)
{
return;
}
if (GetControlRotation().Pitch < 180.f && GetControlRotation().Pitch>45.f && LookAxisVector.Y < 0.f)
{
return;
}
AddControllerPitchInput(LookAxisVector.Y);
}
}
// Called every frame
void AMyCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(PlayerInputComponent);
if (EnhancedInputComponent)
{
//移动绑定
EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AMyCharacter::CharacterMove);
EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &AMyCharacter::CharacterLook);
}
}