iOS 手游开发之如何创建 UE4 插件

网友投稿 757 2022-08-24

iOS 手游开发之如何创建 UE4 插件

iOS 手游开发之如何创建 UE4 插件

前言

在前俩篇文章中,我与大家分享了 UE4 开发如何配置 Xcode 的调试环境以及如何实现 UE4 引擎的按钮事件的响应,其实写这俩篇文章的目的就是为接下来的文章做一个引子,就好比是高级餐厅的前菜一样,接下来我们就要进入到正餐部分了.

既然 UE4 引擎具有跨平台的特性,那是否真的能像很多跨平台的开发工具所说的一样:Write once, run everywhere 呢!我调研过市面上主流的几个跨平台开发工具,也自己动手搭建过环境并写了几个 Demo,我只想跟大家说:谁用谁知道(捂脸笑)。

每个平台都有自己的特性,要想做到一份代码适配所有平台的难度是非常大的,因为我们不能保证每个功能都做到完美适配,所以怎么去解决当前面临的窘境呢!那就是我们要尽量减少跨平台功能的数量,只保证我们的核心功能在各个平台上能完美的适配,把一些辅助功能模块例如:登录,分享,数据采集等模块做成插件的方式集成到我们的项目中,这些插件都是用各个平台的原生代码开发的,iOS 平台就用 OC 或者 swift 开发,Android就用 java 或者 kotlin 开发,所以完全就不用去考虑它的平台兼容性问题了。

那接下来我们就开始今天的教程吧!

UE4 开发之如何创建 iOS 平台插件

UE4 为我们广大开发者提供了众多的插件供我们使用,正是有了这些插件的存在,才让游戏开发变得更快更简单,今天我跟大家分享一下如何编写 UE4 插件。

创建 UE4 插件

1. 在 UE 编辑器中,打开菜单栏中的编辑下拉菜单,选择插件选项

2. 选择右下角的新插件

3. 选择截图上的 "第三方库", 并填写插件名称,例如我起的为 "JJLoginNail",以及填写作者以及描述

4. 创建完成后,会在你的 Xcode 工程中自动引用一个 Plugins 文件夹

处理第三方的 Framework

用于测试,我自建了一个 iOS 静态库: TestLoginSDK.framework, 里面包含一个显示用户登录界面的接口,以及回调账户名的回调,参考代码如下:

@protocol TestLoginDelegate - (void)OnLoginResult:(NSString *)result;@end@interface JJLoginController : NSObject+ (void)showLoginView:(UIViewController *)baseView JJCallBack:(id) delegate;@end

1. 在 ThirdParty 文件夹下创建 iosframeworks 文件夹,随后再该文件夹下创建 iosextend.embeddedframework 文件夹,并将第三方的 framework 放入其中

2. 将 iosextend.embeddedframework 添加到 .zip 压缩文件, 然后将 iosframeworks 引入到 Xcode 工程中

前期准备做好以后,我们现在进入到正式的敲代码阶段.

编码阶段

1. 在 Source 文件夹中插件为我们创建了以下源文件

2. 打开 JJLoginNail.Build.cs,配置我们的第三方 framework 路径,配置信息如下:

// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.using UnrealBuildTool;public class JJLoginNail : ModuleRules{ public JJLoginNail(ReadOnlyTargetRules Target) : base(Target) { PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; PublicIncludePaths.AddRange( new string[] { // ... add public include paths required here ... } ); PrivateIncludePaths.AddRange( new string[] { // ... add other private include paths required here ... } ); PublicDependencyModuleNames.AddRange( new string[] { "Core", "JJLoginNailLibrary", "Projects", // ... add other public dependencies that you statically link with here ... } ); PrivateDependencyModuleNames.AddRange( new string[] { // ... add private dependencies that you statically link with here ... } ); DynamicallyLoadedModuleNames.AddRange( new string[] { // ... add any modules that your module loads dynamically here ... } ); if (Target.Platform == UnrealTargetPlatform.IOS){ PublicAdditionalFrameworks.Add( new Framework( "TestLoginSDK", "../ThirdParty/iosframeworks/iosextend.embeddedframework.zip"

3. 打开 JJLoginNail.h 头文件,加入我们调用 API 的逻辑,以及处理回调的逻辑:

// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.#pragma#include "Modules/ModuleManager.h"#if#import //用于处理 sdk 返回的回调@interface FTestLoginResultModule : NSObject@end#endifclass FJJLoginNailModule : public IModuleInterface{public: /** IModuleInterface implementation */ virtual void StartupModule() override; virtual void ShutdownModule() override; /// 显示登录界面 void showLogin();private: /** Handle to the test dll we will load */ void* ExampleLibraryHandle;};

注意点: 其中我们的 OC 类别需要用 PLATFORM_IOS 宏包起来,并 import 我们所需要的第三方framework。

4. 打开 JJLoginNail.cpp 文件,实现上一步头文件中定义的接口以及在 OC 类中实现回调函数

// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.#include "JJLoginNail.h"#include "Core.h"#include "Modules/ModuleManager.h"#include "Interfaces/IPluginManager.h"#include "JJLoginNailLibrary/ExampleLibrary.h"#define LOCTEXT_NAMESPACE "FJJLoginNailModule"#if#include "IOSAppDelegate.h"@implementation FTestLoginResultModule- (void)OnLoginResult:(NSString *)result{ NSLog(@"登录账号为: %@", result);}@end#endif#ifstatic FTestLoginResultModule *loginResult = nil;#endifvoid FJJLoginNailModule::showLogin(){ #if dispatch_async(dispatch_get_main_queue(), ^{ [JJLoginController showLoginView:(UIViewController*)[IOSAppDelegate GetDelegate].IOSController JJCallBack:[FTestLoginResultModule new]]; }); #endif}void FJJLoginNailModule::StartupModule(){ // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module // Get the base directory of this plugin FString BaseDir = IPluginManager::Get().FindPlugin("JJLoginNail")->GetBaseDir(); // Add on the relative location of the third party dll and load it FString LibraryPath;#if LibraryPath = FPaths::Combine(*BaseDir, TEXT("Binaries/ThirdParty/JJLoginNailLibrary/Win64/ExampleLibrary.dll"));#elif LibraryPath = FPaths::Combine(*BaseDir, TEXT("Source/ThirdParty/JJLoginNailLibrary/Mac/Release/libExampleLibrary.dylib"));#endif // PLATFORM_WINDOWS ExampleLibraryHandle = !LibraryPath.IsEmpty() ? FPlatformProcess::GetDllHandle(*LibraryPath) : nullptr; if (ExampleLibraryHandle) { // Call the test function in the third party library that opens a message box ExampleLibraryFunction(); } else { FMessageDialog::Open(EAppMsgType::Ok, LOCTEXT("ThirdPartyLibraryError", "Failed to load example third party library")); }}void FJJLoginNailModule::ShutdownModule(){ // This function may be called during shutdown to clean up your module. For modules that support dynamic reloading, // we call this function before unloading the module. // Free the dll handle FPlatformProcess::FreeDllHandle(ExampleLibraryHandle); ExampleLibraryHandle = nullptr;}#undefIMPLEMENT_MODULE(FJJLoginNailModule, JJLoginNail)

注意点:在调用 SDK 接口的时候需要切换到主线程上,不然 App 会 Crash;在使用 OC 代码的时候需要用 PLATFORM_IOS 进行包裹;因为我们在实现逻辑中用到了 IOSAppDelegate 获取 RootView,所以我们需要在 JJLoginNail.Build.cs 加入一个配置 "ApplicationCore",不然会提示 IOSAppDelegate.h 头文件找不到,配置如下:

PublicDependencyModuleNames.AddRange( new string[] { "Core", "JJLoginNailLibrary", "Projects", "ApplicationCore" // ... add other public dependencies that you statically link with here ...

5. 回到我们插件文件夹上层文件夹的 Source 下,打开 UE 为我们自动创建的 Hydroger.Build.cs 文件,并在里面配置我们的插件名称 "JJLoginNail", 代码如下:

// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.using UnrealBuildTool;public class Hydroger : ModuleRules{ public Hydroger(ReadOnlyTargetRules Target) PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "JJLoginNail"}); PrivateDependencyModuleNames.AddRange(new string[] { }); // Uncomment if you are using Slate UI // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" }); // Uncomment if you are using online features // PrivateDependencyModuleNames.Add("OnlineSubsystem"); // To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true

#include "MyUserWidget.h"#include "JJLoginNail.h"void UMyUserWidget::callStartFunction(){// FPlatformMisc::MessageBoxExt(EAppMsgType::Ok, TEXT("start"), TEXT("callStartFunction")); #if FJJLoginNailModule *module = new FJJLoginNailModule(); module->showLogin(); #endif

注意点别忘了在 Hydroger.Build.cs 中配置插件名称include 插件头文件,例如:#include "JJLoginNail.h"逻辑用 PLATFORM_IOS 包裹

7. 最后,插上真机设备,在工程中设置好相应的签名证书,CMD+R 将工程跑在真机设备上:

触发按钮事件,调用 SDK 里面的接口

获取回调信息,并打印

结尾

到这里,UE4 引擎创建 iOS 插件步骤就结束了,其实并不是很难,就是配置的环节比较多,如果中间某一个环节掉了链子,那我们创建的插件就无法被工程所引用,所以在插件的使用过程中,需要仔细的去检查我们的配置。

好了,本篇教程到这里就结束了,如果遇到问题可通过留言的方式与我交流,希望本篇文章对大家有所帮助,蟹蟹。

​​HelloWorld杰少​​​

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:iOS开发-你能用到的面试题(iOS开发面试题)
下一篇:使用.NET进行高效率互联网敏捷开发的思考和探索(net 快速开发)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~