当前位置: 首页 > news >正文

《UE5_C++多人TPS完整教程》学习笔记60 ——《P61 开火蒙太奇(Fire Montage)》


本文为B站系列教学视频 《UE5_C++多人TPS完整教程》 —— 《P61 开火蒙太奇(Fire Montage)》 的学习笔记,该系列教学视频为计算机工程师、程序员、游戏开发者、作家(Engineer, Programmer, Game Developer, Author) Stephen Ulibarri 发布在 Udemy 上的课程 《Unreal Engine 5 C++ Multiplayer Shooter》 的中文字幕翻译版,UP主(也是译者)为 游戏引擎能吃么。
在这里插入图片描述


文章目录

  • P61 开火蒙太奇(Fire Montage)
  • 61.1 开火操作映射
  • 61.2 创建开火动画蒙太奇
  • 61.3 播放蒙太奇
  • 61.4 Summary


P61 开火蒙太奇(Fire Montage)

本节课我们想要使用武器进行开火,这意味着我们需要创建用于开火的输入动作映射和开火的动画蒙太奇。
在这里插入图片描述


61.1 开火操作映射

  1. 添加开火操作映射 “Fire”,绑定按键为鼠标左键。
    在这里插入图片描述

  2. 打开 Visual Studio,在 “BlasterCharacter.h” 声明 “Fire” 操作映射函数 “FireButtonPressed()” 和 “FireButtonReleased()”,用于实现人物角色持枪开火和停火。

    /*** BlasterCharacter.h ***/...UCLASS()
    class BLASTER_API ABlasterCharacter : public ACharacter
    {GENERATED_BODY()...protected:// Called when the game starts or when spawnedvirtual void BeginPlay() override;// 与轴映射相对应的回调函数void MoveForward(float Value);		// 人物角色前进或后退void MoveRight(float Value);		// 人物角色左移或右移void Turn(float Value);				// 人物角色视角左转或右转void LookUp(float Value);			// 人物角色俯视或仰视// 与动作映射相对应的回调函数void EquipButtonPressed();			// 人物角色装备武器void CrouchButtonPressed();			// 人物角色蹲伏void AimButtonPressed();			// 人物角色开始瞄准void AimButtonReleased();			// 人物角色停止瞄准void AimOffset(float DeltaTime);	// 人物角色瞄准偏移virtual void Jump() override;		// 人物角色跳跃/* P61 开火蒙太奇(Fire Montage)*/void FireButtonPressed();			// 人物角色开火void FireButtonReleased();			// 人物角色停火/* P61 开火蒙太奇(Fire Montage)*/
    
  3. 在 “CombatComponent.h” 中声明变量 “bIsFireButtonPressed”,用于记录人物角色是否在开火,这样我们在动画蓝图就可以使用它的值判断是否播放开火动画,同时声明函数 “FireButtonPressed()” 并在 “CombatComponent.cpp” 中实现,用于开火或停火操作时设置 “bIsFireButtonPressed” 的值。

    /*** CombatComponent.h ***/UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
    class BLASTER_API UCombatComponent : public UActorComponent
    {GENERATED_BODY()...protected:...UFUNCTION()void OnRep_EquippedWeapon();				// 设置人物角色朝向的 Repnotify 函数/* P61 开火蒙太奇(Fire Montage)*/void FireButtonPressed(bool bPressed);	// 根据人物角色是否在开火,设置 bIsFireButtonPressed/* P61 开火蒙太奇(Fire Montage)*/private:...UPROPERTY(EditAnywhere)float BaseWalkSpeed;						// 基础行走速度UPROPERTY(EditAnywhere)float AimWalkSpeed;							// 瞄准行走速度/* P61 开火蒙太奇(Fire Montage)*/bool bIsFireButtonPressed;					// 人物角色开火键是否按下/* P61 开火蒙太奇(Fire Montage)*/
    };
    
    /*** CombatComponent.cpp ***/.../* P61 开火蒙太奇(Fire Montage)*/
    // 根据人物角色是否在开火,设置 bIsFireButtonPressed
    void UCombatComponent::FireButtonPressed(bool bPressed)
    {bIsFireButtonPressed = bPressed;
    }
    /* P61 开火蒙太奇(Fire Montage)*/
    
  4. 在 “BlasterCharacter.cpp” 的函数 “SetupPlayerInputComponent()” 中分别绑定操作映射函数 “FireButtonPressed()” 和 “FireButtonReleased()”,并完成它们的定义。

    /*** BlasterCharacter.cpp ***/...// Called to bind functionality to input
    void ABlasterCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
    {Super::SetupPlayerInputComponent(PlayerInputComponent);// 绑定操作映射PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);PlayerInputComponent->BindAction("Equip", IE_Pressed, this, &ABlasterCharacter::EquipButtonPressed);PlayerInputComponent->BindAction("Crouch", IE_Pressed, this, &ABlasterCharacter::CrouchButtonPressed);PlayerInputComponent->BindAction("Aim", IE_Pressed, this, &ABlasterCharacter::AimButtonPressed);PlayerInputComponent->BindAction("Aim", IE_Released, this, &ABlasterCharacter::AimButtonReleased);/* P61 开火蒙太奇(Fire Montage)*/PlayerInputComponent->BindAction("Fire", IE_Pressed, this, &ABlasterCharacter::FireButtonPressed);PlayerInputComponent->BindAction("Fire", IE_Released, this, &ABlasterCharacter::FireButtonReleased);/* P61 开火蒙太奇(Fire Montage)*/...
    }.../* P61 开火蒙太奇(Fire Montage)*/
    // 人物角色开火键按下
    void ABlasterCharacter::FireButtonPressed()
    {if (Combat) Combat->FireButtonPressed(true);	// 人物角色在开火,设置 Combat->bIsFireButtonPressed 为 true
    }// 人物角色开火键松开
    void ABlasterCharacter::FireButtonReleased()
    {if (Combat) Combat->FireButtonPressed(false);	// 人物角色已停火,设置 Combat->bIsFireButtonPressed 为 false
    }
    /* P61 开火蒙太奇(Fire Montage)*/
    

61.2 创建开火动画蒙太奇

  1. 编译后,在虚幻引擎中设置开火动画 “Fire_Rifle_Hip” 和瞄准开火动画 “Fire_Rifle_Ironsights” 的基础姿势动画为 “Zero_Pose” 和 “Aim_Zero_Pose
    在这里插入图片描述在这里插入图片描述

  2. 基于 “Fire_Rifle_Hip” 创建动画蒙太奇 “FireWeapon”,并移动至 “Game/Blueprints/Character/Animation/” 目录下。
    在这里插入图片描述

  3. 打开 “FireWeapon” 动画蒙太奇编辑窗口,“新建蒙太奇片段”(New Montage Section),命名为 “RifleHip”,然后 “删除蒙太奇片段”(Delete Montage Section)“Default”。
    在这里插入图片描述在这里插入图片描述

  4. 打开 “动画插槽管理器”(Animation Slot Manager)添加新的插槽 “WeaponSlot”,这样我们就可以在动画姿势中使用这个蒙太奇。
    在这里插入图片描述

  5. 在资产编辑器中切换 “DefaultGroup” 的插槽为 “WeaponSlot”。注意这里需要在左侧资产详情面板设置 “FireWeapon” 预览基础姿势为 “Zero_Pose”,否则在视口中人物角色还是 A 姿势;这个是教学视频里没提到的如果设置了预览基础姿势依然是 A 姿势,可以尝试点击 “预览插槽”(Preview Slot)。
    在这里插入图片描述在这里插入图片描述

  6. 拖拽 “Fire_Rifle_Ironsights” 至资产编辑器中,新建蒙太奇片段 “RifleAim”,在右下角蒙太奇片段中选中 “清除所有”(Clear),这样 “RifleHip” 就不会直接过渡到 “RifleAim” 了。
    在这里插入图片描述在这里插入图片描述在这里插入图片描述


61.3 播放蒙太奇

  1. 在 Visual Studio 中打开 “BlasterCharacter.h”,声明动画蒙太奇变量 “FireWeaponMontage” 和函数 “PlayFireMontage()”,在 “BlasterCharacter.cpp” 中完成函数 “PlayFireMontage()” 的定义。

    /*** BlasterCharacter.h ***/...class BLASTER_API ABlasterCharacter : public ACharacter
    {GENERATED_BODY()public:...// 重写复制属性函数virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;virtual void PostInitializeComponents() override;/* P61 开火蒙太奇(Fire Montage)*/// 播放开火蒙太奇void PlayFireMontage(bool bAiming);/* P61 开火蒙太奇(Fire Montage)*/...
    };
    
    /*** BlasterCharacter.cpp ***/.../* P61 开火蒙太奇(Fire Montage)*/
    #include "BlasterAnimInstance.h"
    /* P61 开火蒙太奇(Fire Montage)*/.../* P61 开火蒙太奇(Fire Montage)*/
    // 播放开火蒙太奇
    void ABlasterCharacter::PlayFireMontage(bool bAiming)
    {if (Combat == nullptr || Combat->EquippedWeapon == nullptr) return;UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();	// 获取动画实例if (AnimInstance && FireWeaponMontage){AnimInstance->Montage_Play(FireWeaponMontage);						// 在动画实例上播放开火蒙太奇FName SectionName;													// 蒙太奇片段名SectionName = bAiming ? FName("RifleAim") : FName("RifleHip");	// 如果人物角色在瞄准,播放 RifleAiming,否则播放 RifleHipAnimInstance->Montage_JumpToSection(SectionName);					// 在动画实例上播放蒙太奇片段}
    }
    /* P61 开火蒙太奇(Fire Montage)*/
    
  2. 编译后,在虚幻引擎中打开 “BP_EpicCharacter”,在右侧细节面板中设置 “Combat” 下的 “Fire Weapon Montage” 为 “FireWeapon”。
    在这里插入图片描述

  3. 打开 “BlasterAnimBP”,在 AnimGraph 面板添加蓝图节点 “使用缓存姿势 “Equipped””、“插槽 “DefaulSlot”” 节点以及 “新保存的缓存姿势”节点,并绘制下图所示蓝图。然后,选中 “插槽 “DefaulSlot”” 节点,在右侧细节面板切换插槽为 “WeaponSlot”。
    在这里插入图片描述

  4. 在 “AimOffset” 状态机的 “AimOffset” 状态节点蓝图面板中添加 “使用缓存姿势 “WeaponSlot””,按下图修改蓝图。
    在这里插入图片描述

  5. 在 Visual Studio 中打开 “CombatComponent.cpp” 完善函数 “FireButtonPressed()” 的定义,如果按下开火键,调用 “PlayFireMontage” 函数,根据人物角色的瞄准状态播放蒙太奇片段。

    /*** BlasterCharacter.cpp ***/
    /* P61 开火蒙太奇(Fire Montage)*/
    // 根据人物角色是否在开火,设置 bIsFireButtonPressed;根据人物角色的瞄准状态,播放开火蒙太奇片段
    void UCombatComponent::FireButtonPressed(bool bPressed)
    {bIsFireButtonPressed = bPressed;			// 设置 bIsFireButtonPressedif (Character && bIsFireButtonPressed)		// 如果人物角色在开火{Character->PlayFireMontage(bAiming);	// 根据 bAming 的值播放开火蒙太奇片段}
    }
    /* P61 开火蒙太奇(Fire Montage)*/
  6. 编译后在虚幻引擎中打开 “FireWeapon” 动画蒙太奇编辑窗口,在左侧资产详情面板将 “混入”(Blend In)和 “混出”(Blend Out)选项卡下的 “混合时间” 都设置为 0.0

  7. 进行测试,我们操控人物角色拾起武器,在不瞄准和瞄准两种情况下按下开火键,可以看到开火动画蒙太奇可以正常播放。
    在这里插入图片描述在这里插入图片描述


61.4 Summary

本节课我们成功实现了角色开火功能,包括输入处理、动画蒙太奇的创建和播放。在输入处理方面,我们在项目设置中创建 “Fire” 开火操作映射,绑定到鼠标左键。接着,在BlasterCharacter中定义了操作映射函数 “FireButtonPressed()” 和 “FireButtonReleased()” ,在 “CombatComponent” 中添加了用于记录开火键是否按下的变量 “bIsFireButtonPressed” 以及它对应的设置函数。随后,我们设置好 “Fire_Rifle_Hip” 和 “Fire_Rifle_Ironsights” 的基础姿势,基于开火动画创建“FireWeapon” 动画蒙太奇,并为 “FireWeapon” 添加了 “RifleHip” 和 “RifleAim” 两个蒙太奇片段,同时还创建了 “WeaponSlot” 插槽用于动画混合。接下来,我们进行了动画蓝图的优化,添加插槽节点和缓存姿势,在瞄准偏移状态机中集成武器插槽。最后,我们实现了蒙太奇的播放逻辑,在 “BlasterCharacter” 中实现 “PlayFireMontage()” 函数,根据瞄准状态播放对应的蒙太奇片段,在角色蓝图中设置开火蒙太奇资源;为确保动画立即播放,设置蒙太奇的混合时间为 0。测试结果表明我们的人物角色能够在站立和瞄准状态下正确播放对应的开火动画,为后续的武器射击功能奠定了基础。
在这里插入图片描述


http://www.dtcms.com/a/431221.html

相关文章:

  • 在wordpress主题后台安装了多说插件但网站上显示不出评论模块wordpress自定义html5
  • 构建AI安全防线:基于越狱检测的智能客服守护系统
  • 树莓派4B下载ubuntu 2504镜像
  • 河北省建设银行网站wordpres做影视网站
  • 电子商务网站建设与管理相关文献wordpress显示最新评论
  • python模块导入冲突问题笔记
  • 红黑树的实现(巨详细!!!)
  • 福州贸易公司网站制作小视频制作
  • 漳州做网站多少钱官方网站后台怎样做超链接
  • 【双指针专题】之移动零
  • 图书馆网站建设教程android studio手机版
  • 网站建设合同报价花果园营销型网站建设
  • 最小二乘问题详解2:线性最小二乘求解
  • Multi-Arith数据集:数学推理评估的关键基准与挑战
  • 基于 Spring Security OAuth2 + JWT 实现 SSO
  • 数智经济时代医疗领域医学影像系统现状与趋势研究:多模态融合技术方向
  • 解读 2025 《高质量数据集 分类指南》
  • 为什么说这个是6dB de-emphasis”(即“6dB去加重”)--Con‘t
  • Eclipse 快捷键
  • 樟木头网站网络安全维护公司
  • 【EE初阶 - 网络原理】网络通信
  • 方案网站有哪些盗用别的公司网站模块
  • 做网站是否要去工商备案做网站群
  • Less resolver error:‘~antd/es/style/themes/index.less‘ wasn‘t found.
  • php网站验证码错误网站改版对用户的影响
  • vue中如何实现异步加载组件
  • 网站地图seo石城网站建设
  • 怎么防止网站被镜像wordpress seo 主题
  • 那些钓鱼网站是怎么做的页面设计上边距在哪里找
  • 中国移动idc建设网站wordpress 导航栏