IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 日常UE4自写C++静态函数分享 -> 正文阅读

[游戏开发]日常UE4自写C++静态函数分享

?

一、LerpTransformByCurve函数
可以根据曲线,平滑的对变换进行插值(按引用),相当于使用曲线替换Lerp节点的Alpha值。其返回值表示是否到达插值终点。参数解释:
const FTransform& Start??? 插值的起点变换

FTransform& Current??? 当前的变换(按引用),可以被曲线平滑改变

const FTransform& Target??? 插值的终点变换

const UCurveFloat* Curve????透明度曲线,其取值在0到1之间,以便进行Lerp插值

float& CurveTime????曲线的当前时间

const float& DeltaSeconds????场景时间

static bool LerpTransformByCurve(const FTransform& Start,FTransform& Current,const FTransform& Target,const UCurveFloat* Curve,float& CurveTime,const float& DeltaSeconds)
{
??? if(Curve)
?? ?{
?? ??? ?CurveTime = CurveTime + DeltaSeconds;
?? ??? ?float MinTime,MaxTime;
?? ??? ?Curve->GetTimeRange(MinTime,MaxTime);

?? ??? ?CurveTime = FMath::Clamp(CurveTime,MinTime,MaxTime);
?? ??? ?FTransform LerpTransform = UKismetMathLibrary::TLerp(Start,Target,Curve->GetFloatValue(CurveTime),ELerpInterpolationMode::DualQuatInterp);

?? ??? ?//直接赋值,不考虑过渡
?? ??? ?//Current = LerpTransform;
?? ??? ?//使用插值赋值较为平滑
?? ??? ?Current = UKismetMathLibrary::TInterpTo(Current,LerpTransform,DeltaSeconds,20.0f);

?? ??? ?if(CurveTime >= MaxTime)
?? ??? ?{
?? ??? ??? ?CurveTime = 0.0f;
?? ??? ??? ?return true;
?? ??? ?}
?? ?}
?? ?return false;
}
需要在Tick内使用。用法举例:

FTransform Start = 起始值;//假设已经赋值了
FTransform End = 终点值;//假设已经赋值了
float MyCurveTime = 0.0f;//假设从曲线起始时间向后进行插值
void AMyClass::Tick(float DeltaSeconds)
{
?? ?Super::Tick(DeltaSeconds);

?? ?//用一个bool控制是否进行插值
?? ?if (bLerpMyTransform)
??? {
????? //用IsFinished取得返回值,如果为true表示已经插值完毕,如果为false表示还没有插值到终点
????? bool IsFinished = LerpTransformByCurve(Start,MyTransform,End,MyCurve,MyCurveTime,DeltaSeconds);

????? //ON TICK

????? if (IsFinished)
????? {
??????? //ON FINISHED

??????? //如果插值完毕,就停止插值
??????? bLerpMyTransform = false;
????? }
????? //在插值的过程中,MyTransform、MyCurveTime会一直保持更新,随时可以直接使用
??? }
}
二、LerpFloatByCurve函数
static bool LerpFloatByCurve(const float& Start,float& Current,const float& Target,const UCurveFloat* Curve,float& CurveTime,const float& DeltaSeconds)
{
??? if(Curve)
?? ?{
?? ??? ?CurveTime = CurveTime + DeltaSeconds;
?? ??? ?float MinTime,MaxTime;
?? ??? ?Curve->GetTimeRange(MinTime,MaxTime);

?? ??? ?CurveTime = FMath::Clamp(CurveTime,MinTime,MaxTime);
?? ??? ?float LerpFloat = UKismetMathLibrary::Lerp(Start,Target,Curve->GetFloatValue(CurveTime));

?? ??? ?//直接赋值,不考虑过渡
?? ??? ?//Current = LerpFloat;
?? ??? ?//使用插值赋值较为平滑
?? ??? ?Current = UKismetMathLibrary::FInterpTo(Current,LerpFloat,DeltaSeconds,20.0f);

?? ??? ?if(CurveTime >= MaxTime)
?? ??? ?{
?? ??? ??? ?CurveTime = 0.0f;
?? ??? ??? ?return true;
?? ??? ?}
?? ?}
?? ?return false;
}
三、当然,更加优雅的方式
/**
?* 根据曲线对变换进行平滑插值,这相当于于使用浮点曲线控制Lerp的Alpha值
?* 注册委托是被允许的,可以使用委托在插值的不同阶段添加行为
?* 但请注意,句柄被CleanTimer销毁后仍然会继续运作,需要使用ClearAllTimersForObject才能销毁。
?*/
DECLARE_DELEGATE(FOnLerpTick);
DECLARE_DELEGATE(FOnLerpFinished);
DECLARE_DELEGATE(FOnLerpStop);
USTRUCT(BlueprintType)
struct FLerpTransformByCurve
{
?? ?GENERATED_BODY()

public:
?? ?FOnLerpTick OnTick;
?? ?FOnLerpFinished OnFinished;
?? ?FOnLerpStop OnStop;

?? ?void StartLerp(UWorld* InWorld,FTransform& Target,FTransform const& A,FTransform const& B,UCurveFloat* Curve,float& CurveTime,
?? ??? ?float const& TimerRate,bool const& bForceStopExistingTimer=true)
?? ?{
?? ??? ?if(bForceStopExistingTimer)
?? ??? ?{
?? ??? ??? ?StopLerp(InWorld);
?? ??? ?}

?? ??? ?TimerCallBack = FTimerDelegate::CreateRaw(this, &FLerpTransformByCurve::LerpBody,InWorld,&Target,A,B,
?? ??? ??? ?Curve,&CurveTime,TimerRate);
?? ??? ?InWorld->GetTimerManager().SetTimer(TimerHandle, TimerCallBack, TimerRate, true);
?? ?}

?? ?void StopLerp(const UWorld* InWorld) const
?? ?{
?? ??? ?//ON STOP
?? ??? ?OnStop.ExecuteIfBound();

?? ??? ?InWorld->GetTimerManager().ClearAllTimersForObject(this);
?? ?}

private:
?? ?FTimerHandle TimerHandle;
?? ?FTimerDelegate TimerCallBack;

?? ?void LerpBody(UWorld* InWorld,FTransform* Target,FTransform A,FTransform B,UCurveFloat* Curve,float* CurveTime,float DeltaSeconds)
?? ?{
?? ??? ?const bool IsFinished = this->LerpTransformByCurve(*Target,A,B,Curve,*CurveTime,DeltaSeconds);

?? ??? ?//ON TICK
?? ??? ?OnTick.ExecuteIfBound();

?? ??? ?if( IsFinished )
?? ??? ?{
?? ??? ??? ?//ON FINISHED
?? ??? ??? ?OnFinished.ExecuteIfBound();

?? ??? ??? ?StopLerp(InWorld);
?? ??? ?}
?? ?}

?? ?static bool LerpTransformByCurve(FTransform& Target,const FTransform& A,const FTransform& B,const UCurveFloat* Curve,float& CurveTime,const float& DeltaSeconds)
?? ?{
?? ??? ?if(Curve)
?? ??? ?{
?? ??? ??? ?CurveTime = CurveTime + DeltaSeconds;
?? ??? ??? ?float MinTime,MaxTime;
?? ??? ??? ?Curve->GetTimeRange(MinTime,MaxTime);

?? ??? ??? ?CurveTime = FMath::Clamp(CurveTime,MinTime,MaxTime);
?? ??? ??? ?const FTransform LerpTransform = UKismetMathLibrary::TLerp(A,B,Curve->GetFloatValue(CurveTime),ELerpInterpolationMode::DualQuatInterp);

?? ??? ??? ?Target = UKismetMathLibrary::TInterpTo(Target,LerpTransform,DeltaSeconds,20.0f);

?? ??? ??? ?if(CurveTime >= MaxTime)
?? ??? ??? ?{
?? ??? ??? ??? ?CurveTime = 0.0f;
?? ??? ??? ??? ?return true;
?? ??? ??? ?}
?? ??? ?}
?? ??? ?return false;
?? ?}
};
FLerpTransformByCurve LerpTransformByCurve;
//可以使用LerpTransformByCurve.OnFinished等来Bind其他事件
LerpTransformByCurve.StartLerp(GetWorld(),MyTransform,Start,End,MyCurve,MyCurveTime,G

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-07-17 16:55:11  更:2022-07-17 16:56:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 10:34:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码