ar_tourism_flutter_unity/ios/Runner/UnityPlugin.swift
2025-05-14 18:24:12 +08:00

232 lines
8.2 KiB
Swift
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Flutter
import UIKit
import UnityLibrary
/// UnityFlutterUnity
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()
// AppDelegateUnity
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) {
// iOSInfo.plisttrue
//
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))
}
}
// UnityFlutter
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)
}
}