ue4c++日记5(贴墙走的球)

原视频地址:调整视角_哔哩哔哩_bilibili

 MyPawn头文件

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "MyPawn.generated.h"

UCLASS()
class TEST_API AMyPawn : public APawn
{
	GENERATED_BODY()

public:
	// Sets default values for this pawn's properties
	AMyPawn();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

	// Called to bind functionality to input
	virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

	UPROPERTY(VisibleAnywhere)
		class UStaticMeshComponent* MyMesh;//模型
	UPROPERTY(VisibleAnywhere)
		class UCameraComponent* Camera;//摄像机
	/*UPROPERTY(EditAnywhere)
		FVector CurrentVelocity;//当前向量
	UPROPERTY(EditAnywhere)
		float MaxSpeed;//最大速度*/

	UPROPERTY(VisibleAnywhere)
		class USphereComponent* SphereComp;//球形组件
	UPROPERTY(VisibleAnywhere)
		class USpringArmComponent* SprintArmComp;//弹簧臂 

	UPROPERTY(VisibleAnywhere)
		class UMyMovementComponent* MovementComp;
	virtual UPawnMovementComponent* GetMovementComponent() const override;//重写
private:
	void MoveForward(float Value);//向前函数
	void MoveRight(float Value);//向右函数

	void CameraPitch(float Value);//抬头低头
	void CameraYaw(float Value);//左右看
	FVector2D CameraInput;//记录CameraPitch和CameraYaw
};

 MyPawn代码文件

// Fill out your copyright notice in the Description page of Project Settings.


#include "MyPawn.h"
#include "Components/StaticMeshComponent.h"
#include "Camera/CameraComponent.h"

#include "Components/SphereComponent.h"//球体头文件
#include "UObject/ConstructorHelpers.h"//help帮助
#include "GameFramework/SpringArmComponent.h"//弹簧臂头文件
#include "MyMovementComponent.h"
// Sets default values
AMyPawn::AMyPawn()
{

	//RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));//设定根组件
 	// Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
	/// <summary>
	/// 根组件
	/// </summary>
	SphereComp = CreateDefaultSubobject<USphereComponent>(TEXT("Sphere"));//对象创建为球体
	SphereComp->SetSphereRadius(80);//设置球体半径
	SphereComp->SetCollisionProfileName(TEXT("BlockAll"));//设置球体碰撞
	SphereComp->SetHiddenInGame(false);//设置可见性
	SetRootComponent(SphereComp);

	/// <summary>
	/// 移动物体
	/// </summary>
	MyMesh = CreateDefaultSubobject<UStaticMeshComponent >(TEXT("Mesh"));//设定一个静态网格体
	MyMesh->SetupAttachment(GetRootComponent());//将静态网格体绑定到根组件下
	//将网格资源赋值给静态网格对象
	static ConstructorHelpers::FObjectFinder<UStaticMesh> MeshComponentAsset(TEXT("StaticMesh'/Engine/EditorMeshes/ArcadeEditorSphere.ArcadeEditorSphere'"));
	if (MeshComponentAsset.Succeeded()) {
		MyMesh->SetStaticMesh(MeshComponentAsset.Object);//将资产赋值给模型
		MyMesh->SetRelativeLocation(FVector(0, 0, -50));//设置在对象的相对位置
		MyMesh->SetRelativeScale3D(FVector(0.2, 0.2, 0.2));//物体大小设置为0.2,0.2,0.2
	}
	/// <summary>
	/// 弹簧臂组件
	/// 更好的模拟运动
	/// </summary>
	SprintArmComp = CreateDefaultSubobject<USpringArmComponent>(TEXT("SprintArm"));
	SprintArmComp->SetupAttachment(GetRootComponent());
	SprintArmComp->TargetArmLength = 400;//弹簧臂长度
	SprintArmComp->SetRelativeRotation(FRotator(-45.f, 0, 0));
	SprintArmComp->bEnableCameraLag = true;//打开弹簧臂功能
	SprintArmComp->CameraLagSpeed = 3;//弹簧臂速度


	Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));//摄像机实例化
	Camera->SetupAttachment(SprintArmComp, USpringArmComponent::SocketName);//将摄像机插入弹簧臂的插槽中

	//Camera->SetupAttachment(GetRootComponent());
	//Camera->SetRelativeLocation(FVector(-300,0,300));
	//Camera->SetRelativeRotation(FRotator(-45.f,0,0));

	//CurrentVelocity = FVector(0.f);//当前速度
	//MaxSpeed = 200.f;//最大速

	AutoPossessPlayer = EAutoReceiveInput::Player0;//0号玩家

	MovementComp = CreateDefaultSubobject <UMyMovementComponent>(TEXT("UMyMovementComponent"));
	MovementComp->UpdatedComponent = RootComponent;//运动更新的组件设置为 “根组件”
	
	CameraInput = FVector2D(0.f, 0);
}

// Called when the game starts or when spawned
void AMyPawn::BeginPlay()
{
	Super::BeginPlay();
	
}

// Called every frame
void AMyPawn::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
	//建议是下面这种写法,其他两种写法试过不行
	//左右看 
	FRotator NewRotation = GetActorRotation();
	NewRotation.Yaw += CameraInput.X;
	SetActorRotation(NewRotation);

	//上下看
	FRotator NewSprintArmRotationUp = SprintArmComp->GetComponentRotation();
	NewSprintArmRotationUp.Pitch += CameraInput.Y;
	NewSprintArmRotationUp.Pitch = FMath::Clamp(NewSprintArmRotationUp.Pitch, -80.f, 80.f);
	SprintArmComp->SetWorldRotation(NewSprintArmRotationUp);
	//设定对象位置
	SetActorLocation(GetActorLocation() + MovementComp->Velocity * DeltaTime);//设定对象位置
}

// Called to bind functionality to input
void AMyPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);
	/// <summary>
	/// 绑定玩家输入
	/// 橙色字——对应UE4的轴映射的字
	/// this——应该是这个对象
	/// 最后——UE4按键响应后传值给到这个方法
	/// </summary>
	PlayerInputComponent->BindAxis("MoveForward", this, &AMyPawn::MoveForward);
	PlayerInputComponent->BindAxis("MoveRight", this, &AMyPawn::MoveRight);
	PlayerInputComponent->BindAxis("CameraPitch", this, &AMyPawn::CameraPitch);
	PlayerInputComponent->BindAxis("CameraYaw", this, &AMyPawn::CameraYaw);
}
#if 1
UPawnMovementComponent* AMyPawn::GetMovementComponent() const
{
	//重写了移动组件,因为引用了mymovementcomponent的贴墙走
	return MovementComp;
}
#endif

//前后左右移动
void AMyPawn::MoveForward(float Value)
{
	//AddInputVector生产者,增加燃料。对应mymovementcomponent中的ConsumeInputVector()(消费者)
	if (MovementComp) {
		MovementComp->AddInputVector(GetActorForwardVector()*Value);

		//UE_LOG(LogTemp, Warning, TEXT("@@s Hit@:x=%s,y=%s,z=%s"), *FString::SanitizeFloat(GetActorForwardVector().X), *FString::SanitizeFloat(GetActorForwardVector().Y), *FString::SanitizeFloat(GetActorForwardVector().Z));

	}
	//clamp约束数值在-1到1
	//CurrentVelocity.X = FMath::Clamp(Value, -1.f, 1.f) * MaxSpeed;
}

void AMyPawn::MoveRight(float Value)
{
	if (MovementComp) {
		MovementComp->AddInputVector(GetActorRightVector()*Value);
	}
}

//上下左右看
void AMyPawn::CameraPitch(float Value)
{
	CameraInput.X = Value;
}

void AMyPawn::CameraYaw(float Value)
{
	CameraInput.Y = Value;
}


MyMovementComponent头文件

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/PawnMovementComponent.h"
#include "MyMovementComponent.generated.h"

/**
 * 
 */
UCLASS()
class TEST_API UMyMovementComponent : public UPawnMovementComponent
{
	GENERATED_BODY()
public:
	virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)override;
	
};

MyMovementComponent代码文件

// Fill out your copyright notice in the Description page of Project Settings.


#include "MyMovementComponent.h"


void UMyMovementComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
	//没有运动组件拥有者||运动更新时的依据组件||是否跳过更新(如果对象被遮挡就不会计算进行)
	if (!PawnOwner||!UpdatedComponent|| ShouldSkipUpdate(DeltaTime)) {
		return;
	}
	FVector DeltaMovement
		= ConsumeInputVector().GetClampedToMaxSize(2) * DeltaTime * 150;
	
	if (!DeltaMovement.IsNearlyZero()) {//检查DeltaMovement是否接近0
		FHitResult HitResult;//碰撞结果

		SafeMoveUpdatedComponent(DeltaMovement,
			UpdatedComponent->GetComponentRotation(), true, HitResult);//开启了避险
		
		//如果撞到东西,贴墙走
		if (HitResult.IsValidBlockingHit()) {
			/// <summary>
			/// 
			/// </summary>
			/// <param name="DeltaTime">运动变化量</param>
			/// <param name="1 - HitResult.Time">(照抄)</param>
			/// <param name="HitResult.Normal">法向量</param>
			/// <param name="HitResult">撞击信息</param>
			SlideAlongSurface(DeltaMovement,
				1 - HitResult.Time, HitResult.Normal, HitResult);
		}
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_56537692/article/details/128748570