mm của Unity hoặc giữ lại tùy chọn của mình - bân ca
Bộ Công Cụ Tích Hợp UniOS
- Dự án Xcode của Unity được tạo tự động bằng mã và sẽ bị ghi đè mỗi lần tái tạo.
- Dự án Xcode của Unity có một tệp AppDelegate riêng.
- Kéo trực tiếp các file Xcode của Unity vào dự án Xcode của iOS sẽ gây rối loạn cấu trúc.
Bộ công cụ UniOSIntegrationKit chủ yếu giải quyết hai vấn đề đầu tiên: không thay đổi cấu trúc của dự án Xcode được Unity tạo ra, mà vẫn sử dụng các phương pháp (như Method-Swizzling, Build Script) để điều chỉnh hành vi từ bên ngoài, tránh phải sửa lại mỗi khi tái tạo dự án Xcode của Unity. Những hướng dẫn về cách tích hợp Unity3D với ứng dụng iOS gốc dành cho Xcode 7 & Unity 5 có thể tham khảo thêm tại tài liệu liên quan. Nhiều ý tưởng ở đây đã được tự động hóa theo cách lập trình dựa trên video hướng dẫn.
Tập tin NSObject+UnitySwizzling
được sử dụng để thực hiện Method-Swizzling nhưng cũng bao gồm các hoạt động liên quan đến UnityWindow. Tệp AppDelegate của Unity được gọi là UnityAppController, nếu kiểm tra kỹ hơn, bạn sẽ thấy trong tập tin .mm có các phương thức delegate như didFinishLaunchingWithOptions
. Trong khi đó, iOS vốn đã có một tệp AppDelegate riêng. Để giữ nguyên tệp này của iOS và truyền các sự kiện Delegate (chẳng hạn như ứng dụng chuyển sang nền, ứng dụng sắp kết thúc, v.v.) cho Unity, chúng ta sử dụng kỹ thuật Method-Swizzling. Thêm thông tin chi tiết có thể tìm thấy tại nshipster.vn.
Trước hết, hãy thay thế tệp main.mm mặc định của iOS bằng tệp main.mm của Unity và chỉnh sửa dòng sau:
const char* AppControllerClassName = "AppDelegate"; // Tên lớp đã triển khai AppDelegate trong dự án iOS
Sau đó, bạn có thể xóa tệp main.mm của Unity hoặc giữ lại tùy chọn của mình.
NSObject+UnitySwizzling.h
#import <Foundation/Foundation.h>
#import "AppDelegate.h"
@interface AppDelegate ()
@property(strong, nonatomic) UnityAppController *unityAppController;
@end
@interface AppDelegate (UnitySwizzling)
+ (NSMutableArray *)getUnityOriginalList;
+ (NSMutableArray *)getUnitySwizzlingList;
+ (NSMutableDictionary *)getUnitySwizzlingDict;
- (UIWindow *)getUnityWindow;
- (void)showUnityWindow;
- (void)hideUnityWindow;
@end
NSObject+UnitySwizzling.m
//
// NSObject+UnitySwizzling.m
//
// Được tạo bởi Fincher Justin vào ngày 25/6/17.
// Bản quyền © 2017. Mọi quyền được bảo lưu.
//
#import <objc/runtime.h>
#import "NSObject+UnitySwizzling.h"
#import "AppDelegate.h"
#import "UnityAppController.h"
#import "UnityMessageCenter.h"
@implementation AppDelegate (UnitySwizzling)
+ (NSMutableArray *)getUnityOriginalList {
return [NSMutableArray arrayWithObjects:
@"application:didFinishLaunchingWithOptions:",
@"applicationWillResignActive:",
@"applicationDidEnterBackground:",
@"applicationWillEnterForeground:",
@"applicationDidBecomeActive:", [Sam86.Vip Game Bài Nhiều Người Chơi Nhất](/post/2021-10-20/)
@"applicationWillTerminate:",
nil];
}
+ (NSMutableArray *)getUnitySwizzlingList {
NSMutableArray *array = [[AppDelegate getUnityOriginalList] mutableCopy];
for (int i = 0; i < [array count]; i++) {
NSString *originalString = (NSString *)[array objectAtIndex:i];
NSString *swizzledString = [NSString stringWithFormat:@"xxx%@", originalString];
[array replaceObjectAtIndex:i withObject:swizzledString];
}
return array;
}
+ (NSMutableDictionary *)getUnitySwizzlingDict {
return [NSMutableDictionary dictionaryWithObjects:
[AppDelegate getUnitySwizzlingList]
forKeys:
[AppDelegate getUnityOriginalList]];
}
- (UIWindow *)getUnityWindow {
return UnityGetMainWindow();
}
- (void)showUnityWindow {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[[UnityMessageCenter sharedManager] runCommand:@"OnUniShow" WithParameter:@""];
[[self getUnityWindow] makeKeyAndVisible];
}];
}
- (void)hideUnityWindow {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[[self window] makeKeyAndVisible]; [j88bet](/post/fakedrea/)
}];
}
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
NSMutableDictionary *dict = [AppDelegate getUnitySwizzlingDict];
NSArray *keys = [dict allKeys];
for (NSString *originalSelectorString in keys) {
NSString *swizzledSelectorString = dict[originalSelectorString];
NSLog(@"Method Swizzling From %@ to %@ ", originalSelectorString, swizzledSelectorString);
SEL originalSelector = NSSelectorFromString(originalSelectorString);
SEL swizzledSelector = NSSelectorFromString(swizzledSelectorString);
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
BOOL didAddMethod =
class_addMethod(class,
originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if [bân ca](/post/0cf20dbd2867da29/) (didAddMethod) {
class_replaceMethod(class,
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
});
}
#pragma mark - Method Swizzling
- (BOOL)xxxapplication:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSLog(@"xxxapplication:didFinishLaunchingWithOptions:launchOptions: Begin");
[self xxxapplication:application didFinishLaunchingWithOptions:launchOptions];
[self hideUnityWindow];
self.unityAppController = [[UnityAppController alloc] init];
[self.unityAppController application:application didFinishLaunchingWithOptions:launchOptions];
NSLog(@"xxxapplication:didFinishLaunchingWithOptions:launchOptions: End");
[self hideUnityWindow];
return YES;
}
- (void)xxxapplicationWillResignActive:(UIApplication *)application {
[self.unityAppController applicationWillResignActive:application];
[self xxxapplicationWillResignActive:application];
}
- (void)xxxapplicationDidEnterBackground:(UIApplication *)application {
NSLog(@"xxxapplicationDidEnterBackground: Begin");
[self.unityAppController applicationDidEnterBackground:application];
[self xxxapplicationDidEnterBackground:application];
}
- (void)xxxapplicationWillEnterForeground:(UIApplication *)application {
NSLog(@"xxxapplicationWillEnterForeground: Begin");
[self.unityAppController applicationWillEnterForeground:application];
[self xxxapplicationWillEnterForeground:application];
}
- (void)xxxapplicationDidBecomeActive:(UIApplication *)application {
NSLog(@"xxxapplicationDidBecomeActive: Begin");
[self.unityAppController applicationDidBecomeActive:application];
[self xxxapplicationDidBecomeActive:application];
}
- (void)xxxapplicationWillTerminate:(UIApplication *)application {
NSLog(@"xxxapplicationWillTerminate: Begin");
[self.unityAppController applicationWillTerminate:application];
[self xxxapplicationWillTerminate:application];
}
@end
UniOSIntegrationKitScript là một kịch bản xây dựng (Build Script), tác dụng là thay đổi đoạn mã trong UnityAppController.h
từ:
inline UnityAppController* GetAppController() {
return (UnityAppController*)[UIApplication sharedApplication].delegate;
}
thành:
inline UnityAppController* GetAppController() {
return (UnityAppController*)[UIApplication sharedApplication].unityAppController;
}
Lý do là khi sử dụng tệp đã triển khai AppDelegate của dự án iOS, [UIApplication sharedApplication].delegate
không còn là UnityAppController nữa mà [UIApplication sharedApplication].unityAppController
mới là, vì chúng ta đã khai báo trước đó:
@interface AppDelegate ()
@property(strong, nonatomic) UnityAppController *unityAppController;
@end
UniOSIntegrationKitScript.sh
#!/bin/sh
# UniOSIntegrationKitScript.sh
#
# Được tạo bởi Fincher Justin vào ngày 27/6/17.
# Bản quyền © 2017. Mọi quyền được bảo lưu.
set -x
echo "UniOSIntegrationKit"
find $SRCROOT/../ -name "UnityAppController.h"
find $SRCROOT/../ -name "UnityAppController.h" -print0 | xargs -0 sed -i "" "s/return (UnityAppController\*)\[UIApplication sharedApplication\]\.delegate;/return ((AppDelegate *)[UIApplication sharedApplication]\.delegate)\.unityAppController;/"
Các vấn đề thứ nhất và thứ hai cơ bản đã được giải quyết. Về vấn đề thứ ba, tôi từng muốn đóng gói toàn bộ phần Unity thành một Pod, nhưng do dự án outsourcing kéo dài và tôi cũng bắt đầu học lại nên chưa tiếp tục. Sẽ cân nhắc thêm khi có dự án tích hợp Unity vào iOS khác trong tương lai.