Unity3D与iOS的交互 简单版开箱即用

本文适合的情况如下:

Unity客户端人员 与 IOS端研发人员合作的情况

目录

From U3D to iOS

实现原理

1.unity工程目录创建2个文件 NativeCallProxy.m、NativeCallProxy.h 并且放到Unity工程目录Plugins/iOS/unity_ios_plus目录下

2.创建C#调用脚本 定义对应.mm脚本的 调用接口,调用也如下


From U3D to iOS

实现原理

由于U3D无法直接调用Objc或者Swift语言声明的接口,幸好U3D的主要语言是C#,因此可以利用C#的特性来访问C语言所定义的接口,然后再通过C接口再调用ObjC的代码(对于Swift代码则还需要使用OC桥接)。

下面演示:利用C#的特性来访问C语言所定义的接口,然后再通过C接口再调用ObjC的代码

1.unity工程目录创建2个文件 NativeCallProxy.m、NativeCallProxy.h 并且放到Unity工程目录Plugins/iOS/unity_ios_plus目录下

 NativeCallProxy.m代码内容:

#import <Foundation/Foundation.h>
#import "NativeCallProxy.h"//固定写法
@implementation FrameworkLibAPIid<NativeCallsProtocol> api = NULL;
+(void) registerAPIforNativeCalls:(id<NativeCallsProtocol>) aApi
{api = aApi;
}
//固定写法结束
@end//固定写法
extern "C" {
//void showHostMainWindow(const char* color) { return [api showHostMainWindow:[NSString stringWithUTF8String:color]]; };//返回字符串的1个函数
const char*  unityCallGetInitData(){NSString* str=[api unityCallGetInitData];char* ret = nullptr;
//    ret = (char*)malloc([str length]+1);
//    memcpy(ret, [str UTF8String], ([str length])+1);ret = (char*)malloc([str length]);memcpy(ret, [str UTF8String], [str length]);return ret;    
};//无返回的1个函数
void unityCallJumpLogin(){return  [api unityCallJumpLogin];
};//无返回、传入字符串的函数
void unityCallJumpToRecharge(const char* gameStatus,const char* receOBName,const char* methodName){return [api unityCallJumpToRecharge:[NSString stringWithUTF8String:gameStatus] :[NSString stringWithUTF8String:receOBName] :[NSString stringWithUTF8String:methodName]];};void unityCallCloseVC(){return [api unityCallCloseVC];
};//隱私按鈕
void onPrivacyButton(){return [api onPrivacyButton];
}//儲值按鈕
const char* storedValue(){NSString* str=[api storedValue];char* ret = nullptr; ret = (char*)malloc([str length]);memcpy(ret, [str UTF8String], [str length]);return ret;
}//切换游戏
const char* ChangeGame(){NSString* str=[api ChangeGame];char* ret = nullptr;ret = (char*)malloc([str length]);memcpy(ret, [str UTF8String], [str length]);return ret;}}//extern "C" {
//
//}

NativeCallProxy.h代码内容

// [!] important set UnityFramework in Target Membership for this file
// [!]           and set Public header visibility//固定写法
#import <Foundation/Foundation.h>
// NativeCallsProtocol defines protocol with methods you want to be called from managed
@protocol NativeCallsProtocol
@required// other methods 自定义方法
/**获取初始json数据:baseUrl、mac_id、gameType、jwt 【对应mm文件的自定义函数名】*/
-(NSString*)unityCallGetInitData;
/**重新登录	【对应mm文件的自定义函数名的接口】*/
-(void)unityCallJumpLogin;
/**跳充值页前保存数据,充值页返回后把保存的数据发信息给unity 【对应mm文件的自定义函数名的接口】*/
-(void)unityCallJumpToRecharge:(NSString*) gameStatus :(NSString*) receOBName :(NSString*) methodName;//ios——关闭vc 【对应mm文件的自定义函数名的接口】
-(void)unityCallCloseVC;//隱私按鈕 【对应mm文件的自定义函数名的接口】
-(void)onPrivacyButton;//储值按钮 【对应mm文件的自定义函数名的接口】
-(NSString*)storedValue;//ch Game 【对应mm文件的自定义函数名的接口】
-(NSString*)ChangeGame;//自定义方法结束
@end//以下为固定写法
__attribute__ ((visibility("default")))
@interface FrameworkLibAPI : NSObject
// call it any time after UnityFrameworkLoad to set object implementing NativeCallsProtocol methods
+(void) registerAPIforNativeCalls:(id<NativeCallsProtocol>) aApi;@end

勾选iOS平台

2.创建C#调用脚本 定义对应.mm脚本的 调用接口,调用也如下

using System;
using System.Collections;
using System.Collections.Generic;
using LitJson;
using UnityEngine;
using UnityEngine.UI;
using System.Runtime.InteropServices;
using UnityEngine.SceneManagement; //引入  这个命名空间,让unity可以使用 Assets/Plugins/iOS 或 Android/ 这里的dll文件/// <summary>
/// 呼叫安卓或 IOS 工具类
/// </summary>
public class CallAndroidOrIos :MonoBehaviour
{public static CallAndroidOrIos instance;private void Awake(){instance = this;}#region  关于IOS的操作/// <summary>/// 模拟 安卓或iOS ,DLL的类;/// </summary>public class NativeAPI{#if UNITY_EDITOR || UNITY_ANDROID/// <summary>/// 获取 IOS返回的 json数据 :baseUrl、mac_id、gameType、jwt/// </summary> public static string unityCallGetInitData(){return "";}/// <summary>/// 让IOS 呼叫重新登录/// </summary>/// <returns></returns>public static void unityCallJumpLogin(){Debug.Log("呼叫 ios重新登录");}/// <summary>/// IOS充值的返回 /// </summary> public static void unityCallJumpToRecharge(string gameStatus, stringreceOBName, string methodName){}/// <summary>/// 关闭当前 IOS活动页/// </summary>public static  void unityCallCloseVC(){}/// <summary>/// 隐私按钮/// </summary>public static void onPrivacyButton(){}/// <summary>/// 储值被点击/// </summary>public static string storedValue(){return "";}/// <summary>/// 切换G/// </summary>/// <returns></returns>public static string ChangeGame(){return "";}#elif UNITY_IOS || UNITY_TVOS //定义对应.mm脚本的 调用接口-----------[DllImport("__Internal")]public static extern string unityCallGetInitData();[DllImport("__Internal")]public static extern void unityCallJumpLogin();[DllImport("__Internal")]public static extern void unityCallJumpToRecharge(string gameStatus, stringreceOBName, string methodName);[DllImport("__Internal")]public static extern void unityCallCloseVC();[DllImport("__Internal")]public static extern void onPrivacyButton();[DllImport("__Internal")]public static extern string storedValue();[DllImport("__Internal")]public static extern string ChangeGame();
#endif}#endregion/// <summary>/// 被安卓调用过来的 统一函数名称  Public void Give_AnCall(string value)/// </summary>public const string Give_AnCall = "Give_AnCall";/// <summary>/// 当处于同一个物体的时候;用来区分函数名称/// </summary>public const string Give_AnCall2 = "Give_AnCall2";/// <summary>/// 关闭app当前页面/// </summary>public void unityCallCloseActivity(){if (Application.platform ==RuntimePlatform.IPhonePlayer|| Application.platform==RuntimePlatform.OSXEditor){Debug.Log("IOS 关闭当前Activity----------");NativeAPI.unityCallCloseVC();//关闭Ios 活动页}else{Debug.Log("关闭当前Activity----------");AndroidJavaClass activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");//只能调用静态AndroidJavaObject  s_ActivityContext = activityClass.GetStatic<AndroidJavaObject>("currentActivity");//可以调用非静态s_ActivityContext.Call("unityCallCloseActivity");//关闭页面 }}/// <summary>/// 获取 玩家进入哪个游戏类型 [ 0是推币机 1是连连看 -1是未知类型]/// 并且获取到 baseURL mac_id jwt gameType/// </summary> public IEnumerator unityCallGetInitData(Action<JsonData,string> callBack){int Time = 0;string strData="";string Tips="";try{if (Application.platform ==RuntimePlatform.IPhonePlayer){strData = NativeAPI.unityCallGetInitData();}else{AndroidJavaClass activityClass;AndroidJavaObject s_ActivityContext;activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); //只能调用静态s_ActivityContext = activityClass.GetStatic<AndroidJavaObject>("currentActivity"); //可以调用非静态strData = s_ActivityContext.Call<string>("unityCallGetInitData");}}catch (Exception e){Tips = "Error:" + e;if (callBack != null){callBack(null, Tips);}//跳出协程的执行yield break;}while (string.IsNullOrEmpty(strData))//等待回调{yield return new WaitForSeconds(1);Time++;if (Time >= 10){break; //跳出循环}}//还是没有 收到安卓返回数据  if (string.IsNullOrEmpty(strData)){if (callBack!=null){Tips = "Get the Android Or IOS data timeout";//获取安卓数据超时callBack(null, Tips);} }else{JsonData jsonData = JsonMapper.ToObject(strData);if (callBack!=null){callBack(jsonData, "successful"); }}}/// <summary>/// 跳转到 充值界面 (1.当前游戏场景名称 ,2.物体名称 ,3.安卓返回参数到 哪个函数接收) /// </summary> public void unityCallJumpToRecharge(string ScreenName, string receOBName, string methodName){if (Application.platform ==RuntimePlatform.IPhonePlayer){NativeAPI.unityCallJumpToRecharge(ScreenName,receOBName,methodName);//跳转到 充值}else{Debug.Log("呼叫 安卓跳转充值!----------------");AndroidJavaClass activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");//只能调用静态AndroidJavaObject  s_ActivityContext = activityClass.GetStatic<AndroidJavaObject>("currentActivity");//可以调用非静态s_ActivityContext.Call("unityCallJumpToRecharge",ScreenName,receOBName,methodName); }}/// <summary>/// 跳转到 重新登录界面/// </summary>public void unityCallJumpLogin(){if (Application.platform ==RuntimePlatform.IPhonePlayer){NativeAPI.unityCallJumpLogin();//IOS 进入 重新登录页面}else{Debug.Log("跳转到重新登录的Activity--------------");AndroidJavaClass activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");//只能调用静态AndroidJavaObject  s_ActivityContext = activityClass.GetStatic<AndroidJavaObject>("currentActivity");//可以调用非静态s_ActivityContext.Call("unityCallJumpLogin");activityClass = null;s_ActivityContext = null;}}/// <summary>/// 显示UnityLog到 安卓调试窗/// </summary>public void unityCallPrintLog(string log){if (Application.platform ==RuntimePlatform.IPhonePlayer){//TODO }else{AndroidJavaClass activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");//只能调用静态AndroidJavaObject  s_ActivityContext = activityClass.GetStatic<AndroidJavaObject>("currentActivity");//可以调用非静态s_ActivityContext.Call("unityCallPrintLog",log);}}/// <summary> 打开隐私按钮 </summary>public void onPrivacyButton(){if (Application.platform ==RuntimePlatform.IPhonePlayer){NativeAPI.onPrivacyButton();}else{Debug.Log("打开隐私按钮");}}/// <summary> 打开储值 </summary>public void storedValue(){if (Application.platform == RuntimePlatform.IPhonePlayer){Debug.Log("ios打开储值:"+NativeAPI.storedValue()); }else{Debug.Log("打开储值按钮");if (Application.platform == RuntimePlatform.WindowsEditor){//LogoGM.instance.HeroInfo_PlayCount(5);//默认给+5个//LogoGM.instance.HeroInfoSave();//PC端 增加可玩次数保存}}}/// <summary> 查询是否切换游戏 </summary>/// <returns></returns>public string ChangeGame(){if (Application.platform == RuntimePlatform.IPhonePlayer){return "IOS查询是否切换" + NativeAPI.ChangeGame();}else{return "PC查询游戏切换";}}/// <summary>/// IOS调用Unity的方法:UnitySendMessage("物体名", "函数名", "回调字符串");/// </summary>/// <param name="msg"></param>public void ReceIosMsg(string msg){Debug.Log("IOS 回调的信息");/*//根据游戏的场景划分 确定回调逻辑int scenceId = SceneManager.GetActiveScene().buildIndex;if (string.IsNullOrEmpty(msg)){Debug.Log(scenceId+"场景 收到IOS消息为空字符");}else{string strType;string strCode;//字符串转json对象JsonData jsonData = JsonMapper.ToObject(msg);switch (scenceId){case 0://场景0try{strType = jsonData["type"].ToString();strCode = jsonData["str"].ToString();if (strType=="ChuShiHua"){int code = int.Parse(strCode);if (code==0)//非游戏 静止在这个界面{Debug.Log(scenceId+"场景收到非游戏Code,等待跳转");//SetOrientationPortrait();//设置为竖屏mSpr.gameObject.SetActive(false);TestUpsideDown(1);}else{Debug.Log("正常游戏");toMenu();}}else{Debug.Log(scenceId+"场景 收到的不是初始化字段:"+strType);}}catch (Exception e){Debug.LogError(string.Format("{0} 场景 解析数据出错 原数据:{1}",scenceId,msg));}break;case 1://场景1try{strType = jsonData["type"].ToString();strCode = jsonData["str"].ToString();if (strType == "APPStore_Scuess"){//TODO 储值成功 添加可玩次数Debug.Log("储值成功");HeroInfo_PlayCount(9999);HeroInfoSave();//场景1的储值}else{Debug.Log(scenceId+"场景 收到的不是储值字段:"+strType);}}catch (Exception e){Debug.LogError(string.Format("{0} 场景 解析数据出错 原数据:{1}",scenceId,msg));}break;}}*/}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/179618.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

苹果相机怎么磨皮 苹果手机怎么磨皮

相信使用苹果相机的小伙伴都有这样的疑惑&#xff0c;苹果相机怎么磨皮&#xff1f;其实可以通过相机的参数进行设置从而达到磨皮的效果&#xff0c;如果觉得相机自带的设置磨皮效果不够好&#xff0c;可以下载磨皮软件来对照片磨皮。今天的文章就来给大家介绍苹果相机怎么磨皮…

GPT与人类共生:解析AI助手的兴起

随着GPT模型的崭新应用&#xff0c;如百度的​1​和CSDN的​2​&#xff0c;以及AI助手的普及&#xff0c;人们开始讨论AI对就业市场和互联网公司的潜在影响。本文将探讨GPT和AI助手的共生关系&#xff0c;以及我们如何使用它们&#xff0c;以及使用的平台和动机。 GPT和AI助手…

Nginx简介,Nginx搭载负载均衡以及Nginx部署前端项目

目录 一. Nginx简介 Nginx的优点 二. Nginx搭载负载均衡 2.1 Nginx安装 2.1.1 安装依赖 2.1.2 解压nginx安装包 2.1.3 安装nginx 2.1.4 启动nginx服务 2.2 tomcat负载均衡 2.3 Nginx配置 三. Nginx前端部署 一. Nginx简介 NGINX&#xff08;读作&#xff1a;engi…

虹科荣誉 | 喜讯!虹科成功入选“广州首届百家新锐企业”!!

文章来源&#xff1a;虹科品牌部 阅读原文&#xff1a;虹科荣誉 | 喜讯&#xff01;虹科成功入选“广州首届百家新锐企业”&#xff01;&#xff01; 近日&#xff0c;由中共广州市委统战部、广州市工商业联合会、广州市工业和信息化局、广州市人民政府国有资产监督管理委员会…

一文带你轻松拿下Java中的抽象类

&#x1f937;‍♀️&#x1f937;‍♀️&#x1f937;‍♀️各位看官你们好呀&#xff01;&#xff01;&#xff01; 今天我带大家来深入了解一下Java中的抽象类&#xff0c;相信看完这篇文章&#xff0c;你将会有很大的收获&#xff01; 个人主页 &#x1f302;c/java领域新星…

leetcode 169. 多数元素

2023.11.2 本题我的思路是将数组nums中的元素以及其出现次数保存至一个哈希表hashMap中&#xff0c;然后找到哈希表中大于⌊n/2⌋ 的value值&#xff0c;并返回对应的key即可。 java代码如下&#xff1a; class Solution {public int majorityElement(int[] nums) {Map<Int…

消息中间件——RabbitMQ(一)Windows/Linux环境搭建(完整版)

前言 最近在学习消息中间件——RabbitMQ&#xff0c;打算把这个学习过程记录下来。此章主要介绍环境搭建。此次主要是单机搭建&#xff08;条件有限&#xff09;&#xff0c;包括在Windows、Linux环境下的搭建&#xff0c;以及RabbitMQ的监控平台搭建。 环境准备 在搭建Rabb…

自家开发VS第三方美颜SDK:技术和资源的比较

开发直播平台时&#xff0c;开发人员面临一个关键决策&#xff1a;是选择使用第三方美颜SDK&#xff0c;还是自家开发美颜算法&#xff1f;本文将深入探讨这两种方法的技术和资源方面的比较&#xff0c;帮助开发者更好地决定哪种途径最适合他们的应用。 一、第三方美颜SDK&am…

springboot打包时依赖jar和项目jar分开打包;jar包瘦身

概述 最近感觉项目在部署时时jar包传输太慢了&#xff1b; 看了下jar包内容&#xff0c;除了项目代码&#xff0c;其余大部分都是依赖jar&#xff1b; 平时改动较多的只是项目代码&#xff0c;依赖jar改动比较少&#xff1b; 所以就在想能不能分开打包&#xff1b;这样只部署项…

Proteus仿真--1602LCD显示仿手机键盘按键字符(仿真文件+程序)

本文主要介绍基于51单片机的1602LCD显示仿手机键盘按键字符&#xff08;完整仿真源文件及代码见文末链接&#xff09; 仿真图如下 其中左下角12个按键模拟仿真手机键盘&#xff0c;使用方法同手机键一样&#xff0c;长按自动跳动切换键值&#xff0c;松手后确认选择&#xff…

ARM版CentOS Linux系统镜像安装教程

Linux系统受程序员钟爱&#xff0c;目前国内常见版本有Ubuntu和CentOS等&#xff0c;CentOS是较为稳定的Linux系统。如何在苹果电脑上安装Linux系统呢&#xff0c;小编为大家准备了ARM版CentOS Linux系统镜像文件资源&#xff0c;一起来看看吧&#xff01; ARM版CentOS Linux系…

matlab双目标定中基线物理长度获取

在MATLAB进行双目摄像机标定时,通常会获得相机的内参,其中包括像素单位的焦距(focal length)以及物理单位的基线长度(baseline)。对于应用中的深度估计和测量,基线长度的物理单位非常重要,因为它直接影响到深度信息的准确性。有时候,您可能只能获取像素单位的焦距和棋…

微信怎么设置自动通过好友申请?

当开展引流获客活动时&#xff0c;员工会在一段时间内频繁收到好友添加的申请&#xff0c;手动同意好友请求费时费力还容易出现漏加的情况&#xff0c;那么微信能自动通过好友请求吗&#xff1f; 如何设置快速自动通过好友申请呢&#xff1f; 当微信号在系统登录&#xff0c;…

每天五分钟计算机视觉:池化层的反向传播

本文重点 卷积神经网络(Convolutional Neural Network,CNN)作为一种强大的深度学习模型,在计算机视觉任务中取得了巨大成功。其中,池化层(Pooling Layer)在卷积层之后起到了信息压缩和特征提取的作用。然而,池化层的反向传播一直以来都是一个相对复杂和深奥的问题。本…

u20.04安装slam库

git clone https://github.com/strasdat/Sophus.git // 下载的最新版是模板类的 git checkout a621ff // 切换为非模板类的历史版本 模板类Sophus的依赖库是Eigen(版本为3.3.X)和fmt&#xff0c;需提前安装好Eigen库和fmt库 git clone https://github.c…

2023年Q3户外装备市场行业分析报告(京东数据分析):同比增长7%,品牌化发展是核心

近年来&#xff0c;户外运动在我国不少地方蓬勃兴起&#xff0c;发展至今&#xff0c;户外运动早已不是聚焦专业领域的小众群体活动&#xff0c;现已发展成为当下热门的大众休闲活动&#xff0c;参与人群愈发广泛&#xff0c;而这股热潮也带动着相关产业的发展。 今年Q3&#x…

爬虫项目(10):白嫖抓第三方网站接口,基于Flask搭建搭建一个AI内容识别平台

在数据驱动的时代,人工智能生成的内容变得越来越普遍。对于内容创作者和分析师来说,区分AI生成的内容与人类生成的内容变得尤为重要。在这篇文章中,我们将介绍一个项目,该项目使用 Flask 和 Requests 库来模拟对 writer.com 的 AI 内容检测功能的访问。 效果演示 地址:h…

[Machine Learning][Part 7]神经网络的基本组成结构

这里我们将探索神经元/单元和层的内部工作原理。特别是,与之前学习的回归/线性模型和逻辑模型进行比较。最后接介绍tensorflow以及如何利用tensorflow来实现这些模型。 神经网络和大脑的神经元工作原理类似&#xff0c;但是比大脑的工作原理要简单的多。大脑中神经元的工作原理…

剑指JUC原理-10.并发编程大师的原子累加器底层优化原理(与人类的优秀灵魂对话)

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码&#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44d;三连支持&…

flutter项目引入本地静态图片资源并展示

想要在flutter中引入静态资源&#xff0c;需要配置pubspec.yaml&#xff0c;将本地的静态资源添加到assets下面&#xff1a; 然后在flutter引入这些静态资源&#xff1a; Image.asset("images/squick.png") 就可以在app中看到这个图片了&#xff1a; 也可以使用网…