UE5之5.4 第一人称示例代码阅读2 子弹发射逻辑

TP_WeaponComponent.h

看看头文件

暴露了attach weapon和fire给蓝图

这两个函数意义一看名字吧,就是捡起来枪的时候执行,一个就是发射子弹的时候执行

cpp 复制代码
#pragma once

#include "CoreMinimal.h"
#include "Components/SkeletalMeshComponent.h"
#include "TP_WeaponComponent.generated.h"

class AFirstPersonCharacter;

UCLASS(Blueprintable, BlueprintType, ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class FIRSTPERSON_API UTP_WeaponComponent : public USkeletalMeshComponent
{
	GENERATED_BODY()

public:
	/** Projectile class to spawn */
	UPROPERTY(EditDefaultsOnly, Category=Projectile)
	TSubclassOf<class AFirstPersonProjectile> ProjectileClass;

	/** Sound to play each time we fire */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Gameplay)
	USoundBase* FireSound;
	
	/** AnimMontage to play each time we fire */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Gameplay)
	UAnimMontage* FireAnimation;

	/** Gun muzzle's offset from the characters location */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Gameplay)
	FVector MuzzleOffset;

	/** MappingContext */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Input, meta=(AllowPrivateAccess = "true"))
	class UInputMappingContext* FireMappingContext;

	/** Fire Input Action */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Input, meta=(AllowPrivateAccess = "true"))
	class UInputAction* FireAction;

	/** Sets default values for this component's properties */
	UTP_WeaponComponent();

	/** Attaches the actor to a FirstPersonCharacter */
	UFUNCTION(BlueprintCallable, Category="Weapon")
	bool AttachWeapon(AFirstPersonCharacter* TargetCharacter);

	/** Make the weapon Fire a Projectile */
	UFUNCTION(BlueprintCallable, Category="Weapon")
	void Fire();

protected:
	/** Ends gameplay for this component. */
	UFUNCTION()
	virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;

private:
	/** The Character holding this weapon*/
	AFirstPersonCharacter* Character;
};

看看具体实现

这个是attach

传入character,然后获取到USkeletalMeshComponent,就是mesh1p这个

然后就attach上去,这个rule后面再细了解吧

然后character还要AddInstanceComponent(this)

这里注意attach和add是分开的

完事就可以注册mapping和bindaction了,最后endplay的时候remove掉

cpp 复制代码
bool UTP_WeaponComponent::AttachWeapon(AFirstPersonCharacter* TargetCharacter)
{
	Character = TargetCharacter;

	// Check that the character is valid, and has no weapon component yet
	if (Character == nullptr || Character->GetInstanceComponents().FindItemByClass<UTP_WeaponComponent>())
	{
		return false;
	}

	// Attach the weapon to the First Person Character
	FAttachmentTransformRules AttachmentRules(EAttachmentRule::SnapToTarget, true);
	AttachToComponent(Character->GetMesh1P(), AttachmentRules, FName(TEXT("GripPoint")));

	// add the weapon as an instance component to the character
	Character->AddInstanceComponent(this);

	// Set up action bindings
	if (APlayerController* PlayerController = Cast<APlayerController>(Character->GetController()))
	{
		if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
		{
			// Set the priority of the mapping to 1, so that it overrides the Jump action with the Fire action when using touch input
			Subsystem->AddMappingContext(FireMappingContext, 1);
		}

		if (UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(PlayerController->InputComponent))
		{
			// Fire
			EnhancedInputComponent->BindAction(FireAction, ETriggerEvent::Triggered, this, &UTP_WeaponComponent::Fire);
		}
	}

	return true;
}

再看另外一个fire函数

cpp 复制代码
void UTP_WeaponComponent::Fire()
{
	if (Character == nullptr || Character->GetController() == nullptr)
	{
		return;
	}

	// Try and fire a projectile
	if (ProjectileClass != nullptr)
	{
		UWorld* const World = GetWorld();
		if (World != nullptr)
		{
			APlayerController* PlayerController = Cast<APlayerController>(Character->GetController());
			const FRotator SpawnRotation = PlayerController->PlayerCameraManager->GetCameraRotation();
			// MuzzleOffset is in camera space, so transform it to world space before offsetting from the character location to find the final muzzle position
			const FVector SpawnLocation = GetOwner()->GetActorLocation() + SpawnRotation.RotateVector(MuzzleOffset);
	
			//Set Spawn Collision Handling Override
			FActorSpawnParameters ActorSpawnParams;
			ActorSpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButDontSpawnIfColliding;
	
			// Spawn the projectile at the muzzle
			World->SpawnActor<AFirstPersonProjectile>(ProjectileClass, SpawnLocation, SpawnRotation, ActorSpawnParams);
		}
	}
	
	// Try and play the sound if specified
	if (FireSound != nullptr)
	{
		UGameplayStatics::PlaySoundAtLocation(this, FireSound, Character->GetActorLocation());
	}
	
	// Try and play a firing animation if specified
	if (FireAnimation != nullptr)
	{
		// Get the animation object for the arms mesh
		UAnimInstance* AnimInstance = Character->GetMesh1P()->GetAnimInstance();
		if (AnimInstance != nullptr)
		{
			AnimInstance->Montage_Play(FireAnimation, 1.f);
		}
	}
}

如果有character,也有子弹类projectileclass

拿到world然后spawnActor了一个AFirstPersonProjectile,就是那个子弹,上一章说过这个对象,他创建完毕是具备一个初速度的,所以就实现发射了,然后执行音频播放和动画播放,动画应该是后坐力

这个attach的具体地方如下所示,所以顺道看看pickup

这个是property,且参数用的是这样的,所以逻辑在蓝图里实现,具体就是上面的图

看看cpp文件实现

就是给overlap也就是相交事件绑定一个broadcast(Character)可以触发onPickUp

然后就走蓝图里的流程了

总结

weapon实现attach,然后是pickup component的mesh使用gun,等character碰到gun了就触发onpick 调用attach

attach后,character就有一个枪拿在手里了

鼠标点击就能出发fire函数了就生成sphere飞出去

相关推荐
AA陈超1 天前
虚幻引擎UE5专用服务器游戏开发-33 在上半身播放组合蒙太奇
c++·游戏·ue5·游戏引擎·虚幻
zhangzhangkeji1 天前
cesium126,230130,Editing Tileset Materials - 0,编辑瓦片集材质,官方教程:
ue5
zhangzhangkeji1 天前
cesium126,230131,区域局部染色:赋值材质实例,建立“材质图层混合”文件,建立裁剪多边形,并应用自己的材质实例
ue5
AA陈超1 天前
虚幻引擎5 GAS开发俯视角RPG游戏 P05-05 游戏效果委托
c++·游戏·ue5·游戏引擎·虚幻
m0_552200821 天前
《UE5_C++多人TPS完整教程》学习笔记62 ——《P63 多人游戏中的开火特效(Fire Effects in Multiplayer)》
c++·游戏·ue5
CandyU21 天前
UE5 小知识点 —— 11 - 下坠
ue5
AA陈超2 天前
虚幻引擎5 GAS开发俯视角RPG游戏 P04-12 可缩放浮点数的曲线表
c++·游戏·ue5·游戏引擎·虚幻
咖啡咖_CoffCa3 天前
【UE5】新建Editor Standalone Window插件,之前(或当前)创建插件的按钮消失(被顶掉/占用)的问题
ue5·虚幻引擎·插件开发
maki0774 天前
VR大空间资料 01 —— 常用VR框架对比
android·ue5·游戏引擎·vr·虚幻·pico
maki0775 天前
虚幻版Pico大空间VR入门教程 01 ——UE5 Android打包环境4.26~5.6
android·ue5·vr·虚幻·pico·大空间