[18] C++虚幻引擎功能拓展

Day1

添加轴动作

EAxis::Type //轴方向 枚举
//旋转输入轴
UInputModifierSwizzleAxis* SwizzleAxis = NewObject<UInputModifierSwizzleAxis>(MappingContext);
KeyMapping.Modifiers.Add(SwizzleAxis);
//取反输入轴
UInputModifierNegate* Negate = NewObject<UInputModifierNegate>(MappingContext);
KeyMapping.Modifiers.Add(Negate);

玩家角色移动

玩家角色移动视角

GetWorld()->GetDeltaSeconds(); //获取时间碰撞系数
//Tick : 时间膨胀系数 跟帧率相关 , 每一帧的事件间隔120帧显示 : 1/120;

UE C++像蓝图提供变量

Tips :

  • 类是生成实例的依据 , 拖拽到场景后变成实例化
  • 混合空间中的动画默认打了同步组
  • 同步组 : 解决2个动画的衔接问题

触发事件 : 

ETriggerEvent::Started  //按下
ETriggerEvent::Completed //松开

Day2

设置默认的子对象类

父类添加好的组件添加自己的命名组件
替换了引擎的移动组件 , 换成自己的移动组件
挂载自己的charMovemont组件

创建自己的控制器和相机管理

相机放到玩家控制器 -> 玩家控制器放到gamemode

C++弹簧臂的滞后效果

FInterpTo 是 Unreal Engine 中的一个函数,用于在两个值之间进行插值。它的作用是在一定的时间内,将一个值平滑地从当前值(起始值)变换到目标值,实现渐变效果。

具体来说,FInterpTo函数有以下参数:

  • Current:当前值,即需要进行插值的值。
  • Target:目标值,即希望当前值变换到的目标值。
  • DeltaTime:时间增量,即每帧之间的时间间隔,通常用于控制变换的速度。
  • InterpSpeed:插值速度,表示在给定时间内,当前值从当前位置移动到目标位置的速度。值越大,移动速度越快。
  • InterpAcceleration:加速度,表示在插值过程中的加速度,用于使变换更加平滑。通常情况下可以忽略,设置为0即可。

在你提供的代码中,FMath::FInterpTo(OffsetSpringZ, 0, DeltaTime, 10)表示将 OffsetSpringZ 的当前值(起始值)平滑地从当前位置变换到目标值0,使用给定的 DeltaTime 和插值速度10。这样就会在一定的时间内使得 OffsetSpringZ 平滑地过渡到0,实现了一个平滑的过渡效果。

待机随机动画

子系统 :

生命周期 :

创建: 第一次调用会创建

消亡: 如果子系统是Instance会随着子系统类型消亡

GameInstance :  游戏实例独有一份
LocalPlayer : 一个玩家独有一份
world: 世界独有一份

第一次调用生效

virtual void Initialize(FSubsystemCollectionBase& Collection) override;

c++获取子系统

蓝图 : 获取子系统

生成骨骼网格体和静态网格体

api : 

相机管理器 : UpdateCamera(); 相当于Tick
动画通知 : 必须加UFUNTION() ; AnimNotify_RelaxedEnd();

Tips : 

所有的U类构造函数 , 要么无参 , 要么带有构造器
UGameplayStatic 不要用于联网生成

引入文件模板格式
#include "Components/BillboardComponent.h"
#include "framework/BillboardComponent.h"

Day3

UI模块分布图

UE C++球形检测

OnSphereBeginOverlap C++触发方式注意事项 , Rider代码到虚幻蓝图的过程为序列化可能造成缓存如果 , 球形检测如果不生效解决办法 : 

1. 把绑定事件放到BeginPlayer里面
2. 关闭虚幻 , rider的build -> clear 一下在构建
3. 在蓝图类默认设置里面更改下蓝图的父类在重新编译
4.检查下2者碰撞预设

多播代理

  1. 动态多播事件

    • 动态多播事件是指使用动态委托(Dynamic Delegate)来实现的,它允许在运行时动态地绑定和解绑函数。
    • 这种方式适用于需要在运行时动态确定事件处理函数的情况,比如游戏中的触发器事件、玩家输入事件等。
    • 在蓝图中,可以使用事件调度器(Event Dispatcher)来创建和触发动态多播事件。
  2. 普通多播事件

    • 普通多播事件是指使用普通委托(Delegate)来实现的,它在编译时已经确定了事件处理函数的类型和数量。
    • 这种方式适用于已经确定了事件处理函数的情况,比如游戏中的角色死亡事件、物体碰撞事件等。
    • 在蓝图中,可以使用自定义事件来创建和触发普通多播事件。
  3. 多播代理

    • 多播代理是指将事件广播给其他类的函数,可以将其理解为一种中介机制,用于实现类之间的解耦和通信。
    • 通过将事件绑定到多播代理上,其他类的函数可以注册到该代理上,从而在事件触发时被调用。
    • 在蓝图中,可以使用接口(Interface)或者自定义的代理类来实现多播代理的功能,从而实现不同类之间的事件通信和处理。

UI代理逻辑 :  UI功能交互 -> 背包触发逻辑 -> 背包广播 -> UI接受到广播进行UI更改

//--声明--//
//申明了代理类型,用于广播附近道具增加或是移除
DECLARE_MULTICAST_DELEGATE_OneParam(DelegateNearItemChanged, ASceneItem*);
//声明代理类型,用于广播背包道具元素增加或删除
DECLARE_MULTICAST_DELEGATE_TwoParams(DelegatePackageItemChanged, int32, int32);
///声明代理类型,装饰部件穿戴广播代理
DECLARE_MULTICAST_DELEGATE_TwoParams(DelegateSkinPartChanged, ESkinType, int32);
///声明代理类型,武器改变广播代理
DECLARE_MULTICAST_DELEGATE_OneParam(DelegateWeaponChanged, int32);
//--定义--//
DelegateNearItemChanged OnNearItemEnter;
DelegateNearItemChanged OnNearItemLeave;

DelegatePackageItemChanged OnPackageAddItem;
DelegatePackageItemChanged OnPackageRemoveItem;

DelegateSkinPartChanged OnPutOnSkinPart;
DelegateSkinPartChanged OnTakeOffSkinPart;

DelegateWeaponChanged OnEquipWeapon;
DelegateWeaponChanged OnUnEquipWeapon;

//--绑定广播--//
Player->GetPackageComponent()->OnNearItemEnter.AddUObject(this, &UPackageUserWidget::OnNearItemEnter); //绑定回调函数
Player->GetPackageComponent()->OnNearItemLeave.AddUObject(this, &UPackageUserWidget::OnNearItemLeave); //绑定回调函数
//--解绑广播--//
Player->GetPackageComponent()->OnNearItemEnter.RemoveAll(this);
Player->GetPackageComponent()->OnNearItemLeave.RemoveAll(this);

//--广播--//
//当用户球形检测到地面物品触发广播通知UI变更UI
void UPackageComponent::OnSceneItemEnter(ASceneItem* SceneItem)
{
	NearItems.AddUnique(SceneItem); //只添加一次
	if (OnNearItemEnter.IsBound()) //有存在有效的代理绑定
	{
		//执行广播
		OnNearItemEnter.Broadcast(SceneItem);
	}
}
void UPackageComponent::OnSceneItemLeave(ASceneItem* SceneItem)
{
	NearItems.Remove(SceneItem);
	if (OnNearItemLeave.IsBound())
	{
		OnNearItemLeave.Broadcast(SceneItem);
	}
}

滞后生成 : 

SpawnActorDeferred

将一个向量绕着另外一个向量进行旋转

FVector NewDir = CharacterBase->GetActorForwardVector().RotateAngleAxis(
FMath::FRandRange(-180.f, 180.f), FVector::UpVector);
FVector Location = CharacterBase->GetActorLocation() + NewDir * FMath::FRandRange(80.f, 120.f);
 
//RotateAngleAxis 旋转角度轴

接口

不同的数据类型有相同的行为

UMG接口执行时机

virtual void NativeConstruct() override; //视口更新执行
virtual void NativeOnInitializer() override; //执行一次

骨骼网格体的创建与附着

FAttachmentTransformRules KeepRelativeTransform; //保持相对变换
FAttachmentTransformRules KeepWorldTransform; //保持世界变化
FAttachmentTransformRules SnapToTargetNotIncludingScale; //紧贴目标,不包括尺度
FAttachmentTransformRules SnapToTargetIncludingScale; //紧贴目标包括尺度

Day5

SceneCaptureComponent2D组件

功能: 预览角色

API 

拿到挂载对象

  • 组件拿到挂载对象 : GetOwner
  • UMG拿到当前使用UMG人 : GetOwningPlayerPawn() 
  • 动画蓝图拿到使用动画的人 : TryGetPawnOwner()
  • 使用当前相机的玩家控制器 : GetOwningPlayerController(); 

拖拽

NativeOnMouseButtonDown //按下

NativeOnDragDetected //拖拽检测

NativeOnDrop 放下

posted @ 2024-05-07 20:35  啊賢  阅读(70)  评论(0编辑  收藏  举报