【Unity3d】Unity与iOS之间通信

iOS和Unity交互之界面跳转 本文介绍了iOS和Unity交互,主要涉及两个界面之间的跳转. 如果对iOS和Unity交互传参方法不熟悉的朋友,可以参考我的另一篇文章 iOS和Unity交互之参数传递 一.程序启动入口. main.mm了解OC或者C的朋友一定知道main方法,这是整个程序的入口.以下是Unity转iOS工程后的main文件中的部分代码.const char* AppControllerClassNam 阅读详情
AI摘要

本文详细介绍了在Unity开发中如何与Android和Objective-C原生层进行通信。对于Unity与Android的交互,提到了参考资源;而对于Unity与Objective-C,文章详细阐述了三个步骤,包括在Xcode中定义函数、将OC代码整合进Unity工程以及在C#中声明并调用OC函数。此外,还特别指出了函数重载、数据类型映射和回调函数的处理方法。

在Unity开发或者SDK开发经常遇到Unity与移动端原生层之间进行通信,这里把它们之间通信做一个整理。

关于Unity与Android之间通信,参考【Unity3d】Unity与Android之间通信

Unity调用Objective-C

主要分三个步骤:

(一)、在xcode中定义要被unity调用的函数

新建一个类,名字可以任意,比如UnityBridge:

头文件:UnityBridge.h (头文件中不需要字段和函数声明)

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface UnityBridge : NSObject

@end

NS_ASSUME_NONNULL_END

头文件里没什么代码,主要代码在实现文件中。

实现文件:UnityBridge.m

实现文件中需要用c语言定义函数,这些函数定义了之后,就可以被unity调用:

#import "UnityBridge.h"

//如果c#调用oc函数时需要一个回调,需要先声明回调参数类型:
typedef void (*MyResultCallback) (int status,const char *result);

//在.m文件中以下4行可以不需要
#if defined (__cplusplus)
extern "C"
{
#endif

	//这里写被unity调用的函数
	
 	void test1(void){
		//这里是函数实现,支持oc语法
	}

	/**
	* int类型参数,返回int
	*/
	int test2(int params){
		//这里是函数实现,支持oc语法
	}
	/**
	* 字符串类型参数
	*/
	void test3(const char *params){
		//这里是函数实现,支持oc语法
	}

	/**
	* 返回字符串时,不能直接返回oc转c的字符串,要调用strdup函数再返回
	*/
	const char* test4(void){
		//返回字符串时,需要使用c分配内存再返回,否则闪退
		//return "abc" //错误,会闪退
		//return [@"abc" UTF8String];//错误,会闪退
		//return strdup("abc") //正确	
		
		//strdup函数需要引入#import <string.h>
		return strdup([@"abc" UTF8String]) //要调用strdup()函数分配c内存再返回给unity,不然闪退
	}

	/**
	* 支持回调参数
	*/
	void test5(MyResultCallback callback){
		//这里是函数实现,支持oc语法
		int code = 0;
		NSString p = @"test";
		const char *result = [p UTF8String];
		//回调给c#
		callback(code,result)
	}
	
//在.m文件中以下3行可以不需要
#if defined (__cplusplus)
}
#endif

函数返回类型是字符串时,oc这边不能直接返回oc转c的char*字符,否则闪退,c++闪退代码行:
…
// Marshaling cleanup of return value native representation
il2cpp_codegen_marshal_free(returnValue);
原因是oc使用了ARC自动释放内存,c层再去free内存发现未分配就会报错。
需要调用strdup()函数再返回,函数所在头文件:#import <string.h> 参见上面示例代码的test4()函数。

注意这些代码不要写在@implementation中,它是c语言的函数。

C++支持函数重载,而C不支持,两者的编译规则也不一样。函数被C++编译后在符号库中的名字与C语言的不同。例如,假设某个函数的原型为: void foo( int x, int y ); 该函数被C编译器编译后在符号库中的名字可能为_foo,而C++编译器则会产生像_foo_int_int之类的名字(不同的编译器可能生成的名字不 同,但是都采用了相同的机制,生成的新名字称为“mangled name”)。_foo_int_int这样的名字包含了函数名、函数参数数量及类型信息,C++就是靠这种机制来实现函数重载的。如果要在C++中使用C的函数,需要加extern "C"修饰。
#if defined (__cplusplus) 这是一个宏判断,c++中才有这个宏。extern "C"也是c++的关键字。因为oc是支持c++(在.mm文件中才支持),extern "C"表示后面函数是c语言的,供外部调用的。如果在.m文件中,可以不需要extren “C”。

(二)、将oc代码复制到unity工程中。

将oc代码(包括.h和.m源文件)拷贝到Unity工程的Assets目录或子目录中。

实际上将oc代码放在unity工程的Assets目录下的任意位置都可以,oc代码会自动被unity引擎识别。

(笔者使用的unity版本是2019.4,以前的版本不知道是否可以是任意位置。)

为了方便管理,oc代码一般放在Assets/Plugins/iOS中。

也可以将代码打包成framework静态库,然后将其拷贝到unity工程的Assets目录中,一般放在 Assets/Plugins/iOS这个目录中。Unity导出xcode会自动依赖这个framework。

(三)、在unity的c#脚本中声明外部(oc)函数原型
using System.Runtime.InteropServices; //需要引入这个命名空间,会提示引入
using UnityEngine;

public class Test

{
   
    private Test() {}


  
#if UNITY_IOS //加个宏比较好

	//以下是外部函数声明,函数签名必须与oc函数保持一致,参数类型用各自语言的,类型映射见文末。
	//声明无参数无返回值的函数
    [DllImport("__Internal")]
    private static extern void test1();
    
	//声明有一个int参数和int返回值的函数
 	[DllImport("__Internal")]
    private static extern int test2(int p);
    
	//声明一个string参数的函数
    [DllImport("__Internal")]
    private static extern void test3(string p);

	//声明返回string类型的函数
    [DllImport("__Internal")]
    private static extern string test4();

	//如果需要oc的回调,声明一个回调函数类型
    delegate void MyResultDelegate(int code,string result);
    
    [DllImport("__Internal")]
    private static extern void test5(MyResultDelegate resultDelegate);
    
	/**
	* 回调函数的实现(或者叫实例)
	*  注意:必须是static类型的
	*/
   	[AOT.MonoPInvokeCallback(typeof(MyResultDelegate))]
     private static void MyResultDelegateInstance(int code, string result)
     {
       //这里写接收到oc回调的代码
     }

#endif

 	 public  void CallOC()
	  {
	  #if UNITY_IOS
	  	test1();
	  	int result1 = test2(1);
	  	test3("abc");
	  	string result2 = test4();
	  	test5(MyResultDelegateInstance);
	  #endif
      }
}

在c#中调用oc中对应的方法,参见以上 CallOC()。

c#调用oc注意事项:

1、数据类型需要使用各自语言的,两者数据类型映射关系在文未。

2、c#中声明的oc方法、回调,都需要static修饰。

Objective-C调用Unity(c#)

oc调用c#比较简单,一般使用以下这个方法:

  UnitySendMessage("MyTestObject", "TestFunc", "msg");

UnitySendMessage函数声明在UnityFramework.framework中UnityInterface.h头文件中:

void  UnitySendMessage(const char* obj, const char* method, const char* msg);

第一个参数obj表示unity中物体GameObject的名字,注意不是c#脚本的名称也不是类名。

如下图:
在这里插入图片描述
第二个参数method表示这个物体挂载的c#脚本中方法的名字。

第三个参数表示msg表示这个方法接收的数据。

例如,以上物体MyTestObject挂载了MyScript.c#脚本(如上图),MyScript.c#中有TestFunc方法:

using UnityEngine;

public class MyScript : MonoBehaviour
{

    private void TestFunc(string content)
 	{
 		//这里是接收oc调用的实现
	}  
             
}

那么在oc中调用UnitySendMessage("MyTestObject", "TestFunc", "msg") c#的TestFunc方法就会执行。

如果有多个参数需要发送,推荐使用json格式。

oc调用c#注意事项:

1、需要依赖UnityFramework.framework框架。

2、unity工程导出的xcode工程默认已经有UnityFramework.framework。

3、如果是自己新建的xcode工程需要手动导入这个框架。

附:c#与oc数据类型映射:

Unity(c#)Objective-C
intint
floatfloat
boolbool
stringconst char *
longlong long
【问题记录】Unity打包iOS真机闪退,报错Error loading ***.app/Frameworks/UnityFramework.framework/UnityFramework 接入的iOS SDK中需要手动添加库/框架,其中AdServices是可选的,仅支持14.3及以上版本iOS。问题出现在AdServices' not found,缺少AdServices.framework文件。方式一:直接修改XCode工程,将Required改为Optional。iOS 13.6闪退,iOS 15.1/15.5正常。方式二:Unity打包后处理,false改为true。实际设置为了必选的,导致低版本iOS异常。 阅读详情

相关推荐

Unity与IOS的交互

IOS端:使用Xcode创建一个新的OC工程,然后创建一个Cocoa Touch Class,Xcode会自动生成一个.m文件和一个.h文件 废话不多说,上代码: ClassName.h: #import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN @interface ClassName : NSObject //+表示共有,-表示私有 //(Type)变量名 +(ClassName *) instance; //显示一个IOS对话框

qq_43244501的博客 777

Unity 和 iOS之间的通信(交互)

上一篇主要说了将Unity集成到原生iOS应用程序中,集成之后肯定是要通信的,所以这篇来说一下Unity 和 iOS之间的通信。 1、iOS调用Unity的方法并传参数 在UnityFramework中提供的有专门的方法,因此我们只要调用就可以了。 首先在AppDelegate.h中声明一个调用方法,方便后面使用。 - (void)sendMessageWithName:(const char*)goName functionName:(const char*) functionName messa

weixin_42714258的博客 7497

Unity3D和IOS的交互教程——通过URL启动APP并传递参数

最近工作中遇到,占坑,先贴代码。等项目期过去后再来补充文字; using System.Runtime.InteropServices; [DllImport("__Internal")] private static extern void _GetURLString (); public static void GetURLString() { if(Applicati

zs19931224的博客 5084

Unity与ios交互(双端通信)

由于U3D无法直接调用Objc或者Swift语言声明的接口,因此通常利用C#的特性来访问C语言所定义的接口,然后再通过C接口调用ObjC的代码(对于Swift代码则还需要使用OC桥接)。具体来说,可以通过在Unity中使用C#脚本调用iOS原生代码,或者将iOS原生代码封装成库供Unity调用。Unity与iOS的交互(双端通信)是一个关键的技术领域,特别是在开发跨平台游戏和应用时。回调函数的参数是图片的路径,Unity通过这个路径加载并显示图片。在Unity中,使用C#编写脚本来调用iOS原生代码。

lcfengokok的博客 2055

在iOS平台上嵌入Unity3D虚拟引擎

在Unity3D编辑器中,点击"Edit",然后选择"Project Settings",再选择"Player"。在"Project Settings"中的"Player"部分,选择"Other Settings"。b. 在"Build Phases"选项卡中,展开"Link Binary With Libraries"部分,并添加所需的框架和库。c. 在"Build Settings"选项卡中,搜索"Other Linker Flags"设置,并添加"-ObjC"标志。如果你有任何其他问题,请随时提问。

QscFramework的博客 1065

将Unity3D项目打包为iOS Framework

在弹出的窗口中,选择“Framework & Library(框架和库)”部分下的“Cocoa Touch Framework(Cocoa Touch框架)”。在下一个窗口中,为您的iOS Framework指定一个名称,并选择一个适当的组织标识符(例如,com.example.framework)。现在,您可以在新创建的iOS Framework目标中编写代码,以调用Unity3D项目中的功能。现在,可以在新创建的iOS Framework目标中编写代码,以调用Unity3D项目中的功能。

DllCoding的博客 1142

Unity3d与iOS交互开发——接入平台SDK必备技能

前言废话:开发手机游戏都知道,你要接入各种平台的SDK。那就需要Unity3d与iOS中Objective-C的函数有交互,所以你就需要用到如下内容: 一、Unity3d  To  iOS: 1、创建一个C#文件 SdkToIOS.cs 这是调用iOS函数的接口: [csharp] view plaincopyprint?

huangyushi的专栏 2552

从零到一:海外短剧成品系统源码搭建流程详解及APP+H5交付服务

在当今全球化的数字娱乐浪潮中,海外短剧市场以其独特的文化魅力和广阔的受众基础,正逐渐成为内容创作者与平台运营者争相布局的新蓝海。我为了紧跟时代的发展我翻看了大量的文章,偶然间看到了一篇文章点进去发现他们是专业做短剧开发的,总结下来在这篇文章里分享给大家。

liangyill_的博客 907

ios android平台接入unity,Unity接入IOS SDK笔记

一. Unity3D与原生IOS代码之间的相互调用Unity使用C#作为开发语言,而IOS采用Objective-C作为开发语言,如何让C#调用OC代码,或者让OC调用C#代码。所幸OC和C#都支持直接嵌入C/C++代码,作为两者之间的桥梁。1. iOS To Unity3dunity3d 的UnitySendMessage函数,在导出Xcode工程时,在UnityInterface.h中已声明...

weixin_36484898的博客 455

二维数字图像相关算法软件Ncorr的使用心得

二维开源软件Ncorr的DIC分析操作过程详解。

m0_72612723的博客 3万+

保姆级教程:用STM32CubeMX HAL库搞定ESP8266连接,附串口printf调试全流程

本文提供了一份详细的STM32CubeMX HAL库教程,指导开发者如何实现ESP8266无线模块的连接与调试。从开发环境搭建、串口配置到AT指令通信解析,涵盖了物联网开发中的关键步骤和常见问题解决方案,帮助开发者快速掌握STM32与ESP8266的集成技术。

weixin_28273593的博客 503

【Unity3d】Unity与Android之间通信

在unity开发或者sdk开发经常遇到unity与移动端原生层之间进行通信,这里把它们之间通信做一个整理。

devnn的专栏 3758

别让IO口保护二极管坑了你!实测讲解单片机电流倒灌的三种典型症状与防护

本文深入解析单片机电流倒灌的三大典型症状与防护方案,重点分析STM32等单片机在ADC采样异常、系统假死和通信速率异常中的表现。通过实测数据和电路设计建议,提供从基础二极管隔离到专业隔离器件的分级防护策略,帮助工程师有效预防和解决电流倒灌问题。

weixin_29280219的博客 344

unity3D与ios互相通信

本人第一次写博客,不对之处。。还望多多指教! 先来说unity调用ios 首先你要有个mac,,mac上要装Xcode。。这个是必不可少的。 然后呢。。先在你的C#脚本里面倒包: Using System.Runtime.InteropServices; (好像是这么写的。。不要直接复制。。最好自己手动导一下)。 [ DllImport( "__Internal

大脸猫的博客 1986

Megatron单机多卡Qwen2.5:pre-train+sft

英伟达:https://github.com/NVIDIA/Megatron-LM/releases/tag/core_r0.8.0阿里:https://github.com/alibaba/Pai-Megatron-Patch/releases/tag/v0.10.2。

weixin_46873015的博客 2178

模型预测控制(MPC)算法介绍

模型预测控制(Model Predictive Control,MPC)是一种先进的控制策略,广泛应用于工业过程控制、机器人控制、电力系统等领域。它基于系统的模型,通过滚动优化来预测系统未来的行为,并据此确定当前的最优控制输入。

AI的内部世界的博客 7168

Unity2019接入IOS SDK

前言 前段时间接入了IOS的SDK,主要参考了如下几篇博客。本篇博客重点记录踩坑。 Unity3D 接入IOS SDK untiy 项目接入 IOS SDK Unity3D与iOS交互(接入原生sdk方法) Unity项目接入IOS的Admob Native(原生视频广告) IOS SDK 下面简单介绍下Unity与IOS之间交互。 1.Unity调用IOS Unity调用IOS需要在Xcode工程创建一个C的中间件,头文件为.h,源文件为.m或.mm,并将它们导入Unity的Assets->Plug

lcy的博客 4636

OpenClaw 技术架构解析-网关层(上)

OpenClaw 网关层是架构核心中枢,承接Channel层消息,串联消息路由器、会话状态管理器等五大组件,负责消息分发、会话管理、状态统筹、上下文维护等关键职责,是连接Channel层与AI执行引擎的核心桥梁,保障多渠道交互稳定、有序运行。

wend的博客 711

Unity3D开发之WebGL平台上 unity和js前端通信交互

一.老版方法 unity发布webplayer平台后会输出html和unity3d文件。我们的程序主要被打包在unity3d文件里,而html则是网页的界面显示。 1.Unity发送消息给JS unity想要和js交互,提供了一个函数:Application**.ExternalCall()**;此函数仅限于webplayer平台下。我们编辑发布的html文件,在里面加入我们的js脚本如下: fu...

weixin_43149049的博客 1万+

基于STM32、HAL库的IP2736U_EF快充协议芯片简介及驱动程序设计

@param connected: 连接状态指针 (1=已连接, 0=未连接)= 0x2736) // 检查厂商ID。* @param hip: IP2736U句柄指针。* @param hip: IP2736U句柄指针。* @param hip: IP2736U句柄指针。* @param hip: IP2736U句柄指针。* @param hip: IP2736U句柄指针。* @param hip: IP2736U句柄指针。* @param hip: IP2736U句柄指针。

corlin6688的博客 430

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

unity3d ios 交互

写这篇博文之前,我也为之忙活了半天,对于那些不熟悉oc的童鞋来说,非常有用,这里主要会讲到常用的通信机制。和一些关于IOS的代码讲解。 一下主要讲解使用unity3d调用IOS的界面浏览一张图片。 1.unity3d 与 IOS 的基本通信机制。 在C#脚本中,定义一个类,里面写入类似这样的 public static class PlatformNative{ [Dl...

deleizhen7765的博客 202

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

【Unity3D插件】Unity3D各类教程汇总

推荐阅读 优快云主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 一、工具篇 工欲善其事,必先利其器 学习Unity3D不从工具篇说起怎么能行? 学习Unity3D最重要的两个工具:Unity3D和Visual Studio(Visual Studio Code也行) 1-1、Unity3D安装 Unity 安装个人免费版步骤详解(通过UnityHub安装unity,是比较流行的安装方式) https://blog.youkuaiyun.com/fi.

优快云博客专家,Unity3D高级软件工程师,《Unity 3D从入门到实战》作者。 1万+

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Unity3d接入IOS内购

利用Unity3d制作完毕游戏发布到appstore,有时会做游戏内购买虚拟物品,也就是内购。 在Ios开发中叫做:In App Purchase,简称IPA 那么如何在unity3d内嵌入IPA呢?几经辗转,多方搜索,摸索出点经验,分享给大家,如有疏漏,还请指教。 当然也有人们写好的插件可用,我觉得自己写的才用着顺手。   一、准备条件: 1、 申请苹果开发者账号。后台先创建证书,在

三人行、则必有我师 1万+

探索Unity 3D在iOS应用中的无限可能

探索Unity 3D在iOS应用中的无限可能 在移动应用开发的世界里,Unity 3D以其强大的游戏引擎功能和跨平台能力,一直是开发者们的首选。然而,将Unity 3D集成到iOS应用中,似乎总是一项复杂且耗时的任务。但今天,我们将揭开这一过程的神秘面纱,带你领略如何在iOS应用中轻松嵌入Unity 3D。 项目介绍 本项目旨在提供一个详细的指南,帮助开发者将Unity 3D项目无缝集成到iOS应...

gitblog_00581的博客 1034
上一篇: 【Kotlin】by lazy关键字的实现原理
下一篇: 【Unity3d】Unity与Android之间通信
devnn
博客等级 码龄12年 2005粉丝 90原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值