You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Swift回调中的参数传递至Unity?

Unity iOS插件异步回调实现方案(Swift+C桥接)

问题背景

我正在用Swift编写Unity的iOS插件,通过C语言做桥接层,目前同步调用逻辑运行正常。现在我有一个带回调的Swift函数,当回调触发时会返回一些值,想把这些值传递到Unity,该怎么实现?


现有同步调用代码

Unity (C#)

public class PluginHelper : MonoBehaviour
{
    [DllImport("__Internal")]
    private static extern double IOS_getVersion();

    private void Start()
    {
        double result = IOS_getVersion();
        Debug.Log(result);
    }
}

C桥接层

#import <Foundation/Foundation.h>
#include "UnityFramework/UnityFramework-Swift.h"

extern "C" {

double IOS_getVersion(){
    double result = [[UnityPlugin shared] swift_getVersion];
    return result;
}

}

Swift插件类

@objc public class UnityPlugin : NSObject {

    @objc public static let shared = UnityPlugin()
    
    @objc public func swift_getVersion() -> Double{
        // 原有逻辑
        let result = 1.0 // 示例值
        return result
    }
}

待处理的带回调Swift函数

public static func swiftfunction(target: AnyObject, handler: @escaping ((Notification?) -> Void)) -> NSObjectProtocol

异步回调实现步骤

1. 修改Swift代码,适配Unity回调

通过Unity官方提供的UnitySendMessageC接口实现跨语言消息传递,同时处理回调数据和内存管理:

@objc public class UnityPlugin : NSObject {

    @objc public static let shared = UnityPlugin()
    private var notificationObserver: NSObjectProtocol?
    // 保存Unity接收消息的GameObject名称和方法名
    private var unityCallbackObjName: String?
    private var unityCallbackMethodName: String?

    @objc public func swift_getVersion() -> Double{
        let result = 1.0 // 示例值
        return result
    }

    // 新增:注册回调的方法,接收Unity的对象名和方法名
    @objc public func registerNotificationCallback(gameObjName: String, methodName: String) {
        self.unityCallbackObjName = gameObjName
        self.unityCallbackMethodName = methodName

        // 调用带回调的swiftfunction
        notificationObserver = UnityPlugin.swiftfunction(target: self) { [weak self] notification in
            guard let self = self, let objName = self.unityCallbackObjName, let methodName = self.unityCallbackMethodName else { return }
            
            // 解析通知内容(示例:取userInfo中的"value"字段)
            let callbackValue = notification?.userInfo?["value"] as? String ?? "no data"
            
            // 调用UnitySendMessage向Unity发送消息
            UnitySendMessage(objName, methodName, callbackValue)
        }
    }

    // 新增:移除观察者,避免内存泄漏
    @objc public func unregisterNotificationCallback() {
        if let observer = notificationObserver {
            NotificationCenter.default.removeObserver(observer)
            notificationObserver = nil
            unityCallbackObjName = nil
            unityCallbackMethodName = nil
        }
    }
}

// 声明UnitySendMessage函数,让Swift可以调用
func UnitySendMessage(_ obj: UnsafePointer<CChar>, _ method: UnsafePointer<CChar>, _ msg: UnsafePointer<CChar>)

2. 更新C桥接层,添加注册/注销回调函数

新增供Unity调用的C接口,实现字符串格式转换:

#import <Foundation/Foundation.h>
#include "UnityFramework/UnityFramework-Swift.h"

extern "C" {

double IOS_getVersion(){
    double result = [[UnityPlugin shared] swift_getVersion];
    return result;
}

// 注册回调:接收Unity的GameObject名称和方法名
void IOS_registerNotificationCallback(const char* gameObjName, const char* methodName) {
    NSString* objName = [NSString stringWithUTF8String:gameObjName];
    NSString* method = [NSString stringWithUTF8String:methodName];
    [[UnityPlugin shared] registerNotificationCallback:objName methodName:method];
}

// 注销回调
void IOS_unregisterNotificationCallback() {
    [[UnityPlugin shared] unregisterNotificationCallback];
}

}

3. 修改Unity C#代码,接收异步回调

添加注册回调的调用逻辑,以及接收回调的处理方法:

using UnityEngine;
using System.Runtime.InteropServices;

public class PluginHelper : MonoBehaviour
{
    [DllImport("__Internal")]
    private static extern double IOS_getVersion();

    [DllImport("__Internal")]
    private static extern void IOS_registerNotificationCallback(string gameObjName, string methodName);

    [DllImport("__Internal")]
    private static extern void IOS_unregisterNotificationCallback();

    private void Start()
    {
        // 同步调用示例
        double result = IOS_getVersion();
        Debug.Log(result);

        // 注册异步回调:传入当前GameObject名称和接收方法名
        IOS_registerNotificationCallback(gameObject.name, "OnNotificationCallbackReceived");
    }

    // 接收iOS回调的方法(必须public,参数类型与Swift传递的一致)
    public void OnNotificationCallbackReceived(string callbackData)
    {
        Debug.Log("收到iOS回调数据:" + callbackData);
        // 此处添加自定义数据处理逻辑
    }

    // 对象销毁时注销回调,避免内存泄漏
    private void OnDestroy()
    {
        IOS_unregisterNotificationCallback();
    }
}

关键说明

  • UnitySendMessage:Unity官方提供的跨语言通信接口,参数依次为接收消息的GameObject名称、对象上的方法名、传递的字符串参数;如需传递复杂数据,可序列化为JSON字符串,在Unity端反序列化。
  • 内存管理:Swift中需在合适时机移除通知观察者,Unity端在对象销毁时调用注销函数,避免内存泄漏。
  • 数据兼容性:确保Swift传递的参数类型与Unity接收方法的参数类型一致,如需传递非字符串数据,需做格式转换。

内容的提问来源于stack exchange,提问作者Gorka C

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 09:55:08