UE4学习监督——C++人物移动

上一次我们尝试新建一个关卡。这一次我们尝试创建一个可以移动的人物。

首先需要做一些准备工作,针对vs不能自动补全头文件这一问题可以安装reshaper插件,可帮助补全。如果不安装插件且不知道头文件名称可复制相关类名查询API。

网络上相关教程很多,在此我只选取官方Demo给出的源码,尝试以这种方式让人物动起来。

首先我们在内容浏览器中创建一个新的C++类,命名为HeroDemo,继承自Character类。

在这里插入图片描述

我们在头文件中做一些声明:

UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Camera)
	class USpringArmComponent* CameraBoom;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Camera)
	class UCameraComponent* FollowCamera;

protected:
	void MoveForward(float Axis);
//设置人物前进
	void MoveRight(float Axis);
//设置人物向右移动
public:
	FORCEINLINE class USpringArmComponent* GetCamera() const { return CameraBoom; }
	FORCEINLINE class UCameraComponent* GetFollowCamera() const { return FollowCamera; }
	

UPROPERTY通常用于说明一些状态,如是否在其他位置可以编辑、是否可以被蓝图读取等,其中Category通常表示在编辑器的名称。

USpringArmComponent 为一个组件类,它提供相机的弹簧臂,可以实现视角的移动等。

UCameraComponent 为相机组件类,在可以提供视野等。

FORCEINLINE 是c++关键字 用于内联函数。区别于inline,FORCEINLINE 根据程序员判断进行内联,而非根据编辑器性能和优化分析。

头文件已经编写完成,现在我们开始完成具体内容。

AHeroDemo::AHeroDemo()
{
    //设置输入控制默认玩家
	AutoPossessPlayer = EAutoReceiveInput::Player0;
    
 	// 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;
    
//设置碰撞体积大小
	GetCapsuleComponent()->InitCapsuleSize(42.f, 96.f);
	
//保证控制器不会随视角反转
	bUseControllerRotationPitch = false;
	bUseControllerRotationRoll = false;
	bUseControllerRotationYaw = false;

//获取人物移动,此为Character内置
	GetCharacterMovement()->bOrientRotationToMovement = true;
	GetCharacterMovement()->RotationRate = FRotator(0.0f, 540.0f, 0.0f);
	GetCharacterMovement()->JumpZVelocity = 600.0f;//跳跃速度
	GetCharacterMovement()->AirControl = 0.2f;

	//设置弹簧臂
	CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));//创建默认组件
	CameraBoom->SetupAttachment(RootComponent);//附加到根组件
	CameraBoom->TargetArmLength = 300.0f;//弹簧臂长度
	CameraBoom->bUsePawnControlRotation = true;//设置是否根据输入控制旋转

	//设置相机
	FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));
	FollowCamera->SetupAttachment(CameraBoom, USpringArmComponent::SocketName);
	FollowCamera->bUsePawnControlRotation = false;

}

CreateDefaultSubobject 该函数是个模板函数,用于创建组件或子对象,然后返回指向新建组件内存区域的指针。

关于bOrientRotationToMovement

在这里插入图片描述

用于更新人物的旋转。

关于SocketName问题

在这里插入图片描述

指弹簧臂末端位置

下面开始绑定按键

void AHeroDemo::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
//用于绑定函数和按键,保证输入
    Super::SetupPlayerInputComponent(PlayerInputComponent);
//check用于检查指针
	check(PlayerInputComponent);
	PlayerInputComponent->BindAction(("Jump"), IE_Pressed, this, &ACharacter::Jump);
	PlayerInputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping);

	PlayerInputComponent->BindAxis("MoveForward", this, &AHeroDemo::MoveForward);
	PlayerInputComponent->BindAxis("MoveRight", this, &AHeroDemo::MoveRight);
	PlayerInputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
	PlayerInputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);
}

BindAction用于绑定触发事件,如跳跃等。

第一个参数为名称,之后再编辑器中需要设置

第二个为触发条件,如IE_Pressed和IE_Released表示按下/松开触发。

第三个为执行主体,通常为this

第四个为调用函数。

这里调用了ACaharacter和Apawn的一些函数,这也是为何继承Character类的原因,因为UE4底层已经给我们编写好了基础的移动,我们只需要调用就可以。当然或许高层次的开发会需要重写底层代码,在此不做考虑。

然后需要在编辑器中设置绑定

在这里插入图片描述

点击编辑->项目设置->输入,并进行如下设置:

向后和向左移动只需要将值设为复数即可完成。

下面编写移动的函数

void AHeroDemo::MoveForward(float Axis)
{
	if((Controller!=NULL)&(Axis!=0.0f))
	{
		const FRotator Rotation = Controller->GetControlRotation();
		const FRotator YawRotation(0, Rotation.Yaw, 0);

		const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
		AddMovementInput(Direction, Axis);
	}
}

void AHeroDemo::MoveRight(float Axis)
{
	if ((Controller != NULL) & (Axis != 0.0f))
	{
		const FRotator Rotation = Controller->GetControlRotation();
		const FRotator YawRotation(0, Rotation.Yaw, 0);

		const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
		AddMovementInput(Direction, Axis);
	}
		
}

两段代码很相似。大体模式是首先获得控制器的旋转,之后选择性输入一个方向的旋转。FRotationMatrix为矩阵结构,可以让一个物体轻松地转向另一个物体。这里应该是让actor转向controller的方向,从而实现人物转动。GetUnitAxis()将获取的控制器左右旋转角度转化为旋转后x/y轴方向的单位向量存为Direction(要去的方向)。最后AddMoveMentInput添加移动,两个方向为方向和长度。在Pawn和Character类中,底层为我们写好按帧刷新读取,故不用额外操作。

在这里插入图片描述

到此代码已经完成,下面回到编辑器编译,运行。成功。

向量存为Direction(要去的方向)。最后AddMoveMentInput添加移动,两个方向为方向和长度。在Pawn和Character类中,底层为我们写好按帧刷新读取,故不用额外操作。

[外链图片转存中…(img-sdlH6uKn-1635072344978)]

到此代码已经完成,下面回到编辑器编译,运行。成功。

以上许多都是个人理解和感受,如有不正确、不到位的地方希望大家指正。

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值