制作iOS SDK接入到Untiy项目,然后导出unitypackage包给其它unity游戏接入SDK

之前一直从事iOS开发工作,最近要做一个iOS SDK给Unity游戏项目使用,新手遇到很多问题,还好都自己解决了,记录一下;

1、开发iOS SDK:之前因为对Unity接入iOS SDK和UnityPackage打包不熟,看网上说Unity不会自动复制Framework到Xcode工程,所以用的静态链接库,也就是.a形式;(其实Unity导出Xcode后接入SDK对iOS开发人员来说非常简单!但Unity项目希望能自动化处理,导出Xcode后可以不经任何修改,所以需要把iOS SDK做成UnityPackage包,在Unity开发环境简单、快捷接入)

2、由于Untiy使用C#语言开发,所以iOS需要提供 C 接口给 Unity 调用,例如: mysdk.h

ifdef __cplusplus //C++环境

extern "C"{

endif

           void usersdk(const char *param);

ifdef __cplusplus //C++环境

}

endif

然后在 mysdk.mm 文件实现:

void usersdk(const char *param)
{

}

3、SDK分别针对真机和模拟器在Release模式编译,编译后合并成通用.a,最后应该得到一些.h头文件、.a二进制文件、可能还有一些资源文件,比如 test.txt,image.xcassets图片文件夹等;

4、新建 Unity 项目,在Assets目录下面新建 /Plugins/MySDK/iOS和Android文件夹,把第2步的文件和资源还有 mysdk.h 和 mysdk.mm 放到iOS目录下;

5、在 Unity新建 C# 文件,调用 SDK 接口:

public class ECKChatSDK : MonoBehaviour {

#if UNITY_IOS && !UNITY_EDITOR

[DllImport("__Internal")]
void usersdk(string param);

#endif

void OnGUI() {

    if (GUI.Button (new Rect (200, 150, 200, 50), "使用SDK")) {

        #if UNITY_IOS && !UNITY_EDITOR

        usersdk("param");

        #endif

        #if UNITY_ANDROID && !UNITY_EDITOR

        #endif

    }
}

}

Unity会自动匹配 string 和 const char *;

6、新建 iosbulid.cs 自动复制文件和资源:

在 Unity 的 Assets 目录下,新建目录和文件 /Scripts/Editor/iosbulid.cs,内容如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode;
using System.IO;

public class iOSBuild : MonoBehaviour {

[PostProcessBuild]
public static void OnPostprocessBuild(BuildTarget buildTarget, string path)
{
    if (BuildTarget.iOS == buildTarget)
    {
        //复制资源文件夹
        ECKCopyiOSResource(path);
        //修改工程文件
        ECKModifyPBXProject(path);
    }
}

private static void ECKModifyPBXProject(string path)
{
    string projPath = PBXProject.GetPBXProjectPath(path);
    PBXProject proj = new PBXProject();

    proj.ReadFromString(File.ReadAllText(projPath));
    string target = proj.TargetGuidByName("Unity-iPhone");

    //添加 -ObjC标记
    proj.AddBuildProperty(target, "OTHER_LDFLAGS", "-ObjC");

    //引用资源文件夹
    string resourceDirectoryPath = "Libraries/Plugins/ECKChatSDK/iOS/Resource";
    ECKAddResourceGroupToiOSProject(path, proj, target, resourceDirectoryPath);

    //引用资源文件夹,直接添加文件夹,以Create folder references 形式添加
    /*
    string resourcePath = "Libraries/Plugins/ECKChatSDK/iOS/Resource";
    //string fileGuid = proj.AddFolderReference(Path.Combine(path, resourcePath), resourcePath, PBXSourceTree.Source);
    string fileGuid = proj.AddFolderReference(Path.Combine(path, resourcePath), resourcePath);
    proj.AddFileToBuild(target, fileGuid);*/

    //保存工程文件
    File.WriteAllText(projPath, proj.WriteToString());
}

//在工程文件添加资源文件夹引用,以 Create Group 形式加到工程文件
private static void ECKAddResourceGroupToiOSProject(string xcodePath, PBXProject proj, string target, string resourceDirectoryPath)
{
    string dirFullPath = Path.Combine(xcodePath, resourceDirectoryPath);
    //添加文件引用
    string[] files = Directory.GetFiles(dirFullPath);
    foreach (string s in files)
    {
        string fileExtension = Path.GetExtension(s);
        if (fileExtension.Equals(".DS_Store")) {
            continue;
        }
        string fileName = Path.GetFileName(s);
        string targetFilePath = Path.Combine(resourceDirectoryPath, fileName); 
        string fileGuid = proj.AddFolderReference(targetFilePath, targetFilePath);
        proj.AddFileToBuild(target, fileGuid);
    }
    //添加子文件夹
    string[] subDirectorys = Directory.GetDirectories(dirFullPath);
    foreach (string s in subDirectorys)
    {
        string fileName = Path.GetFileName(s);
        string subDirPath = Path.Combine (resourceDirectoryPath, fileName); 
        string fileExtension = Path.GetExtension(s);
        if (fileExtension.Equals (".xcassets")) {
            string fileGuid = proj.AddFile(subDirPath, subDirPath);
            proj.AddFileToBuild(target, fileGuid);
        } else {
            ECKAddResourceGroupToiOSProject (xcodePath, proj, target, subDirPath);
        }
    }
}

//复制ios多语言文件和图片资源
private static void ECKCopyiOSResource(string path)
{
    string fromDir = Application.dataPath+"/Plugins/ECKChatSDK/iOS/Resource/";
    string targetDir = path + "/Libraries/Plugins/ECKChatSDK/iOS/Resource/";

    ECKCopyDirectoryFiles (fromDir, targetDir);
}

/** 将文件夹下面的所有非.meta文件(不包括子文件夹)复制到iOS工程目录下*/
private static void ECKCopyDirectoryFiles(string fromDir, string targetDir)
{
    if (!Directory.Exists(targetDir))
    {
        Directory.CreateDirectory(targetDir);
    }

    //复制所有文件
    string[] files = Directory.GetFiles(fromDir);

    // Copy the files and overwrite destination files if they already exist.
    foreach (string s in files)
    {
        string extension = Path.GetExtension(s);
        if (extension.Equals(".meta")) 
        {
            continue;
        }
        string fileName = Path.GetFileName(s);
        string targetFilePath = Path.Combine(targetDir, fileName);
        File.Copy(s, targetFilePath, true);
    }

    //复制所有子文件夹
    string[] subDirectorys = Directory.GetDirectories(fromDir);

    // Copy the files and overwrite destination files if they already exist.
    foreach (string s in subDirectorys)
    {
        string dirName = Path.GetFileName(s);
        string targetDirPath = Path.Combine(targetDir, dirName);
        ECKCopyDirectoryFiles (s, targetDirPath);
    }
}

}

因为加了 [PostProcessBuild] 表情,这个 OnPostprocessBuild 函数会在 Untiy编译成Xcode后自动执行!

这里需要说明的是,Xcode工程添加文件夹有2种方式,第一种是 Create Groups,第二种是 Create folder references,如果使用

/*
string resourcePath = "Libraries/Plugins/ECKChatSDK/iOS/Resource";
//string fileGuid = proj.AddFolderReference(Path.Combine(path, resourcePath), resourcePath, PBXSourceTree.Source);
string fileGuid = proj.AddFolderReference(Path.Combine(path, resourcePath), resourcePath);
proj.AddFileToBuild(target, fileGuid);*/

这段代码,会以 第二种 Create folder references 形式加到工程文件;

ECKAddResourceGroupToiOSProject 这个函数会以 第一种方式加到工程文件;

7、最后运行 Xcode工程,应该可以直接 run 起来了,测试无误后,进入下一步;

8、在 Unity项目,选中 /Plugins/MySDK 文件夹,右键选择 Export Package ... 得到 MySDK.unitypackage包,把这个包给 Untiy项目,对方先打开他们自己游戏的Unity工程,然后双击我们的 MySDK.unitypackage包,点击 import 按钮,就可以导入到游戏的Unity工程,把 iosbulid.cs 里面的函数复制到游戏的相似地方,实现自动复制文件和资源功能;

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345