前言:
這次是iOS和Unity交互。過程沒有預(yù)想的那么順利,也踩了一些坑,做個(gè)筆記。
要做的事情就是實(shí)現(xiàn) iOS 和 Unity 交互,互相調(diào)用函數(shù),傳值。
傳值系列
iOS Unity 交互(系列一)Unity調(diào)用iOS函數(shù) Unity給iOS傳值
iOS Unity 交互(系列二)iOS調(diào)用Unity函數(shù) iOS給Unity傳值
iOS Unity 交互(系列三)iOS Unity互傳參數(shù)與完整示例代碼
iOS Unity 交互(系列四)Unity調(diào)用iOS SDK
需要的工具
1、蘋果電腦安裝:Xcode,Unity,VSCode,開發(fā)工具安裝最新的就行。
2、蘋果手機(jī)真機(jī),用于調(diào)試。
實(shí)現(xiàn)目標(biāo)
實(shí)現(xiàn)在Unity中調(diào)用Xcode里面的函數(shù)傳值,然后Xcode處理完把結(jié)果再傳給Unity,然后Unity移除GameObject,Xcode把對(duì)應(yīng)的對(duì)象銷毀。
在Unity里面放一個(gè)立方體(Cube),把腳本掛載到立方體上,運(yùn)行項(xiàng)目,觀察Unity iOS傳值,隨后銷毀立方體。
操作流程
1、在Unity里面放一個(gè)立方體 Cube。
1、在上一個(gè)已經(jīng)生成的Xcode項(xiàng)目中,寫.mm代碼,編譯通過后,復(fù)制粘貼到Unity工程里,(.mm文件放在 Asset/Plugins/iOS 目錄下)。
2、在Unity中寫C#腳本。
3、運(yùn)行項(xiàng)目
第1步 在場景里新建一個(gè)立方體,并掛載腳本。
這一步使用到了上篇文章里的工程。如果不清楚項(xiàng)目是怎么來的,看一下上一篇 iOS Unity 交互(系列一)Unity調(diào)用iOS函數(shù) Unity給iOS傳值

第2步 寫代碼
圖片中的完整代碼在文章末尾
jiaoben.cs 代碼文件在 Asset 目錄下,Unity_iOS_Connect.mm 文件在 Asset/Plugins/iOS目錄下。

第3步 生成Xcode項(xiàng)目,真機(jī)運(yùn)行。

圖片中的示例代碼:
C# 腳本代碼 jiaoben.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;
public class Jiaoben : MonoBehaviour
{
[DllImport("__Internal")]
private static extern void BridgeObjectInitWith(string name);
[DllImport("__Internal")]
private static extern void BridgeObjectNeed(string name);
[DllImport("__Internal")]
private static extern void BridgeObjectDestory();
void Start()
{
Debug.Log("腳本開始運(yùn)行");
//初始化對(duì)象,傳入U(xiǎn)nity 里面要掛載到的 GameObject 對(duì)象名字
//這里腳本掛載到了自定義的一個(gè)立方體上
BridgeObjectInitWith("CubeOnYourPhone");
//初始化之后給iOS發(fā)送消息
BridgeObjectNeed("Unity_Tag");
//3秒鐘之后把自己從場景中干掉
GameObject.Destroy(this.gameObject, 3.0f);
}
//寫上在 OC .mm文件中的同名函數(shù)
public void ObtainIOSMessage(string msg)
{
Debug.Log("C# 腳本收到消息: " + msg);
}
//在掛載對(duì)象銷毀的時(shí)候,把OC里面的類也銷毀掉,避免占用內(nèi)存
private void OnDestroy()
{
BridgeObjectDestory();
}
// Update is called once per frame
void Update()
{
}
}
OC .mm文件代碼 Unity_iOS_Connect.mm
//
// Unity_iOS_Connect.m
//
//
// Created by 程序猿 on 2020/2/31.
//
#import <Foundation/Foundation.h>
//寫一個(gè)OC類 BridgeObject
@interface BridgeObject : NSObject
///Unity中掛載腳本的對(duì)象名字
@property (nonatomic, strong) NSString *objectName;
@end
@implementation BridgeObject
- (void)dealloc {
NSLog(@"???????? 實(shí)例對(duì)象 已經(jīng)銷毀");
}
- (instancetype)initWithObject:(NSString *)objectName {
if (self = [super init]) {
self.objectName = objectName;
}
return self;
}
- (void)handleMsgFromUnity:(NSString *)message {
NSLog(@"調(diào)用 %s", __func__);
NSString *s = [NSString stringWithFormat:@"%@ & iOS_Tag", message];
UnitySendMessage([self.objectName UTF8String], "ObtainIOSMessage", [s UTF8String]);
}
@end
BridgeObject *instance = nil;
extern "C" {
//初始化
extern void BridgeObjectInitWith(const char *gameObjectName) {
NSString *s = [NSString stringWithUTF8String:gameObjectName];
if (instance == nil) {
instance = [[BridgeObject alloc] initWithObject:s];
}
}
//初始化
extern void BridgeObjectNeed(const char * message) {
NSString *s = [NSString stringWithUTF8String:message];
[instance handleMsgFromUnity:s];
}
///銷毀
extern void BridgeObjectDestory() {
instance = nil;
}
}
結(jié)語
終究是有一天碰上了Unity。
感謝以下iOS/Unity玩家的文章:
Unity3D與iOS的交互
<iOS和Unity交互>之參數(shù)傳遞
Unity與iOS交互
unity 與oc交互
Unity平臺(tái)調(diào)用IOS
Unity和OC簡單交互(方法互調(diào))
Unity-IOS交互整理
iOS與Unity交互筆記之參數(shù)傳遞
iOS 和 Unity之間參數(shù)傳遞的方法
iOS與Unity交互筆記之參數(shù)傳遞
iOS和Unity交互之參數(shù)傳遞
Unity3d與iOS交互開發(fā)—接入平臺(tái)SDK必備技能
iOS 和 Unity 交互之參數(shù)傳遞
報(bào)錯(cuò)解決:
malloc: *** error for object 0x1018ad6a0: pointer being freed was not allocated
Unity 調(diào)用oc報(bào)錯(cuò):malloc: *** error for object 0x1ecc0eb0: pointer being freed was not allocated
malloc: *** error for object 0x1ecc0eb0: pointer being freed was not allocated
Unity3D中C#調(diào)用iOS的靜態(tài)庫(*.a)
pointer being freed was not allocated