UE4 如何实现与 iOS 原生之间的数据交互

Posted HelloWord杰少

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UE4 如何实现与 iOS 原生之间的数据交互相关的知识,希望对你有一定的参考价值。

本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索
HelloWorld杰少 即可关注。

前言

一眨眼已经步入 2021 年了,今天是 2021 年上班的第一天, 首先在这里先跟大家道声贺:“祝大家新年快乐,财源广进”,哈哈,大家元旦的假期过的还开心么,如果过的不开心那也请努力忘掉吧!毕竟新年要有新气象,剩下的每天都要活力满满。

作为 2021 年的第一个工作日,好的文章肯定是少不了的,今天就来给大家讲讲 UE4 开发在移动平台中最重要的一个环节: 数据交互。

如何实现数据交互

我之前写过一篇文章叫做: UE4 开发之如何创建 iOS 平台插件, 如果你看过了,你肯定已经知道如何通过创建插件的方式让 UE4 去调用我们 ios 原生的第三方库,这样做的好处我在那篇文章中也提到过了,就是可以让游戏开发人员专注于游戏本身,而将一些 UI 适配性不好的子功能或者用 UE 开发优势明显低于原生方式去做的功能交给插件去解决,这样各司其职的解决方案会大大提高游戏的品质。

但是有些仔细的人可能看了我之前那篇制作插件的文章会说:“这篇文章虽然讲了如何创建插件,如何调用插件的接口,但是没有说如何获取插件的返回值啊!我如果要登录我需要拿到插件返回的登录 token 啊!这样我才能让游戏服务器去验证登录成功还是失败”。

别着急,今天咱就把这部分给大家补上,请继续往下看。

我先模拟一个登录的环境,我的插件提供了一个登录接口,接口很简单,调用接口传入账号和密码,然后返回值通过 iOS 的 block 返回,返回值的格式是 “账号+密码”, 代码如下:

LoginMangment.h

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

typedef void(^getLoginStr)(NSString *loginStr);


@interface LoginMangment : NSObject

+ (LoginMangment *)shareInstance;

- (void)callLogin:(NSString *)account pwd:(NSString *)pwd block:(getLoginStr)loginStr;

@end

NS_ASSUME_NONNULL_END

LoginMangment.m

@implementation LoginMangment

+ (LoginMangment *)shareInstance 
    static LoginMangment *_instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^
        if (_instance == nil)
            _instance = [LoginMangment new];
        
    );
    
    return  _instance;



- (void)callLogin:(NSString *)account pwd:(NSString *)pwd block:(nonnull getLoginStr)loginStr
    
    NSString *ss = [NSString stringWithFormat:@"LoginString is : %@+%@", account, pwd];
    loginStr(ss);


@end

接下来,要给大家介绍一个重要的内容,也是本篇文章的核心:UE 委托.

可能大家要笑了,委托不就是 delegate 吗? iOS 用的熟的不要再熟了,没错,UE4 的委托与 iOS 的委托其实是一个道理,只是在代码实现的形式上有所区别.

光说不练假把式,那我就给大家实现一个简单的委托吧!

实现一个委托,需要执行以下几步操作:

声明委托

声明委托,需要用到 UE4 提供的特定宏来声明,UE4 为委托提供了如下的宏定义:

本篇的就实现的简单一点,因为我在上面定义的回调函数只有一个返回值,所以我就使用 DECLARE_DELEGATE_OneParam 宏来声明我的委托,委托的名称叫做 FStringDelegate, 然后在 UE4 的类中定义委托 FStringDelegate 的成员变量 WriteToLogDelegate,最后声明一个回调函数 testCallBack,代码如下:

#pragma once

#include "CoreMinimal.h"
#include "TestPlugin.h"
#include "Blueprint/UserWidget.h"
#include "MyUserWidget.generated.h"


DECLARE_DELEGATE_OneParam(FStringDelegate, FString);
/**
 * 
 */
UCLASS()
class TESTUE4DEMO_API UMyUserWidget : public UUserWidget

    FStringDelegate WriteToLogDelegate;
    FTestPluginModule *module;
    
	GENERATED_BODY()
    UFUNCTION(BlueprintCallable)
    void callInitSDK(int param);
    
    UFUNCTION(BlueprintCallable)
    void callTriger(int param);
    
    void testCallBack(FString str);
    
;

绑定委托

委托声明好了,那接下来就是要将回调函数绑定到委托上,在这里我用了 CreateUObject 这个函数来绑定委托,这样当我们的委托执行这个这个回调函数的时候,就会触发 testCallBack ,我们就能获取到回调值了,代码如下:

#include "MyUserWidget.h"


void UMyUserWidget::callInitSDK(int param)
    FStringDelegate writeToLogDelegate = FStringDelegate::CreateUObject(this, &ThisClass::testCallBack);
   #if PLATFORM_IOS
    module = new FTestPluginModule();
    module->initCollection(writeToLogDelegate);
    #endif



void UMyUserWidget::callTriger(int param)
    #if PLATFORM_IOS
    module->trigerCrash();
    #endif



void UMyUserWidget::testCallBack(FString str)
    const TCHAR* result = *str;
    FPlatformMisc::MessageBoxExt(EAppMsgType::Ok, result, TEXT("Callback"));


执行委托

通过调用 Execute() 函数来执行绑定到委托的回调函数,不过为了检查执行前委托是否已经绑定,所以这个我用这个函数来执行比较安全:ExecuteIfBound(), 代码如下:

#pragma once

#include "Modules/ModuleManager.h"
DECLARE_DELEGATE_OneParam(FStringDelegate, FString);

#if PLATFORM_IOS
#import <TestLogin/LoginMangment.h>
#endif

class FTestPluginModule : public IModuleInterface

    FStringDelegate testDelegate;
public:

	/** IModuleInterface implementation */
	virtual void StartupModule() override;
	virtual void ShutdownModule() override;
    
    // 显示用户UI
    void initCollection(FStringDelegate &myDelegate);
    
    // 崩溃
    void trigerCrash();

private:
	/** Handle to the test dll we will load */
	void*	ExampleLibraryHandle;
;
void FTestPluginModule::initCollection(FStringDelegate &myDelegate)
    #if PLATFORM_IOS
    testDelegate = myDelegate;
    #endif


void FTestPluginModule::trigerCrash()
    #if PLATFORM_IOS
    [[LoginMangment shareInstance] callLogin:@"zhangsan" pwd:@"123456" block:^(NSString * _Nonnull loginStr) 
        FString UE4Str = loginStr;
        testDelegate.ExecuteIfBound(UE4Str);
    ];
    #endif

好了,设置完 Xcode 的签名证书,插上真机运行,如果没有问题,出现的结果应该是:点了初始化后按钮后,再点登录按钮,会弹出一个 Alert 框,上面的内容是账号密码,如图所示:

写在最后

今天这篇文章给大家讲述了如何通过委托的方式来与 iOS 原生进行数据交互,到这里为止,加上前面的3篇文章一共是4篇,都是关于 UE4 和 iOS 平台对接的教程,因为我也是一步步从小白开始走过来的,UE4 开发 说实话对新手确实不太友好,网上的资料太少,然后自己本身也存在很多的 bug 问题,我在公司也处于一直给 UE4 填坑的状态,所以这几篇文章的内容我都是按照给新人培训的标准来写的,囊括了环境配置,创建简单 UI,对接 iOS 原生插件,以及数据交互,如果你是一名在游戏公司上班的 iOSer ,又恰好公司立项了 UE4 项目 ,那希望我的文章能够帮到你,谢谢。

相关阅读:
UE4 如何实现与 iOS 原生之间的数据交互
UE4 开发之如何创建 iOS 平台插件
UE4 开发之实现按钮事件响应
UE4 开发之配置 Xcode 调试环境

关注我的技术公众号,获取优质技术文章。
微信扫一扫下方二维码即可关注:

以上是关于UE4 如何实现与 iOS 原生之间的数据交互的主要内容,如果未能解决你的问题,请参考以下文章

iOS与Unity3d交互

iOS - OC 与 JS 交互六种方式总结

WebViewJavascriptBridge实现js与android和ios原生交互

Flutter 专题49 图解 Flutter 与 Android 原生交互 #yyds干货盘点#

RN与原生交互——传参并带有回调

UE4蓝图与C++交互——射击游戏中多武器系统的实现