232 lines
8.2 KiB
Swift
232 lines
8.2 KiB
Swift
import Flutter
|
||
import UIKit
|
||
import UnityLibrary
|
||
|
||
/// Unity插件类,用于注册Flutter与Unity之间的通信桥梁
|
||
public class UnityPlugin: NSObject, FlutterPlugin {
|
||
|
||
// Unity框架引用
|
||
private weak var unityFramework: UnityFramework?
|
||
private weak var flutterViewController: FlutterViewController?
|
||
|
||
// 单例实例
|
||
static var instance: UnityPlugin?
|
||
|
||
// 注册插件方法
|
||
public static func register(with registrar: FlutterPluginRegistrar) {
|
||
let channel = FlutterMethodChannel(
|
||
name: "com.example.ar_tourism_flutter_unity.unity",
|
||
binaryMessenger: registrar.messenger()
|
||
)
|
||
|
||
// 创建插件实例并保存单例引用
|
||
let instance = UnityPlugin(registrar: registrar)
|
||
self.instance = instance
|
||
|
||
// 设置方法调用处理器
|
||
registrar.addMethodCallDelegate(instance, channel: channel)
|
||
}
|
||
|
||
init(registrar: FlutterPluginRegistrar) {
|
||
super.init()
|
||
|
||
// 尝试获取AppDelegate中的Unity框架引用
|
||
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
|
||
self.unityFramework = appDelegate.unityFramework
|
||
}
|
||
|
||
// 尝试获取FlutterViewController
|
||
if let rootViewController = UIApplication.shared.keyWindow?.rootViewController as? FlutterViewController {
|
||
self.flutterViewController = rootViewController
|
||
} else if let rootVC = UIApplication.shared.keyWindow?.rootViewController {
|
||
// 如果根视图控制器不是FlutterViewController,尝试在子视图控制器中查找
|
||
self.flutterViewController = findFlutterViewController(rootVC)
|
||
}
|
||
}
|
||
|
||
// 递归查找FlutterViewController
|
||
private func findFlutterViewController(_ viewController: UIViewController) -> FlutterViewController? {
|
||
if let flutterVC = viewController as? FlutterViewController {
|
||
return flutterVC
|
||
}
|
||
|
||
if let navigationController = viewController as? UINavigationController {
|
||
for childVC in navigationController.viewControllers {
|
||
if let flutterVC = findFlutterViewController(childVC) {
|
||
return flutterVC
|
||
}
|
||
}
|
||
}
|
||
|
||
if let tabBarController = viewController as? UITabBarController {
|
||
for childVC in tabBarController.viewControllers ?? [] {
|
||
if let flutterVC = findFlutterViewController(childVC) {
|
||
return flutterVC
|
||
}
|
||
}
|
||
}
|
||
|
||
for childVC in viewController.children {
|
||
if let flutterVC = findFlutterViewController(childVC) {
|
||
return flutterVC
|
||
}
|
||
}
|
||
|
||
if let presentedVC = viewController.presentedViewController {
|
||
return findFlutterViewController(presentedVC)
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// 处理Flutter调用的方法
|
||
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
||
switch call.method {
|
||
case "initializeUnity":
|
||
initializeUnity(result: result)
|
||
|
||
case "checkAndRequestPermissions":
|
||
checkAndRequestPermissions(result: result)
|
||
|
||
case "start_unity":
|
||
startUnity(call: call, result: result)
|
||
|
||
case "closeUnity":
|
||
closeUnity(result: result)
|
||
|
||
case "sendMessageToUnity":
|
||
sendMessageToUnity(call: call, result: result)
|
||
|
||
default:
|
||
result(FlutterMethodNotImplemented)
|
||
}
|
||
}
|
||
|
||
// 初始化Unity
|
||
private func initializeUnity(result: @escaping FlutterResult) {
|
||
if unityFramework == nil {
|
||
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
|
||
appDelegate.initUnityFramework()
|
||
self.unityFramework = appDelegate.unityFramework
|
||
}
|
||
}
|
||
|
||
result(unityFramework != nil)
|
||
}
|
||
|
||
// 检查并请求权限
|
||
private func checkAndRequestPermissions(result: @escaping FlutterResult) {
|
||
// iOS中通常在Info.plist中已声明所需权限,这里简单返回true
|
||
// 如果有特定权限检查需求,可以在这里添加相应代码
|
||
result(true)
|
||
}
|
||
|
||
// 启动Unity
|
||
private func startUnity(call: FlutterMethodCall, result: @escaping FlutterResult) {
|
||
guard let args = call.arguments as? [String: Any] else {
|
||
result(FlutterError(code: "INVALID_ARGUMENTS", message: "参数无效", details: nil))
|
||
return
|
||
}
|
||
|
||
let token = args["token"] as? String ?? ""
|
||
let sceneName = args["sceneName"] as? String ?? "Main"
|
||
let returnToHome = args["returnToHome"] as? Bool ?? true
|
||
|
||
print("启动Unity: token=\(token), sceneName=\(sceneName), returnToHome=\(returnToHome)")
|
||
|
||
// 确保Unity已初始化
|
||
if unityFramework == nil {
|
||
initializeUnity(result: { success in
|
||
if success as? Bool == true {
|
||
self.loadUnityScene(sceneName: sceneName, token: token)
|
||
result(true)
|
||
} else {
|
||
result(FlutterError(code: "UNITY_INIT_FAILED", message: "Unity初始化失败", details: nil))
|
||
}
|
||
})
|
||
} else {
|
||
loadUnityScene(sceneName: sceneName, token: token)
|
||
result(true)
|
||
}
|
||
}
|
||
|
||
// 加载Unity场景
|
||
private func loadUnityScene(sceneName: String, token: String) {
|
||
// 向Unity发送加载场景的消息
|
||
if let unityFramework = unityFramework {
|
||
// 设置一些全局参数
|
||
unityFramework.sendMessageToGO(
|
||
withName: "GameManager",
|
||
functionName: "SetToken",
|
||
message: token
|
||
)
|
||
|
||
// 加载指定场景
|
||
unityFramework.sendMessageToGO(
|
||
withName: "GameManager",
|
||
functionName: "LoadScene",
|
||
message: sceneName
|
||
)
|
||
}
|
||
}
|
||
|
||
// 关闭Unity
|
||
private func closeUnity(result: @escaping FlutterResult) {
|
||
if let unityFramework = unityFramework {
|
||
unityFramework.pause(true)
|
||
}
|
||
result(true)
|
||
}
|
||
|
||
// 向Unity发送消息
|
||
private func sendMessageToUnity(call: FlutterMethodCall, result: @escaping FlutterResult) {
|
||
guard let args = call.arguments as? [String: Any],
|
||
let gameObject = args["gameObject"] as? String,
|
||
let methodName = args["methodName"] as? String,
|
||
let message = args["message"] as? String else {
|
||
result(FlutterError(code: "INVALID_ARGUMENTS", message: "参数无效", details: nil))
|
||
return
|
||
}
|
||
|
||
if let unityFramework = unityFramework {
|
||
unityFramework.sendMessageToGO(
|
||
withName: gameObject,
|
||
functionName: methodName,
|
||
message: message
|
||
)
|
||
result(true)
|
||
} else {
|
||
result(FlutterError(code: "UNITY_NOT_INITIALIZED", message: "Unity未初始化", details: nil))
|
||
}
|
||
}
|
||
|
||
// 接收从Unity发送的消息并转发到Flutter
|
||
public func receiveUnityMessage(_ message: String) {
|
||
let channel = FlutterMethodChannel(
|
||
name: "com.example.ar_tourism_flutter_unity.unity",
|
||
binaryMessenger: flutterViewController as! FlutterBinaryMessenger
|
||
)
|
||
|
||
channel.invokeMethod("onUnityMessage", arguments: message)
|
||
}
|
||
|
||
// 处理Unity返回事件
|
||
public func handleUnityBackPressed() {
|
||
let channel = FlutterMethodChannel(
|
||
name: "com.example.ar_tourism_flutter_unity.unity",
|
||
binaryMessenger: flutterViewController as! FlutterBinaryMessenger
|
||
)
|
||
|
||
channel.invokeMethod("onUnityBackPressed", arguments: nil)
|
||
}
|
||
|
||
// 处理Unity关闭事件
|
||
public func handleUnityClosed() {
|
||
let channel = FlutterMethodChannel(
|
||
name: "com.example.ar_tourism_flutter_unity.unity",
|
||
binaryMessenger: flutterViewController as! FlutterBinaryMessenger
|
||
)
|
||
|
||
channel.invokeMethod("onUnityClosed", arguments: nil)
|
||
}
|
||
} |