【UE4实用技能】写一个异步回调的蓝图接口

在做系统功能的时候经常需要到服务器去下载图片然后再显示,蓝图已经提供了这个接口供大家使用:

如果没有别的其他需求,那这个接口就够用了。

不过我们的项目需要在这个接口的基础上加一些功能:
1.本地缓存(不需要每次都请求)
2.把图片存放到硬盘(不需要每次重启游戏都重新下载)
3.设定一个文件数量阈值,超过这个值就删掉最早的文件
4.判断一下路径,如果是本地的图片直接加载,网络图片加载(整合所有图片加载接口为唯一一个)

因为改动比较多所以不在DownloadImage这个接口上改,重新写一个类来处理。(具体还是参考他的逻辑来写)



首先先简单讲一下异步回调的蓝图接口改怎么写。
1.先继承蓝图的异步回调基类

class CLIENT_API UImageDownloader : public UBlueprintAsyncActionBase

2.注册一下回调接口

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FGetImageDelegate, UTexture2D*, Texture);

    UPROPERTY(BlueprintAssignable)
        FGetImageDelegate OnSuccess;

    UPROPERTY(BlueprintAssignable)
        FGetImageDelegate OnFail;

这里需要注意一下,回调FGetImageDelegate的声明记得不要与其他类的名命重复了
3.补充一下构造函数


UImageDownloader::UImageDownloader(const FObjectInitializer& ObjectInitializer)
    : Super(ObjectInitializer)
{
    if (HasAnyFlags(RF_ClassDefaultObject) == false)
    {
        AddToRoot();
    }
}

4.提供唯一接口GetImage(FString URL)

    UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true"))
    static UActImageDownloader* GetImage(FString URL);

大概就是这样

#pragma once
#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
#include "Interfaces/IHttpRequest.h"
#include "Kismet/BlueprintAsyncActionBase.h"
#include <map>
#include "ImageDownloader.generated.h"

class UTexture2D;

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FGetImageDelegate, UTexture2D*, Texture);

UCLASS()
class CLIENT_API UImageDownloader : public UBlueprintAsyncActionBase
{
    //GENERATED_UCLASS_BODY()
    GENERATED_BODY()

public:
    UImageDownloader(const FObjectInitializer& ObjectInitializer);

    UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true"))
    static UActImageDownloader* GetImage(FString URL);

    UPROPERTY(BlueprintAssignable)
        FGetImageDelegate OnSuccess;

    UPROPERTY(BlueprintAssignable)
        FGetImageDelegate OnFail;
};


具体逻辑如果有人看再写吧,公司项目代码不好复制,需要做专门做一个demo



稍微记录一下几个需要注意的点:

1.创建C++类的时候应该从ue编辑器那边创建,这样会少一点问题

2.构造函数最好自己写, 不然经常编译有问题。自己写的话要用GENERATED_BODY()

UCLASS()
class CLIENT_API UActImageDownloader : public UBlueprintAsyncActionBase
{
    //GENERATED_UCLASS_BODY()
    GENERATED_BODY()

3.这一点很重要!我们写异步回调的,蓝图的执行逻辑是先跑你的函数,再赋值两个delegate。会导致的问题是,正常下载图片没有问题,如果加载本地图片的话,实际是同步,这时候会找不到OnSuccess和OnFail的代理,也就是这两个

这时候下面的流程就不走了。。。
解决方式就是,在代码里加一帧的延时。

    //如果直接调用Start的话,获取网络回调没问题,但是获取本地文件时会出现onsuccess绑的事件找不到的问题
    //调用DelayStart,加了个延时一帧调用
    FSimpleDelegateGraphTask::CreateAndDispatchWhenReady(
        FSimpleDelegateGraphTask::FDelegate::CreateLambda([=]()
    {
        Start(URL);//这里是你的逻辑
    }),
        TStatId(),
        nullptr,
        ENamedThreads::GameThread
        );

原文地址:http://blog.51cto.com/13638120/2170230

时间: 2024-11-09 01:42:24

【UE4实用技能】写一个异步回调的蓝图接口的相关文章

【UE4实用技能】UE4蓝图开发中的一些小细节

1.加载图标Icon路径:/Game/Arts/UI/TableIcons/Task_Icon/Achievement/Task_icon_weixin.Task_icon_weixin(就是Content换成/Game,后面一样) 2.获取ui控件的绝对坐标 3.获取鼠标坐标 4.判一下空 5.Toggole用FlipFlop 原文地址:http://blog.51cto.com/13638120/2166626

写一个读取Excel表格的接口

# -*- coding: gbk -*-import xlrd class Canshu: def __init__(self,filepath): """ 创建文件对象 :param filepath: 文件路径 """ self.workbook = xlrd.open_workbook(filepath) def get_canshu(self,sheetname,row,col): """ 获取某一个单元格

嵌套的异步回调

今天被一个问题纠结了2个小时,一开始失败的代码大概是这样的: dispatch_group_t group = dispatch_group_create(); while([rs next]){ dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{ [httpHelper getSecure:url completionHandler:^(NSDictionary* dict){ // 子任务 }]; }); } dis

同步和异步回调

同步和异步回调 作者:havoc (原文地址:http://blog.ometer.com/2011/07/24/callbacks-synchronous-and-asynchronous/) 这里讲两个使用callback设计API的指南,并且添加到我的杂记posts about minor API design points中.我之前多次在不同的场合发起过关于"sync vs. async"回调的问题.这个问题着实困扰着API设计者和使用者. 最近,这个问题在我处理Hammers

Java并发编程实践:Callable异步回调Future、FutureTask用法

Callable接口类似于Runnable,从名字就可以看出来了,但是Runnable不会返回结果,并且无法抛出返回结果的异常,而Callable功能更强大一些,被线程执行后,可以返回值,这个返回值可以被Future拿到.FutureTask实现了两个接口,Runnable和Future,所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值,那么这个组合的使用有什么好处呢?假设有一个很耗时的返回值需要计算,并且这个返回值不是立刻需要的话,那么就可以使用这

动手写一个Remoting测试工具

基于.NET开发分布式系统,经常用到Remoting技术.在测试驱动开发流行的今天,如果针对分布式系统中的每个Remoting接口的每个方法都要写详细的测试脚本,无疑非常浪费时间.所以,我想写一个能自动测试remoting接口的小工具InterfaceTester.而且,当分布式系统中的某个remoting接口出现bug时,该小工具可以提交需要模拟的数据,以便在调试remoting服务的环境中,快速定位和解决bug. InterfaceTester运行起来后的效果如下图: 1.如何使用 (1)首

动手写一个Remoting接口测试工具(附源码下载)

基于.NET开发分布式系统,经常用到Remoting技术.在测试驱动开发流行的今天,如果针对分布式系统中的每个Remoting接口的每个方法都要写详细的测试脚本,无疑非常浪费时间.所以,我想写一个能自动测试remoting接口的小工具InterfaceTester.而且,当分布式系统中的某个remoting接口出现bug时,该小工具可以提交需要模拟的数据,以便在调试remoting服务的环境中,快速定位和解决bug. InterfaceTester运行起来后的效果如下图: 1.如何使用 (1)首

【unity实用技能】记一次失败的蓝图接口开发失败经验

本来想写一个批量控制widget开关的接口,想写一个像append一样的可加pin的接口 首先还是找到这个接口得代码 可以看到关键的点就是 CommutativeAssociativeBinaryOperator = "true"就是这个,标记这个接口是可以加pin的.接下来就是照着写一下接口 // Fill out your copyright notice in the Description page of Project Settings. #pragma once #incl

用tornado 写异步回调程序

用tornado,一般都用到它的 AsyncHTTPClient的 fetch.我们可以参考 fetch,使用tornado的特性,写异步回调程序 首先看看 fetch的实现,关键是用了future def fetch(self, request, callback=None, **kwargs): """Executes a request, asynchronously returning an `HTTPResponse`. The request may be eit