Commit 788b6a52 王帅

0.1.4 readme

1 个父辈 8f613225
正在显示 783 个修改的文件 包含 2409 行增加3 行删除
{
"process_id" : 48984,
"version" : "2019.4.39f1c1",
"app_path" : "/Applications/Unity/Hub/Editor/2019.4.39f1c1/Unity.app",
"app_contents_path" : "/Applications/Unity/Hub/Editor/2019.4.39f1c1/Unity.app/Contents"
}
\ No newline at end of file \ No newline at end of file
...@@ -503,4 +503,4 @@ ScriptsOnlyBuild: ...@@ -503,4 +503,4 @@ ScriptsOnlyBuild:
platform: 9 platform: 9
scenePathNames: scenePathNames:
- Assets/AASDKDemo/Scenes/AASDKDemoScene.unity - Assets/AASDKDemo/Scenes/AASDKDemoScene.unity
playerPath: /Users/ws/Desktop/ZAAUnityDemo/bbbbbbb playerPath: /Users/ws/Desktop/ZAAUnityDemo/111111
Base path: '/Applications/Unity/Hub/Editor/2019.4.39f1c1/Unity.app/Contents', plugins path '/Applications/Unity/Hub/Editor/2019.4.39f1c1/Unity.app/Contents/PlaybackEngines' Base path: '/Applications/Unity/Hub/Editor/2019.4.39f1c1/Unity.app/Contents', plugins path '/Applications/Unity/Hub/Editor/2019.4.39f1c1/Unity.app/Contents/PlaybackEngines'
Cmd: initializeCompiler Cmd: initializeCompiler
Cmd: compileSnippet
api=14 type=1 insize=1402 outsize=2318 kw= pd=UNITY_NO_DXT5nm UNITY_NO_RGBM UNITY_ENABLE_REFLECTION_BUFFERS UNITY_FRAMEBUFFER_FETCH_AVAILABLE UNITY_NO_SCREENSPACE_SHADOWS UNITY_PBS_USE_BRDF2 SHADER_API_MOBILE UNITY_HARDWARE_TIER2 UNITY_COLORSPACE_GAMMA UNITY_LIGHTMAP_DLDR_ENCODING ok=1
<linker>
<assembly fullname="UnityEngine">
<type fullname="UnityEngine.Object" preserve="nothing"/>
<type fullname="UnityEditor.VFXManager" preserve="nothing"/>
<type fullname="UnityEditor.PlayerSettings" preserve="nothing"/>
<type fullname="UnityEngine.Material" preserve="nothing"/>
<type fullname="UnityEngine.TextAsset" preserve="nothing"/>
<type fullname="UnityEngine.Shader" preserve="nothing"/>
<type fullname="UnityEditor.MonoScript" preserve="nothing"/>
<type fullname="UnityEditor.AudioManager" preserve="nothing"/>
<type fullname="UnityEditor.PhysicsManager" preserve="nothing"/>
<type fullname="UnityEditor.TimeManager" preserve="nothing"/>
<type fullname="UnityEditor.InputManager" preserve="nothing"/>
<type fullname="UnityEditor.TagManager" preserve="nothing"/>
<type fullname="UnityEditor.MonoManager" preserve="nothing"/>
<type fullname="UnityEngine.Rendering.GraphicsSettings" preserve="nothing"/>
<type fullname="UnityEngine.QualitySettings" preserve="nothing"/>
<type fullname="UnityEditor.Physics2DSettings" preserve="nothing"/>
<type fullname="UnityEngine.AudioBehaviour" preserve="nothing"/>
<type fullname="UnityEngine.Canvas" preserve="nothing"/>
<type fullname="UnityEngine.RectTransform" preserve="nothing"/>
<type fullname="UnityEngine.LightmapSettings" preserve="nothing"/>
<type fullname="UnityEngine.Sprite" preserve="nothing"/>
<type fullname="UnityEngine.Texture2D" preserve="nothing"/>
<type fullname="UnityEngine.Behaviour" preserve="nothing"/>
<type fullname="UnityEngine.MonoBehaviour" preserve="nothing"/>
<type fullname="UnityEngine.Transform" preserve="nothing"/>
<type fullname="UnityEngine.Component" preserve="nothing"/>
<type fullname="UnityEngine.GameObject" preserve="nothing"/>
<type fullname="UnityEngine.RenderSettings" preserve="nothing"/>
<type fullname="UnityEngine.AudioListener" preserve="nothing"/>
<type fullname="UnityEngine.Font" preserve="nothing"/>
<type fullname="UnityEngine.CanvasRenderer" preserve="nothing"/>
<type fullname="UnityEngine.Light" preserve="nothing"/>
<type fullname="UnityEngine.Texture" preserve="nothing"/>
<type fullname="UnityEngine.Cubemap" preserve="nothing"/>
<type fullname="UnityEngine.Camera" preserve="nothing"/>
</assembly>
<assembly fullname="Assembly-CSharp">
<type fullname="AASDKDemoScript" preserve="nothing"/>
</assembly>
<assembly fullname="UnityEngine.UI">
<type fullname="UnityEngine.EventSystems.EventSystem" preserve="nothing"/>
<type fullname="UnityEngine.EventSystems.StandaloneInputModule" preserve="nothing"/>
<type fullname="UnityEngine.UI.Button" preserve="nothing"/>
<type fullname="UnityEngine.UI.CanvasScaler" preserve="nothing"/>
<type fullname="UnityEngine.UI.GraphicRaycaster" preserve="nothing"/>
<type fullname="UnityEngine.UI.Image" preserve="nothing"/>
<type fullname="UnityEngine.UI.InputField" preserve="nothing"/>
<type fullname="UnityEngine.UI.Text" preserve="nothing"/>
</assembly>
</linker>
{"report":{"modules":[{"name":"Animation","dependencies":[{"name":"Animator","scenes":[],"dependencyType":0,"icon":null},{"name":"AnimatorController","scenes":[],"dependencyType":1,"icon":null},{"name":"AnimatorOverrideController","scenes":[],"dependencyType":0,"icon":null},{"name":"RuntimeAnimatorController","scenes":[],"dependencyType":1,"icon":null}]},{"name":"Audio","dependencies":[{"name":"AudioBehaviour","scenes":["Assets/AASDKDemo/Scenes/AASDKDemoScene.unity"],"dependencyType":0,"icon":null},{"name":"AudioClip","scenes":[],"dependencyType":0,"icon":null},{"name":"AudioListener","scenes":["Assets/AASDKDemo/Scenes/AASDKDemoScene.unity"],"dependencyType":0,"icon":null},{"name":"AudioManager","scenes":[],"dependencyType":1,"icon":null},{"name":"SampleClip","scenes":[],"dependencyType":1,"icon":null}]},{"name":"Core","dependencies":[{"name":"Behaviour","scenes":[],"dependencyType":1,"icon":null},{"name":"BuildSettings","scenes":[],"dependencyType":1,"icon":null},{"name":"Camera","scenes":["Assets/AASDKDemo/Scenes/AASDKDemoScene.unity"],"dependencyType":0,"icon":null},{"name":"Component","scenes":[],"dependencyType":1,"icon":null},{"name":"ComputeShader","scenes":[],"dependencyType":0,"icon":null},{"name":"Cubemap","scenes":["Assets/AASDKDemo/Scenes/AASDKDemoScene.unity"],"dependencyType":0,"icon":null},{"name":"CubemapArray","scenes":[],"dependencyType":0,"icon":null},{"name":"DelayedCallManager","scenes":[],"dependencyType":1,"icon":null},{"name":"EditorExtension","scenes":[],"dependencyType":1,"icon":null},{"name":"GameManager","scenes":[],"dependencyType":1,"icon":null},{"name":"GameObject","scenes":["Assets/AASDKDemo/Scenes/AASDKDemoScene.unity"],"dependencyType":0,"icon":null},{"name":"GlobalGameManager","scenes":[],"dependencyType":1,"icon":null},{"name":"GraphicsSettings","scenes":[],"dependencyType":0,"icon":null},{"name":"InputManager","scenes":[],"dependencyType":1,"icon":null},{"name":"LevelGameManager","scenes":[],"dependencyType":1,"icon":null},{"name":"Light","scenes":["Assets/AASDKDemo/Scenes/AASDKDemoScene.unity"],"dependencyType":0,"icon":null},{"name":"LightmapSettings","scenes":["Assets/AASDKDemo/Scenes/AASDKDemoScene.unity"],"dependencyType":0,"icon":null},{"name":"LightProbes","scenes":[],"dependencyType":0,"icon":null},{"name":"LowerResBlitTexture","scenes":[],"dependencyType":0,"icon":null},{"name":"Material","scenes":["Assets/AASDKDemo/Scenes/AASDKDemoScene.unity"],"dependencyType":0,"icon":null},{"name":"Mesh","scenes":[],"dependencyType":0,"icon":null},{"name":"MeshFilter","scenes":[],"dependencyType":0,"icon":null},{"name":"MeshRenderer","scenes":[],"dependencyType":0,"icon":null},{"name":"MonoBehaviour","scenes":["Assets/AASDKDemo/Scenes/AASDKDemoScene.unity"],"dependencyType":0,"icon":null},{"name":"MonoManager","scenes":[],"dependencyType":1,"icon":null},{"name":"MonoScript","scenes":["Assets/AASDKDemo/Scenes/AASDKDemoScene.unity"],"dependencyType":1,"icon":null},{"name":"NamedObject","scenes":["Assets/AASDKDemo/Scenes/AASDKDemoScene.unity"],"dependencyType":1,"icon":null},{"name":"Object","scenes":["Assets/AASDKDemo/Scenes/AASDKDemoScene.unity"],"dependencyType":0,"icon":null},{"name":"PlayerSettings","scenes":[],"dependencyType":1,"icon":null},{"name":"PreloadData","scenes":[],"dependencyType":0,"icon":null},{"name":"QualitySettings","scenes":[],"dependencyType":0,"icon":null},{"name":"RectTransform","scenes":["Assets/AASDKDemo/Scenes/AASDKDemoScene.unity"],"dependencyType":0,"icon":null},{"name":"ReflectionProbe","scenes":[],"dependencyType":0,"icon":null},{"name":"Renderer","scenes":[],"dependencyType":1,"icon":null},{"name":"RenderSettings","scenes":["Assets/AASDKDemo/Scenes/AASDKDemoScene.unity"],"dependencyType":0,"icon":null},{"name":"RenderTexture","scenes":[],"dependencyType":0,"icon":null},{"name":"ResourceManager","scenes":[],"dependencyType":1,"icon":null},{"name":"RuntimeInitializeOnLoadManager","scenes":[],"dependencyType":1,"icon":null},{"name":"ScriptMapper","scenes":[],"dependencyType":1,"icon":null},{"name":"Shader","scenes":["Assets/AASDKDemo/Scenes/AASDKDemoScene.unity"],"dependencyType":0,"icon":null},{"name":"Sprite","scenes":["Assets/AASDKDemo/Scenes/AASDKDemoScene.unity"],"dependencyType":0,"icon":null},{"name":"SpriteAtlas","scenes":[],"dependencyType":0,"icon":null},{"name":"SpriteRenderer","scenes":[],"dependencyType":0,"icon":null},{"name":"TagManager","scenes":[],"dependencyType":1,"icon":null},{"name":"TextAsset","scenes":["Assets/AASDKDemo/Scenes/AASDKDemoScene.unity"],"dependencyType":0,"icon":null},{"name":"Texture","scenes":[],"dependencyType":1,"icon":null},{"name":"Texture2D","scenes":["Assets/AASDKDemo/Scenes/AASDKDemoScene.unity"],"dependencyType":0,"icon":null},{"name":"Texture2DArray","scenes":[],"dependencyType":0,"icon":null},{"name":"Texture3D","scenes":[],"dependencyType":0,"icon":null},{"name":"TimeManager","scenes":[],"dependencyType":1,"icon":null},{"name":"Transform","scenes":[],"dependencyType":1,"icon":null},{"name":"Required by Animation Module","scenes":[],"dependencyType":2,"icon":"package/com.unity.modules.animation"},{"name":"Required by Audio Module","scenes":[],"dependencyType":2,"icon":"package/com.unity.modules.audio"},{"name":"Required by GameCenter Module","scenes":[],"dependencyType":2,"icon":"package/com.unity.modules.gamecenter"},{"name":"Required by ImageConversion Module","scenes":[],"dependencyType":2,"icon":"package/com.unity.modules.imageconversion"},{"name":"Required by IMGUI Module","scenes":[],"dependencyType":2,"icon":"package/com.unity.modules.imgui"},{"name":"Required by InputLegacy Module","scenes":[],"dependencyType":2,"icon":"package/com.unity.modules.inputlegacy"},{"name":"Required by TextRendering Module","scenes":[],"dependencyType":2,"icon":"package/com.unity.modules.textrendering"},{"name":"Required by UI Module","scenes":[],"dependencyType":2,"icon":"package/com.unity.modules.ui"}]},{"name":"GameCenter","dependencies":[]},{"name":"ImageConversion","dependencies":[{"name":"Required by GameCenter Module","scenes":[],"dependencyType":2,"icon":"package/com.unity.modules.gamecenter"}]},{"name":"IMGUI","dependencies":[]},{"name":"InputLegacy","dependencies":[{"name":"Required by IMGUI Module","scenes":[],"dependencyType":2,"icon":"package/com.unity.modules.imgui"}]},{"name":"SharedInternals","dependencies":[{"name":"Required by Animation Module","scenes":[],"dependencyType":2,"icon":"package/com.unity.modules.animation"},{"name":"Required by Audio Module","scenes":[],"dependencyType":2,"icon":"package/com.unity.modules.audio"},{"name":"Required by Core Module","scenes":[],"dependencyType":2,"icon":"package/com.unity.modules.core"},{"name":"Required by GameCenter Module","scenes":[],"dependencyType":2,"icon":"package/com.unity.modules.gamecenter"},{"name":"Required by ImageConversion Module","scenes":[],"dependencyType":2,"icon":"package/com.unity.modules.imageconversion"},{"name":"Required by IMGUI Module","scenes":[],"dependencyType":2,"icon":"package/com.unity.modules.imgui"},{"name":"Required by InputLegacy Module","scenes":[],"dependencyType":2,"icon":"package/com.unity.modules.inputlegacy"},{"name":"Required by TextRendering Module","scenes":[],"dependencyType":2,"icon":"package/com.unity.modules.textrendering"},{"name":"Required by UI Module","scenes":[],"dependencyType":2,"icon":"package/com.unity.modules.ui"}]},{"name":"TextRendering","dependencies":[{"name":"Font","scenes":["Assets/AASDKDemo/Scenes/AASDKDemoScene.unity"],"dependencyType":0,"icon":null},{"name":"Required by IMGUI Module","scenes":[],"dependencyType":2,"icon":"package/com.unity.modules.imgui"},{"name":"Required by UI Module","scenes":[],"dependencyType":2,"icon":"package/com.unity.modules.ui"}]},{"name":"UI","dependencies":[{"name":"Canvas","scenes":["Assets/AASDKDemo/Scenes/AASDKDemoScene.unity"],"dependencyType":0,"icon":null},{"name":"CanvasGroup","scenes":[],"dependencyType":0,"icon":null},{"name":"CanvasRenderer","scenes":["Assets/AASDKDemo/Scenes/AASDKDemoScene.unity"],"dependencyType":0,"icon":null}]}]}}
\ No newline at end of file \ No newline at end of file
-out="/Users/ws/Desktop/Zplay/ZAnti-Addiction/ZAnti-Addiction-Unity/AASDK-Unity/Temp/StagingArea/Data/Managed/tempStrip" -x="/Users/ws/Desktop/Zplay/ZAnti-Addiction/ZAnti-Addiction-Unity/AASDK-Unity/Temp/StagingArea/Data/Managed/../platform_native_link.xml" -x="/var/folders/3f/mrlf6c5d7qn5tdqc_msdhxl40000gn/T/tmp2c1f8a53.tmp" -x="/Users/ws/Desktop/Zplay/ZAnti-Addiction/ZAnti-Addiction-Unity/AASDK-Unity/Temp/StagingArea/Data/Managed/TypesInScenes.xml" -d="/Users/ws/Desktop/Zplay/ZAnti-Addiction/ZAnti-Addiction-Unity/AASDK-Unity/Temp/StagingArea/Data/Managed" --include-unity-root-assembly="/Users/ws/Desktop/Zplay/ZAnti-Addiction/ZAnti-Addiction-Unity/AASDK-Unity/Temp/StagingArea/Data/Managed/Assembly-CSharp.dll" --include-unity-root-assembly="/Users/ws/Desktop/Zplay/ZAnti-Addiction/ZAnti-Addiction-Unity/AASDK-Unity/Temp/StagingArea/Data/Managed/UnityEngine.UI.dll" --dotnetruntime=il2cpp --dotnetprofile=unityaot --use-editor-options --include-directory="/Users/ws/Desktop/Zplay/ZAnti-Addiction/ZAnti-Addiction-Unity/AASDK-Unity/Temp/StagingArea/Data/Managed" --rule-set=Conservative --editor-data-file="/Users/ws/Desktop/Zplay/ZAnti-Addiction/ZAnti-Addiction-Unity/AASDK-Unity/Temp/StagingArea/Data/Managed/EditorToUnityLinkerData.json" --platform=iOS --enable-engine-module-stripping --engine-modules-asset-file="/Applications/Unity/Hub/Editor/2019.4.39f1c1/PlaybackEngines/iOSSupport/Whitelists/../modules.asset"
\ No newline at end of file \ No newline at end of file
wait-for-native-debugger=0
vr-enabled=0
hdr-display-enabled=0
此文件类型无法预览
此文件的差异太大,无法显示。
#pragma once
// Enabling this will force app to do a hard crash instead of a nice exit when UnhandledException
// is thrown. This will force iOS to generate a standard crash report, that can be submitted to
// iTunes by app users and inspected by developers.
#define ENABLE_IOS_CRASH_REPORTING 1
// Enabling this will add a custom Objective-C Uncaught Exception handler, which will print out
// exception information to console.
#define ENABLE_OBJC_UNCAUGHT_EXCEPTION_HANDLER 1
// Enable custom crash reporter to capture crashes. Crash logs will be available to scripts via
// CrashReport API.
#define ENABLE_CUSTOM_CRASH_REPORTER 0
// Enable submission of custom crash reports to Unity servers. This will enable custom crash
// reporter.
#define ENABLE_CRASH_REPORT_SUBMISSION 0
#if ENABLE_CRASH_REPORT_SUBMISSION && !ENABLE_CUSTOM_CRASH_REPORTER
#undef ENABLE_CUSTOM_CRASH_REPORTER
#define ENABLE_CUSTOM_CRASH_REPORTER 1
#endif
#if PLATFORM_TVOS
#undef ENABLE_CUSTOM_CRASH_REPORTER
#define ENABLE_CUSTOM_CRASH_REPORTER 0
#endif
extern "C" void UnityInstallPostCrashCallback();
void InitCrashHandling();
#import "PLCrashReporter.h"
#import "CrashReporter.h"
#include "UndefinePlatforms.h"
#include <mach-o/ldsyms.h>
#include "RedefinePlatforms.h"
extern "C" NSString* UnityGetCrashReportsPath();
static NSUncaughtExceptionHandler* gsCrashReporterUEHandler = NULL;
static decltype(_mh_execute_header) * sExecuteHeader = NULL;
extern "C" void UnitySetExecuteMachHeader(const decltype(_mh_execute_header)* header)
{
sExecuteHeader = header;
}
extern "C" const decltype(_mh_execute_header) * UnityGetExecuteMachHeader() {
return sExecuteHeader;
}
static void SavePendingCrashReport()
{
if (![[UnityPLCrashReporter sharedReporter] hasPendingCrashReport])
return;
NSFileManager *fm = [NSFileManager defaultManager];
NSError *error;
if (![fm createDirectoryAtPath: UnityGetCrashReportsPath() withIntermediateDirectories: YES attributes: nil error: &error])
{
::printf("CrashReporter: could not create crash report directory: %s\n", [[error localizedDescription] UTF8String]);
return;
}
NSData *data = [[UnityPLCrashReporter sharedReporter] loadPendingCrashReportDataAndReturnError: &error];
if (data == nil)
{
::printf("CrashReporter: failed to load crash report data: %s\n", [[error localizedDescription] UTF8String]);
return;
}
NSString* file = [UnityGetCrashReportsPath() stringByAppendingPathComponent: @"crash-"];
unsigned long long seconds = (unsigned long long)[[NSDate date] timeIntervalSince1970];
file = [file stringByAppendingString: [NSString stringWithFormat: @"%llu", seconds]];
file = [file stringByAppendingString: @".plcrash"];
if ([data writeToFile: file atomically: YES])
{
::printf("CrashReporter: saved pending crash report.\n");
if (![[UnityPLCrashReporter sharedReporter] purgePendingCrashReportAndReturnError: &error])
{
::printf("CrashReporter: couldn't remove pending report: %s\n", [[error localizedDescription] UTF8String]);
}
}
else
{
::printf("CrashReporter: couldn't save crash report.\n");
}
// Now copy out a pending version that we can delete if/when we send it
file = [UnityGetCrashReportsPath() stringByAppendingPathComponent: @"crash-pending.plcrash"];
if ([data writeToFile: file atomically: YES])
{
::printf("CrashReporter: saved copy of pending crash report.\n");
}
else
{
::printf("CrashReporter: couldn't save copy of pending crash report.\n");
}
}
static void InitCrashReporter()
{
NSError *error;
UnityInstallPostCrashCallback();
if ([[UnityPLCrashReporter sharedReporter] enableCrashReporterAndReturnError: &error])
::printf("CrashReporter: initialized\n");
else
NSLog(@"CrashReporter: could not enable crash reporter: %@", error);
SavePendingCrashReport();
}
static void UncaughtExceptionHandler(NSException *exception)
{
NSLog(@"Uncaught exception: %@: %@\n%@", [exception name], [exception reason], [exception callStackSymbols]);
if (gsCrashReporterUEHandler)
gsCrashReporterUEHandler(exception);
}
static void InitObjCUEHandler()
{
// Crash reporter sets its own handler, so we have to save it and call it manually
gsCrashReporterUEHandler = NSGetUncaughtExceptionHandler();
NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);
}
void InitCrashHandling()
{
#if ENABLE_CUSTOM_CRASH_REPORTER
InitCrashReporter();
#endif
#if ENABLE_OBJC_UNCAUGHT_EXCEPTION_HANDLER
InitObjCUEHandler();
#endif
}
// This function will be called when AppDomain.CurrentDomain.UnhandledException event is triggered.
// When running on device the app will do a hard crash and it will generate a crash log.
extern "C" void CrashedCheckBelowForHintsWhy()
{
#if ENABLE_IOS_CRASH_REPORTING || ENABLE_CUSTOM_CRASH_REPORTER
// Make app crash hard here
__builtin_trap();
// Just in case above doesn't work
abort();
#endif
}
/* SINGLE CPP FILE TO GENERATE SEAMLESS BRIDGE BETWEEN BINARIES < SHARED ENGINE LIBRARY WITH ABSTRACT EXTERN FUNCTIONS> | < PLAYER EXECUTABLE WITH ABSTRACT FUNCTION IMPLEMENTATION >
1. if building shared engine library this file will:
define body for Unity* methods that proxy call to actual method
actual method will be set later from outside with respective call to SetUnity*Body
defines SetUnity*Body method to set actual method for call, theese functions are exported from library
2. if building player against shared engine library this file will:
calls SetUnity*Body providing actual method to be called by shared engine library later
wraps all SetUnity*Body calls in one single method SetAllUnityFunctionsForDynamicPlayerLib
- notes:
file will be included only if development / il2ccp and:
- for xcode project if BuildSettings.UseDynamicPlayerLib is true
- for player if (build.pl staticLib=1, jam BUILD_IOS_DYNAMIC_PLAYER=1)
DynamicLibEngineAPI-functions.h include list of functions to proxy calls from player to trampoline
- each function inlist is defined with UnityExternCall or UnityExternCall4StaticMember
*/
// deal with __VA_ARGS__ to convert them to formated lists with provided M macro
#define VA_ARGS_COUNT(...) INTERNAL_GET_ARG_COUNT_PRIVATE(0, ## __VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#define INTERNAL_GET_ARG_COUNT_PRIVATE(_0, _1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, _9_, _10_, _11_, _12_, _13_, _14_, _15_, _16_, _17_, _18_, _19_, _20_, count, ...) count
#define JOIN_VA_ARGS_0(M, ...)
#define JOIN_VA_ARGS_1(M, T1) M(T1,1)
#define JOIN_VA_ARGS_2(M, T1, T2) M(T1,1), M(T2,2)
#define JOIN_VA_ARGS_3(M, T1, T2, T3) M(T1,1), M(T2,2), M(T3,3)
#define JOIN_VA_ARGS_4(M, T1, T2, T3, T4) M(T1,1), M(T2,2), M(T3,3), M(T4,4)
#define JOIN_VA_ARGS_5(M, T1, T2, T3, T4, T5) M(T1,1), M(T2,2), M(T3,3), M(T4,4), M(T5,5)
#define JOIN_VA_ARGS_6(M, T1, T2, T3, T4, T5, T6) M(T1,1), M(T2,2), M(T3,3), M(T4,4), M(T5,5), M(T6,6)
#define JOIN_VA_ARGS_7(M, T1, T2, T3, T4, T5, T6, T7) M(T1,1), M(T2,2), M(T3,3), M(T4,4), M(T5,5), M(T6,6), M(T7,7)
#define JOIN_VA_ARGS_8(M, T1, T2, T3, T4, T5, T6, T7, T8) M(T1,1), M(T2,2), M(T3,3), M(T4,4), M(T5,5), M(T6,6), M(T7,7), M(T8,8)
#define JOIN_VA_ARGS_9(M, T1, T2, T3, T4, T5, T6, T7, T8, T9) M(T1,1), M(T2,2), M(T3,3), M(T4,4), M(T5,5), M(T6,6), M(T7,7), M(T8,8), M(T9,9)
#define JOIN_VA_ARGS___(M, N, ...) JOIN_VA_ARGS_##N(M, __VA_ARGS__ )
#define JOIN_VA_ARGS__(M, N, ...) JOIN_VA_ARGS___(M,N,__VA_ARGS__)
#define JOIN_VA_ARGS_(M, ...) JOIN_VA_ARGS__(M,VA_ARGS_COUNT(__VA_ARGS__), __VA_ARGS__)
#define JOIN_VA_ARGS(M, ...) JOIN_VA_ARGS_(M,__VA_ARGS__)
// convert to function definition params:
// egz: VA_ARGS_TO_PARAMS(int, char, bool) expands to: int p3, char p2, bool p1
#define VA_JOIN_AS_PARAMS(type, index) type p##index
#define VA_ARGS_TO_PARAMS(...) JOIN_VA_ARGS(VA_JOIN_AS_PARAMS,__VA_ARGS__)
// convert to function call params
// egz: VA_ARGS_TO_CALL(int,char,bool) exapnds to: p3, p2, p1
#define VA_JOIN_AS_CALL(type, index) p##index
#define VA_ARGS_TO_CALL(...) JOIN_VA_ARGS(VA_JOIN_AS_CALL,__VA_ARGS__)
#ifndef UNITY_ENGINE_DYNAMICLIB_MODE
#define UNITY_ENGINE_DYNAMICLIB_MODE 0
#endif
#if UNITY_ENGINE_DYNAMICLIB_MODE
// [ part of Unity Player ]
// this part generates Unity* functions that act as proxy to call actual function from trampoline
// for each function in DynamicLibEngineAPI-functions.h will be generated proxy function
// proxy for extern "C" function
// egz: UnityExternCall(int, UnityTestFunctionName, int);
// will expand to:
// static int(*gPtrUnityTestFunctionName)(int) = nullptr;
// extern "C" int UnityTestFunctionName(int p1) {
// assert(gPtrUnityTestFunctionName) != nullptr);
// return gPtrUnityTestFunctionName(p1);
// }
// __attribute__((visibility("default")))
// extern "C" void SetUnityTestFunctionNameBody(decltype(&UnityTestFunctionName) fPtr) {
// gPtrUnityTestFunctionName = fPtr;
// }
#define UnityExternCall(returnType, funcName, ...) \
static returnType(*gPtr##funcName)(__VA_ARGS__) = nullptr; \
extern "C" returnType funcName(VA_ARGS_TO_PARAMS(__VA_ARGS__)) {\
assert(gPtr##funcName != nullptr); \
return gPtr##funcName(VA_ARGS_TO_CALL(__VA_ARGS__)); \
} \
__attribute__((visibility("default"))) \
extern "C" void Set##funcName##Body(decltype(&funcName) fPtr) { \
gPtr##funcName = fPtr; \
}
// proxy for class static methods
// egz: UnityExternCall4StaticMember(int, MyClass MyMethod, int);
// will expand to:
// static int(*gPtrMyClassMyMethod)(int) = nullptr;
// int MyClass::MyMethod(int p1) {
// assert(gPtrMyClassMyMethod) != nullptr);
// return gPtrMyClassMyMethod(p1);
// }
// __attribute__((visibility("default")))
// extern "C" void SetMyClassMyMethodBody(decltype(gPtrMyClassMyMethod) fPtr) {
// gPtrMyClassMyMethod = fPtr;
// }
#define UnityExternCall4StaticMember(returnType, className, funcName, ...) \
static returnType(*gPtr##className##funcName)(__VA_ARGS__) = nullptr; \
returnType className::funcName(VA_ARGS_TO_PARAMS(__VA_ARGS__)) { \
assert(gPtr##className##funcName != nullptr); \
return gPtr##className##funcName(VA_ARGS_TO_CALL(__VA_ARGS__)); \
} \
__attribute__((visibility("default"))) \
extern "C" void Set##className##funcName##Body(decltype(gPtr##className##funcName) fPtr) { \
gPtr##className##funcName = fPtr; \
}
#include "PlatformDependent/iPhonePlayer/Trampoline/Classes/Unity/UnitySharedDecls.h"
#include "PlatformDependent/iPhonePlayer/Trampoline/Classes/Unity/UnityRendering.h"
#include "PlatformDependent/iPhonePlayer/TrampolineInterface.h"
#include "Runtime/Graphics/DisplayManager.h"
#include "Runtime/Input/LocationService.h"
#import <UIKit/UIKit.h>
#include "External/baselib/builds/Include/PreExternalInclude.h"
#include <mach-o/ldsyms.h>
#include "External/baselib/builds/Include/PostExternalInclude.h"
#include "DynamicLibEngineAPI-functions.h"
#undef UnityExternCall
#undef UnityExternCall4StaticMember
#else
// [ part of Xcode project ]
// for each function defined in DynamicLibEngineAPI-functions.h will be generated SetUnity*Body function
// for extern "C" functions
// egz: UnityExternCall(int, UnityTestFunctionName, int);
// will expand to:
// extern "C" UnityTestFunctionName(int);
// extern "C" SetUnityTestFunctionName(decltype(&UnityTestFunctionName));
#define UnityExternCall(returnType, funcName, ...) \
extern "C" returnType funcName(__VA_ARGS__); \
extern "C" void Set##funcName##Body(decltype(&funcName));
// for class static method
// egz: UnityExternCall4StaticMember(int, MyClass MyMethod, int);
// will expand to:
// extern "C" void SetMyClassMyMethodBody(decltype(&MyClass::MyMethod));
#define UnityExternCall4StaticMember(returnType, className, funcName, ...) \
extern "C" void Set##className##funcName##Body(decltype(&className::funcName));
#include "UnityRendering.h"
#include "Classes/iPhone_Sensors.h"
#include "UndefinePlatforms.h"
#include <mach-o/ldsyms.h>
#include "RedefinePlatforms.h"
#include "DynamicLibEngineAPI-functions.h"
#undef UnityExternCall
#undef UnityExternCall4StaticMember
// single function to call every Set*Body function from DynamicLibEngineAPI-functions.h
#define UnityExternCall(returnType, funcName, ...) Set##funcName##Body(funcName);
#define UnityExternCall4StaticMember(returnType, className, funcName, ...) Set##className##funcName##Body(className::funcName)
extern "C" void SetAllUnityFunctionsForDynamicPlayerLib()
{
#include "DynamicLibEngineAPI-functions.h"
}
#undef UnityExternCall
#undef UnityExternCall4StaticMember
#endif
/*
* Author: Landon Fuller <landonf@plausiblelabs.com>
*
* Copyright (c) 2008-2009 Plausible Labs Cooperative, Inc.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#import <Foundation/Foundation.h>
/**
* @ingroup functions
*
* Prototype of a callback function used to execute additional user code with signal information as provided
* by PLCrashReporter. Called upon completion of crash handling, after the crash report has been written to disk.
*
* @param info The signal info.
* @param uap The crash's threads context.
* @param context The API client's supplied context value.
*
* @sa @ref async_safety
* @sa PLCrashReporter::setPostCrashCallbacks:
*/
typedef void (*UnityPLCrashReporterPostCrashSignalCallback)(siginfo_t *info, ucontext_t *uap, void *context);
/**
* @ingroup types
*
* This structure contains callbacks supported by PLCrashReporter to allow the host application to perform
* additional tasks prior to program termination after a crash has occured.
*
* @sa @ref async_safety
*/
typedef struct UnityPLCrashReporterCallbacks
{
/** The version number of this structure. If not one of the defined version numbers for this type, the behavior
* is undefined. The current version of this structure is 0. */
uint16_t version;
/** An arbitrary user-supplied context value. This value may be NULL. */
void *context;
/** The callback used to report caught signal information. In version 0 of this structure, all crashes will be
* reported via this function. */
UnityPLCrashReporterPostCrashSignalCallback handleSignal;
} UnityPLCrashReporterCallbacks;
@interface UnityPLCrashReporter : NSObject
{
@private
/** YES if the crash reporter has been enabled */
BOOL _enabled;
/** Application identifier */
NSString *_applicationIdentifier;
/** Application version */
NSString *_applicationVersion;
/** Path to the crash reporter internal data directory */
NSString *_crashReportDirectory;
}
+ (UnityPLCrashReporter *)sharedReporter;
- (BOOL)hasPendingCrashReport;
- (NSData *)loadPendingCrashReportData;
- (NSData *)loadPendingCrashReportDataAndReturnError:(NSError **)outError;
- (NSData *)generateLiveReport;
- (NSData *)generateLiveReportAndReturnError:(NSError **)outError;
- (BOOL)purgePendingCrashReport;
- (BOOL)purgePendingCrashReportAndReturnError:(NSError **)outError;
- (BOOL)enableCrashReporter;
- (BOOL)enableCrashReporterAndReturnError:(NSError **)outError;
- (void)setCrashCallbacks:(UnityPLCrashReporterCallbacks *)callbacks;
@end
#pragma once
#include "LifeCycleListener.h"
@protocol AppDelegateListener<LifeCycleListener>
@optional
// these do not have apple defined notifications, so we use our own notifications
// notification will be posted from
// - (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
// notification user data is deviceToken
- (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSNotification*)notification;
// notification will be posted from
// - (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
// notification user data is error
- (void)didFailToRegisterForRemoteNotificationsWithError:(NSNotification*)notification;
// notification will be posted from
// - (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo
// notification user data is userInfo
- (void)didReceiveRemoteNotification:(NSNotification*)notification;
// notification will be posted from
// - (void)application:(UIApplication*)application didReceiveLocalNotification:(UILocalNotification*)notification
// notification user data is notification
- (void)didReceiveLocalNotification:(NSNotification*)notification;
// notification will be posted from
// - (BOOL)application:(UIApplication*)application openURL:(NSURL*)url sourceApplication:(NSString*)sourceApplication annotation:(id)annotation
// notification user data is the NSDictionary containing all the params
- (void)onOpenURL:(NSNotification*)notification;
// notification will be posted from
// - (BOOL)application:(UIApplication*)application willFinishLaunchingWithOptions:(NSDictionary*)launchOptions
// notification user data is the NSDictionary containing launchOptions
- (void)applicationWillFinishLaunchingWithOptions:(NSNotification*)notification;
// notification will be posted from
// - (void)application:(UIApplication*)application handleEventsForBackgroundURLSession:(nonnull NSString *)identifier completionHandler:(nonnull void (^)())completionHandler
// notification user data is NSDictionary with one item where key is session identifier and value is completion handler
- (void)onHandleEventsForBackgroundURLSession:(NSNotification*)notification;
// these are just hooks to existing notifications
- (void)applicationDidReceiveMemoryWarning:(NSNotification*)notification;
- (void)applicationSignificantTimeChange:(NSNotification*)notification;
- (void)applicationWillChangeStatusBarFrame:(NSNotification*)notification;
- (void)applicationWillChangeStatusBarOrientation:(NSNotification*)notification;
@end
void UnityRegisterAppDelegateListener(id<AppDelegateListener> obj);
void UnityUnregisterAppDelegateListener(id<AppDelegateListener> obj);
extern "C" __attribute__((visibility("default"))) NSString* const kUnityDidRegisterForRemoteNotificationsWithDeviceToken;
extern "C" __attribute__((visibility("default"))) NSString* const kUnityDidFailToRegisterForRemoteNotificationsWithError;
extern "C" __attribute__((visibility("default"))) NSString* const kUnityDidReceiveRemoteNotification;
extern "C" __attribute__((visibility("default"))) NSString* const kUnityDidReceiveLocalNotification;
extern "C" __attribute__((visibility("default"))) NSString* const kUnityOnOpenURL;
extern "C" __attribute__((visibility("default"))) NSString* const kUnityWillFinishLaunchingWithOptions;
extern "C" __attribute__((visibility("default"))) NSString* const kUnityHandleEventsForBackgroundURLSession;
#include "AppDelegateListener.h"
#define DEFINE_NOTIFICATION(name) extern "C" __attribute__((visibility ("default"))) NSString* const name = @#name;
DEFINE_NOTIFICATION(kUnityDidRegisterForRemoteNotificationsWithDeviceToken);
DEFINE_NOTIFICATION(kUnityDidFailToRegisterForRemoteNotificationsWithError);
DEFINE_NOTIFICATION(kUnityDidReceiveRemoteNotification);
DEFINE_NOTIFICATION(kUnityDidReceiveLocalNotification);
DEFINE_NOTIFICATION(kUnityOnOpenURL);
DEFINE_NOTIFICATION(kUnityWillFinishLaunchingWithOptions);
DEFINE_NOTIFICATION(kUnityHandleEventsForBackgroundURLSession);
#undef DEFINE_NOTIFICATION
void UnityRegisterAppDelegateListener(id<AppDelegateListener> obj)
{
#define REGISTER_SELECTOR(sel, notif_name) \
if([obj respondsToSelector:sel]) \
[[NSNotificationCenter defaultCenter] addObserver:obj \
selector:sel \
name:notif_name \
object:nil \
]; \
UnityRegisterLifeCycleListener(obj);
REGISTER_SELECTOR(@selector(didRegisterForRemoteNotificationsWithDeviceToken:), kUnityDidRegisterForRemoteNotificationsWithDeviceToken);
REGISTER_SELECTOR(@selector(didFailToRegisterForRemoteNotificationsWithError:), kUnityDidFailToRegisterForRemoteNotificationsWithError);
REGISTER_SELECTOR(@selector(didReceiveRemoteNotification:), kUnityDidReceiveRemoteNotification);
REGISTER_SELECTOR(@selector(didReceiveLocalNotification:), kUnityDidReceiveLocalNotification);
REGISTER_SELECTOR(@selector(onOpenURL:), kUnityOnOpenURL);
REGISTER_SELECTOR(@selector(applicationDidReceiveMemoryWarning:), UIApplicationDidReceiveMemoryWarningNotification);
REGISTER_SELECTOR(@selector(applicationSignificantTimeChange:), UIApplicationSignificantTimeChangeNotification);
#if !PLATFORM_TVOS
REGISTER_SELECTOR(@selector(applicationWillChangeStatusBarFrame:), UIApplicationWillChangeStatusBarFrameNotification);
REGISTER_SELECTOR(@selector(applicationWillChangeStatusBarOrientation:), UIApplicationWillChangeStatusBarOrientationNotification);
#endif
REGISTER_SELECTOR(@selector(applicationWillFinishLaunchingWithOptions:), kUnityWillFinishLaunchingWithOptions);
REGISTER_SELECTOR(@selector(onHandleEventsForBackgroundURLSession:), kUnityHandleEventsForBackgroundURLSession);
#undef REGISTER_SELECTOR
}
void UnityUnregisterAppDelegateListener(id<AppDelegateListener> obj)
{
UnityUnregisterLifeCycleListener(obj);
[[NSNotificationCenter defaultCenter] removeObserver: obj name: kUnityDidRegisterForRemoteNotificationsWithDeviceToken object: nil];
[[NSNotificationCenter defaultCenter] removeObserver: obj name: kUnityDidFailToRegisterForRemoteNotificationsWithError object: nil];
[[NSNotificationCenter defaultCenter] removeObserver: obj name: kUnityDidReceiveRemoteNotification object: nil];
[[NSNotificationCenter defaultCenter] removeObserver: obj name: kUnityDidReceiveLocalNotification object: nil];
[[NSNotificationCenter defaultCenter] removeObserver: obj name: kUnityOnOpenURL object: nil];
[[NSNotificationCenter defaultCenter] removeObserver: obj name: UIApplicationDidReceiveMemoryWarningNotification object: nil];
[[NSNotificationCenter defaultCenter] removeObserver: obj name: UIApplicationSignificantTimeChangeNotification object: nil];
#if !PLATFORM_TVOS
[[NSNotificationCenter defaultCenter] removeObserver: obj name: UIApplicationWillChangeStatusBarFrameNotification object: nil];
[[NSNotificationCenter defaultCenter] removeObserver: obj name: UIApplicationWillChangeStatusBarOrientationNotification object: nil];
#endif
}
#pragma once
// important app life-cycle events
@protocol LifeCycleListener<NSObject>
@optional
- (void)didFinishLaunching:(NSNotification*)notification;
- (void)didBecomeActive:(NSNotification*)notification;
- (void)willResignActive:(NSNotification*)notification;
- (void)didEnterBackground:(NSNotification*)notification;
- (void)willEnterForeground:(NSNotification*)notification;
- (void)willTerminate:(NSNotification*)notification;
- (void)unityDidUnload:(NSNotification*)notification;
- (void)unityDidQuit:(NSNotification*)notification;
@end
void UnityRegisterLifeCycleListener(id<LifeCycleListener> obj);
void UnityUnregisterLifeCycleListener(id<LifeCycleListener> obj);
#ifdef __cplusplus
extern "C" {
#endif
extern __attribute__((visibility("default"))) NSString* const kUnityDidUnload;
extern __attribute__((visibility("default"))) NSString* const kUnityDidQuit;
#ifdef __cplusplus
} // extern "C"
#endif
#include "LifeCycleListener.h"
#define DEFINE_NOTIFICATION(name) extern "C" __attribute__((visibility ("default"))) NSString* const name = @#name;
DEFINE_NOTIFICATION(kUnityDidUnload);
DEFINE_NOTIFICATION(kUnityDidQuit);
void UnityRegisterLifeCycleListener(id<LifeCycleListener> obj)
{
#define REGISTER_SELECTOR(sel, notif_name) \
if([obj respondsToSelector:sel]) \
[[NSNotificationCenter defaultCenter] addObserver:obj \
selector:sel \
name:notif_name \
object:nil \
]; \
REGISTER_SELECTOR(@selector(didFinishLaunching:), UIApplicationDidFinishLaunchingNotification);
REGISTER_SELECTOR(@selector(didBecomeActive:), UIApplicationDidBecomeActiveNotification);
REGISTER_SELECTOR(@selector(willResignActive:), UIApplicationWillResignActiveNotification);
REGISTER_SELECTOR(@selector(didEnterBackground:), UIApplicationDidEnterBackgroundNotification);
REGISTER_SELECTOR(@selector(willEnterForeground:), UIApplicationWillEnterForegroundNotification);
REGISTER_SELECTOR(@selector(willTerminate:), UIApplicationWillTerminateNotification);
REGISTER_SELECTOR(@selector(unityDidUnload:), kUnityDidUnload);
REGISTER_SELECTOR(@selector(unityDidQuit:), kUnityDidQuit);
#undef REGISTER_SELECTOR
}
void UnityUnregisterLifeCycleListener(id<LifeCycleListener> obj)
{
[[NSNotificationCenter defaultCenter] removeObserver: obj name: UIApplicationDidFinishLaunchingNotification object: nil];
[[NSNotificationCenter defaultCenter] removeObserver: obj name: UIApplicationDidBecomeActiveNotification object: nil];
[[NSNotificationCenter defaultCenter] removeObserver: obj name: UIApplicationWillResignActiveNotification object: nil];
[[NSNotificationCenter defaultCenter] removeObserver: obj name: UIApplicationDidEnterBackgroundNotification object: nil];
[[NSNotificationCenter defaultCenter] removeObserver: obj name: UIApplicationWillEnterForegroundNotification object: nil];
[[NSNotificationCenter defaultCenter] removeObserver: obj name: UIApplicationWillTerminateNotification object: nil];
[[NSNotificationCenter defaultCenter] removeObserver: obj name: kUnityDidUnload object: nil];
[[NSNotificationCenter defaultCenter] removeObserver: obj name: kUnityDidQuit object: nil];
}
#pragma once
#include "LifeCycleListener.h"
struct UnityDisplaySurfaceBase; // Unity/UnityRendering.h
struct RenderingSurfaceParams; // Unity/DisplayManager.h
// due to delicate nature of render loop we have just one delegate in app
// if you need to use several rendering delegates you need to do one of:
// 1. create custom delegate that will have code to combine effects by itself
// 2. use helper that simply holds array of delegates (which will work only in easiest cases)
@protocol RenderPluginDelegate<LifeCycleListener, NSObject>
@required
// this will be called right after gles intialization.
// surface pointer will never be changed, so you should keep it.
// the only valid fields in there as of now are layer and context
- (void)mainDisplayInited:(struct UnityDisplaySurfaceBase*)surface;
@optional
// this will be called before recreating main display surface (from [UnityView recreateRenderingSurface])
// you can tweak params here.
// use it for enabling CVTextureCache support and the likes
- (void)onBeforeMainDisplaySurfaceRecreate:(struct RenderingSurfaceParams*)params;
// this will be called right after recreating main display surface (from [UnityView recreateRenderingSurface])
// as [UnityView recreateRenderingSurface] is the only place where unity itself will trigger surface recreate
// you can use this method to update your rendering depending on changes
- (void)onAfterMainDisplaySurfaceRecreate;
// this will be called after frame render and msaa resolve but before blitting to system FB
// you can expect that frame contents are ready (though still in target resolution)
// use it for anylizing/postprocessing rendered frame, taking screenshot and the like
// you should use targetFB if it is not 0
// otherwise use systemFB (covers case of intermediate fb not needed: no msaa, native res, no CVTextureCache involved)
- (void)onFrameResolved;
@end
// simple helper for common plugin stuff
// you can implement protocol directly, but subclassing this will provide some common implementation
@interface RenderPluginDelegate : NSObject<RenderPluginDelegate>
{
struct UnityDisplaySurfaceBase* mainDisplaySurface;
}
- (void)mainDisplayInited:(struct UnityDisplaySurfaceBase*)surface;
@end
// simple helper to have an array of render delegates.
// be warned that it works in simplest cases only, when there is no interop between delegates
@interface RenderPluginArrayDelegate : RenderPluginDelegate
{
NSArray* delegateArray;
}
@property(nonatomic, retain) NSArray* delegateArray;
- (void)mainDisplayInited:(struct UnityDisplaySurfaceBase*)surface;
- (void)onBeforeMainDisplaySurfaceRecreate:(struct RenderingSurfaceParams*)params;
- (void)onAfterMainDisplaySurfaceRecreate;
- (void)onFrameResolved;
- (void)didBecomeActive:(NSNotification*)notification;
- (void)willResignActive:(NSNotification*)notification;
- (void)didEnterBackground:(NSNotification*)notification;
- (void)willEnterForeground:(NSNotification*)notification;
- (void)willTerminate:(NSNotification*)notification;
@end
#include "RenderPluginDelegate.h"
@implementation RenderPluginDelegate
- (void)mainDisplayInited:(struct UnityDisplaySurfaceBase*)surface
{
mainDisplaySurface = surface;
// TODO: move lifecycle to init?
UnityRegisterLifeCycleListener(self);
}
@end
#define CALL_METHOD_ON_ARRAY(method) \
do{ \
for(id<RenderPluginDelegate> del in delegateArray) \
{ \
if([del respondsToSelector:@selector(method)]) \
[del method]; \
} \
} while(0)
#define CALL_METHOD_ON_ARRAY_ARG(method, arg) \
do{ \
for(id<RenderPluginDelegate> del in delegateArray) \
{ \
if([del respondsToSelector:@selector(method:)]) \
[del method:arg]; \
} \
} while(0)
@implementation RenderPluginArrayDelegate
@synthesize delegateArray;
- (void)mainDisplayInited:(struct UnityDisplaySurfaceBase*)surface
{
[super mainDisplayInited: surface];
CALL_METHOD_ON_ARRAY_ARG(mainDisplayInited, surface);
}
- (void)onBeforeMainDisplaySurfaceRecreate:(struct RenderingSurfaceParams*)params
{
CALL_METHOD_ON_ARRAY_ARG(onBeforeMainDisplaySurfaceRecreate, params);
}
- (void)onAfterMainDisplaySurfaceRecreate;
{
CALL_METHOD_ON_ARRAY(onAfterMainDisplaySurfaceRecreate);
}
- (void)onFrameResolved;
{
CALL_METHOD_ON_ARRAY(onFrameResolved);
}
- (void)didBecomeActive:(NSNotification*)notification
{
CALL_METHOD_ON_ARRAY_ARG(didBecomeActive, notification);
}
- (void)willResignActive:(NSNotification*)notification
{
CALL_METHOD_ON_ARRAY_ARG(willResignActive, notification);
}
- (void)didEnterBackground:(NSNotification*)notification
{
CALL_METHOD_ON_ARRAY_ARG(didEnterBackground, notification);
}
- (void)willEnterForeground:(NSNotification*)notification
{
CALL_METHOD_ON_ARRAY_ARG(willEnterForeground, notification);
}
- (void)willTerminate:(NSNotification*)notification
{
CALL_METHOD_ON_ARRAY_ARG(willTerminate, notification);
}
@end
#undef CALL_METHOD_ON_ARRAY
#undef CALL_METHOD_ON_ARRAY_ARG
#pragma once
#import <Foundation/NSNotification.h>
// view changes on the main view controller
@protocol UnityViewControllerListener<NSObject>
@optional
- (void)viewWillLayoutSubviews:(NSNotification*)notification;
- (void)viewDidLayoutSubviews:(NSNotification*)notification;
- (void)viewWillDisappear:(NSNotification*)notification;
- (void)viewDidDisappear:(NSNotification*)notification;
- (void)viewWillAppear:(NSNotification*)notification;
- (void)viewDidAppear:(NSNotification*)notification;
- (void)interfaceWillChangeOrientation:(NSNotification*)notification;
- (void)interfaceDidChangeOrientation:(NSNotification*)notification;
@end
@protocol UnityViewControllerNotifications<NSObject>
@optional
- (void)onViewWillLayoutSubviews;
- (void)onViewDidLayoutSubviews;
- (void)onViewDidDisappear:(BOOL)animated;
- (void)onViewWillDisappear:(BOOL)animated;
- (void)onViewDidAppear:(BOOL)animated;
- (void)onViewWillAppear:(BOOL)animated;
@end
// this default delegate will send notifications for UnityViewControllerListener
@interface UnityViewControllerNotificationsDefaultSender : NSObject<UnityViewControllerNotifications>
- (void)onViewWillLayoutSubviews;
- (void)onViewDidLayoutSubviews;
- (void)onViewDidDisappear:(BOOL)animated;
- (void)onViewWillDisappear:(BOOL)animated;
- (void)onViewDidAppear:(BOOL)animated;
- (void)onViewWillAppear:(BOOL)animated;
@end
void UnityRegisterViewControllerListener(id<UnityViewControllerListener> obj);
void UnityUnregisterViewControllerListener(id<UnityViewControllerListener> obj);
extern "C" __attribute__((visibility("default"))) NSString* const kUnityViewWillLayoutSubviews;
extern "C" __attribute__((visibility("default"))) NSString* const kUnityViewDidLayoutSubviews;
extern "C" __attribute__((visibility("default"))) NSString* const kUnityViewWillDisappear;
extern "C" __attribute__((visibility("default"))) NSString* const kUnityViewDidDisappear;
extern "C" __attribute__((visibility("default"))) NSString* const kUnityViewWillAppear;
extern "C" __attribute__((visibility("default"))) NSString* const kUnityViewDidAppear;
extern "C" __attribute__((visibility("default"))) NSString* const kUnityInterfaceWillChangeOrientation;
extern "C" __attribute__((visibility("default"))) NSString* const kUnityInterfaceDidChangeOrientation;
#include "UnityViewControllerListener.h"
#include <UIKit/UIApplication.h>
#define DEFINE_NOTIFICATION(name) extern "C" __attribute__((visibility ("default"))) NSString* const name = @#name;
DEFINE_NOTIFICATION(kUnityViewWillLayoutSubviews);
DEFINE_NOTIFICATION(kUnityViewDidLayoutSubviews);
DEFINE_NOTIFICATION(kUnityViewWillDisappear);
DEFINE_NOTIFICATION(kUnityViewDidDisappear);
DEFINE_NOTIFICATION(kUnityViewWillAppear);
DEFINE_NOTIFICATION(kUnityViewDidAppear);
DEFINE_NOTIFICATION(kUnityInterfaceWillChangeOrientation);
DEFINE_NOTIFICATION(kUnityInterfaceDidChangeOrientation);
#undef DEFINE_NOTIFICATION
void UnityRegisterViewControllerListener(id<UnityViewControllerListener> obj)
{
#define REGISTER_SELECTOR(sel, notif_name) \
if([obj respondsToSelector:sel]) \
[[NSNotificationCenter defaultCenter] addObserver:obj selector:sel name:notif_name object:nil]; \
REGISTER_SELECTOR(@selector(viewWillLayoutSubviews:), kUnityViewWillLayoutSubviews);
REGISTER_SELECTOR(@selector(viewDidLayoutSubviews:), kUnityViewDidLayoutSubviews);
REGISTER_SELECTOR(@selector(viewWillDisappear:), kUnityViewWillDisappear);
REGISTER_SELECTOR(@selector(viewDidDisappear:), kUnityViewDidDisappear);
REGISTER_SELECTOR(@selector(viewWillAppear:), kUnityViewWillAppear);
REGISTER_SELECTOR(@selector(viewDidAppear:), kUnityViewDidAppear);
REGISTER_SELECTOR(@selector(interfaceWillChangeOrientation:), kUnityInterfaceWillChangeOrientation);
REGISTER_SELECTOR(@selector(interfaceDidChangeOrientation:), kUnityInterfaceDidChangeOrientation);
#undef REGISTER_SELECTOR
}
void UnityUnregisterViewControllerListener(id<UnityViewControllerListener> obj)
{
[[NSNotificationCenter defaultCenter] removeObserver: obj name: kUnityViewWillLayoutSubviews object: nil];
[[NSNotificationCenter defaultCenter] removeObserver: obj name: kUnityViewDidLayoutSubviews object: nil];
[[NSNotificationCenter defaultCenter] removeObserver: obj name: kUnityViewWillDisappear object: nil];
[[NSNotificationCenter defaultCenter] removeObserver: obj name: kUnityViewDidDisappear object: nil];
[[NSNotificationCenter defaultCenter] removeObserver: obj name: kUnityViewWillAppear object: nil];
[[NSNotificationCenter defaultCenter] removeObserver: obj name: kUnityViewDidAppear object: nil];
[[NSNotificationCenter defaultCenter] removeObserver: obj name: kUnityInterfaceWillChangeOrientation object: nil];
[[NSNotificationCenter defaultCenter] removeObserver: obj name: kUnityInterfaceDidChangeOrientation object: nil];
}
extern void AppController_SendUnityViewControllerNotification(NSString* name);
@implementation UnityViewControllerNotificationsDefaultSender
- (void)onViewWillLayoutSubviews
{
AppController_SendUnityViewControllerNotification(kUnityViewWillLayoutSubviews);
}
- (void)onViewDidLayoutSubviews
{
AppController_SendUnityViewControllerNotification(kUnityViewDidLayoutSubviews);
}
- (void)onViewDidDisappear:(BOOL)animated
{
AppController_SendUnityViewControllerNotification(kUnityViewDidDisappear);
}
- (void)onViewWillDisappear:(BOOL)animated
{
AppController_SendUnityViewControllerNotification(kUnityViewWillDisappear);
}
- (void)onViewDidAppear:(BOOL)animated
{
AppController_SendUnityViewControllerNotification(kUnityViewDidAppear);
}
- (void)onViewWillAppear:(BOOL)animated
{
AppController_SendUnityViewControllerNotification(kUnityViewWillAppear);
}
@end
//
// Prefix header
//
#include "Preprocessor.h"
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#endif
#include "UnityTrampolineConfigure.h"
#include "UnityInterface.h"
#ifndef __OBJC__
#if USE_IL2CPP_PCH
#include "il2cpp_precompiled_header.h"
#endif
#endif
#ifndef TARGET_IPHONE_SIMULATOR
#define TARGET_IPHONE_SIMULATOR 0
#endif
#define printf_console printf
#pragma once
#include <Availability.h>
#include <TargetConditionals.h>
//------------------------------------------------------------------------------
//
// ensuring proper compiler/xcode/whatever selection
//
#ifndef __clang__
#error Please use clang compiler.
#endif
// NOT the best way but apple do not care about adding extensions properly
#if __clang_major__ < 9
#error Please use Xcode 9.0 or newer
#endif
#if !defined(__IPHONE_11_0) || __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_11_0
#error Please use iOS SDK 11.0 or newer
#endif
#if defined(TARGET_OS_TV) && TARGET_OS_TV && !defined(__TVOS_11_0)
#error Please use tvOS SDK 11.0 or newer
#endif
#if TARGET_OS_IOS && (!defined(__IPHONE_10_0) || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_10_0)
#error Please target iOS 10.0 or newer
#endif
#if TARGET_OS_TV && (!defined(__TVOS_10_0) || __TV_OS_VERSION_MIN_REQUIRED < __TVOS_10_0)
#error Please target tvOS 10.0 or newer
#endif
//------------------------------------------------------------------------------
//
// defines for target platform
//
#define UNITY_TRAMPOLINE_IN_USE 1
#if defined(TARGET_OS_TV) && TARGET_OS_TV
#define PLATFORM_TVOS 1
#define PLATFORM_IOS 0
#else
#define PLATFORM_TVOS 0
#define PLATFORM_IOS 1
#endif
#define PLATFORM_OSX 0
//------------------------------------------------------------------------------
//
// defines for sdk/target version
//
#if !TARGET_IPHONE_SIMULATOR && !TARGET_TVOS_SIMULATOR
#define UNITY_CAN_USE_METAL 1
#elif TARGET_IPHONE_SIMULATOR && defined(__IPHONE_13_0)
#define UNITY_CAN_USE_METAL 1
#elif TARGET_TVOS_SIMULATOR && defined(__TVOS_13_0)
#define UNITY_CAN_USE_METAL 1
#else
#define UNITY_CAN_USE_METAL 0
#endif
// It's hard to figure out which SDK we are using as the availability macros defined in the SDK
// have various quirks.
//
// It's not possible to use *_VERSION_MAX_ALLOWED macros because they not always corresponded to
// the SDK version. In particular, __TV_OS_VERSION_MAX_ALLOWED was out of sync in all Xcode dot
// releases except the first so far.
//
// The highest __IPHONE_X_Y or __TVOS_X_Y macro that is defined in Availability.h correctly
// corresponds to the version of the SDK (at least in each Xcode version since 6.0 up to 9.0).
// However, some other headers (e.g. System/Library/Frameworks/QuartzCore.framework/Headers/CABase.h
// in SDKs up to 9.3) may define the macros itself and this does not correspond to the what's in
// Availability.h. Thus we make sure to include "Preprocessor.h" before the CABase.h header.
#if defined(CABASE_H)
#error "Please include Preprocessor.h before other includes"
#endif
#if defined(__IPHONE_10_0)
#define UNITY_HAS_IOSSDK_10_0 1
#else
#define UNITY_HAS_IOSSDK_10_0 0
#endif
#if defined(__IPHONE_10_2)
#define UNITY_HAS_IOSSDK_10_2 1
#else
#define UNITY_HAS_IOSSDK_10_2 0
#endif
#if defined(__IPHONE_10_3)
#define UNITY_HAS_IOSSDK_10_3 1
#else
#define UNITY_HAS_IOSSDK_10_3 0
#endif
#if defined(__IPHONE_11_0)
#define UNITY_HAS_IOSSDK_11_0 1
#else
#define UNITY_HAS_IOSSDK_11_0 0
#endif
#if defined(__IPHONE_11_1)
#define UNITY_HAS_IOSSDK_11_1 1
#else
#define UNITY_HAS_IOSSDK_11_1 0
#endif
#if defined(__IPHONE_12_0)
#define UNITY_HAS_IOSSDK_12_0 1
#else
#define UNITY_HAS_IOSSDK_12_0 0
#endif
#if defined(__IPHONE_13_0)
#define UNITY_HAS_IOSSDK_13_0 1
#else
#define UNITY_HAS_IOSSDK_13_0 0
#endif
#if defined(__IPHONE_14_0)
#define UNITY_HAS_IOSSDK_14_0 1
#else
#define UNITY_HAS_IOSSDK_14_0 0
#endif
#if defined(__IPHONE_15_0)
#define UNITY_HAS_IOSSDK_15_0 1
#else
#define UNITY_HAS_IOSSDK_15_0 0
#endif
#if defined(__TVOS_10_0)
#define UNITY_HAS_TVOSSDK_10_0 1
#else
#define UNITY_HAS_TVOSSDK_10_0 0
#endif
#if defined(__TVOS_10_2)
#define UNITY_HAS_TVOSSDK_10_2 1
#else
#define UNITY_HAS_TVOSSDK_10_2 0
#endif
#if defined(__TVOS_11_0)
#define UNITY_HAS_TVOSSDK_11_0 1
#else
#define UNITY_HAS_TVOSSDK_11_0 0
#endif
#if defined(__TVOS_12_0)
#define UNITY_HAS_TVOSSDK_12_0 1
#else
#define UNITY_HAS_TVOSSDK_12_0 0
#endif
#if defined(__TVOS_13_0)
#define UNITY_HAS_TVOSSDK_13_0 1
#else
#define UNITY_HAS_TVOSSDK_13_0 0
#endif
#if defined(__TVOS_14_0)
#define UNITY_HAS_TVOSSDK_14_0 1
#else
#define UNITY_HAS_TVOSSDK_14_0 0
#endif
#if defined(__TVOS_15_0)
#define UNITY_HAS_TVOSSDK_15_0 1
#else
#define UNITY_HAS_TVOSSDK_15_0 0
#endif
// The following UNITY_USES_* flags disable functionality in the trampoline project
// whenever the user does not use it from his scripts. We detect the API usage and
// adjust the value of these flags whenever the project is built (including when the
// project is appended)
#define UNITY_USES_REMOTE_NOTIFICATIONS 1
#define UNITY_USES_WEBCAM 0
#define UNITY_USES_MICROPHONE 0
#define UNITY_USES_REPLAY_KIT 0
#define UNITY_USES_IAD 1
#define UNITY_SNAPSHOT_VIEW_ON_APPLICATION_PAUSE 0
#define UNITY_DEVELOPER_BUILD 0
#define UNITY_USES_DYNAMIC_PLAYER_LIB 0
#define UNITY_USES_LOCATION 0
#define USE_IL2CPP_PCH 0
#define UNITY_SUPPORT_ROTATION PLATFORM_IOS
#if PLATFORM_TVOS
#define UNITY_TVOS_ORIENTATION landscapeLeft
#endif
#if PLATFORM_IOS // available in ios9 sdk which is min requirement
#define UNITY_REPLAY_KIT_AVAILABLE UNITY_USES_REPLAY_KIT
#elif PLATFORM_TVOS // available in tvos10 sdk which is min requirement
#define UNITY_REPLAY_KIT_AVAILABLE UNITY_USES_REPLAY_KIT && defined(__TVOS_10_0)
#else
#define UNITY_REPLAY_KIT_AVAILABLE 0
#endif
// On tvOS simulator we implement a fake remote as tvOS simulator does not support controllers (yet)
#define UNITY_TVOS_SIMULATOR_FAKE_REMOTE (PLATFORM_TVOS && TARGET_TVOS_SIMULATOR)
#pragma once
struct Quaternion4f
{
float x, y, z, w;
};
static Quaternion4f gQuatRot[4] =
{ // { x*sin(theta/2), y*sin(theta/2), z*sin(theta/2), cos(theta/2) }
// => { 0, 0, sin(theta/2), cos(theta/2) } (since <vec> = { 0, 0, +/-1})
{ 0.f, 0.f, 0.f /*sin(0)*/, 1.f /*cos(0)*/}, // ROTATION_0, theta = 0 rad
{ 0.f, 0.f, (float)sqrt(2) * 0.5f /*sin(pi/4)*/, -(float)sqrt(2) * 0.5f /*cos(pi/4)*/}, // ROTATION_90, theta = pi/4 rad
{ 0.f, 0.f, 1.f /*sin(pi/2)*/, 0.f /*cos(pi/2)*/}, // ROTATION_180, theta = pi rad
{ 0.f, 0.f, -(float)sqrt(2) * 0.5f /*sin(3pi/4)*/, -(float)sqrt(2) * 0.5f /*cos(3pi/4)*/} // ROTATION_270, theta = 3pi/2 rad
};
inline void QuatMultiply(Quaternion4f& result, const Quaternion4f& lhs, const Quaternion4f& rhs)
{
result.x = lhs.w * rhs.x + lhs.x * rhs.w + lhs.y * rhs.z - lhs.z * rhs.y;
result.y = lhs.w * rhs.y + lhs.y * rhs.w + lhs.z * rhs.x - lhs.x * rhs.z;
result.z = lhs.w * rhs.z + lhs.z * rhs.w + lhs.x * rhs.y - lhs.y * rhs.x;
result.w = lhs.w * rhs.w - lhs.x * rhs.x - lhs.y * rhs.y - lhs.z * rhs.z;
}
inline Quaternion4f QuatMultiply(const Quaternion4f& lhs, const Quaternion4f& rhs)
{
Quaternion4f output;
QuatMultiply(output, lhs, rhs);
return output;
}
inline Quaternion4f QuatMake(float x, float y, float z, float w)
{
Quaternion4f q = {x, y, z, w};
return q;
}
inline Quaternion4f QuatIdentity()
{
return gQuatRot[0];
}
inline Quaternion4f QuatScale(const Quaternion4f& q, float s)
{
return QuatMake(s * q.x, s * q.y, s * q.z, s * q.w);
}
inline float QuatNormSquared(const Quaternion4f& q)
{
return q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w;
}
inline Quaternion4f QuatConjugate(const Quaternion4f& q)
{
return QuatMake(-q.x, -q.y, -q.z, q.w);
}
inline Quaternion4f QuatInverse(const Quaternion4f& q)
{
return QuatScale(QuatConjugate(q), 1.0f / QuatNormSquared(q));
}
inline Vector3f QuatToEuler(const Quaternion4f& q)
{
return VecMake(
atan2f(2.0f * (q.w * q.y + q.x * q.z),
1.0f - 2.0f * (q.y * q.y + q.x * q.x)),
asinf(2.0f * (q.w * q.x - q.z * q.y)),
atan2f(2.0f * (q.w * q.z + q.y * q.x),
1.0f - 2.0f * (q.x * q.x + q.z * q.z)));
}
inline float QuatNorm(const Quaternion4f& q)
{
return sqrtf(QuatNormSquared(q));
}
inline Quaternion4f QuatNormalize(const Quaternion4f& q)
{
return QuatScale(q, 1.0f / QuatNorm(q));
}
inline Quaternion4f QuatDifference(const Quaternion4f& a, const Quaternion4f& b)
{
return QuatMultiply(QuatInverse(b), a);
}
inline Quaternion4f QuatRotationFromTo(const Vector3f& src, const Vector3f& dest)
{
// Based on Stan Melax's article in Game Programming Gems
float mag0 = VecMagnitude(src);
if (mag0 < FLT_EPSILON)
return QuatIdentity();
float mag1 = VecMagnitude(dest);
if (mag1 < FLT_EPSILON)
return QuatIdentity();
Vector3f v0 = VecScale(1.0f / mag0, src);
Vector3f v1 = VecScale(1.0f / mag1, dest);
float d = VecDotProduct(v0, v1);
// If dot == 1, vectors are the same
if (d >= (1.0f - 1e-6f))
return QuatIdentity();
if (d < (1e-6f - 1.0f))
return gQuatRot[2];
float s = sqrtf((1.0f + d) * 2.0f);
float i = 1.0f / s;
Vector3f c = VecCrossProduct(v0, v1);
return QuatNormalize(QuatMake(
c.x * i, c.y * i, c.z * i, s * 0.5f));
}
// DO NOT PUT #pragma once or include guard check here
// This header is designed to be able to be included multiple times
// This header is used to redefine platforms after they were temporary undefined by UndefinePlatforms.h
// Please make sure to always use this paired with the UndefinePlatforms.h header.
//
// ex.
//
// #include "UndefinePlatforms.h"
// #include "Some3rdParty.h"
// #include "RedefinePlatforms.h"
#ifndef DETAIL__PLATFORMS_HAD_BEEN_UNDEFINED_BY_UNDEFINEPLATFORMS_H
#error "DefinePlatforms.h can only be used after UndefinePlatforms.h got included before."
#endif
#undef DETAIL__PLATFORMS_HAD_BEEN_UNDEFINED_BY_UNDEFINEPLATFORMS_H
// define all other platforms to 0
#undef PLATFORM_WIN
#if defined(DETAIL__TEMP_PLATFORM_WIN_WAS_1)
#undef DETAIL__TEMP_PLATFORM_WIN_WAS_1
#define PLATFORM_WIN 1
#else
#define PLATFORM_WIN 0
#endif
#undef PLATFORM_OSX
#if defined(DETAIL__TEMP_PLATFORM_OSX_WAS_1)
#undef DETAIL__TEMP_PLATFORM_OSX_WAS_1
#define PLATFORM_OSX 1
#else
#define PLATFORM_OSX 0
#endif
#undef PLATFORM_LINUX
#if defined(DETAIL__TEMP_PLATFORM_LINUX_WAS_1)
#undef DETAIL__TEMP_PLATFORM_LINUX_WAS_1
#define PLATFORM_LINUX 1
#else
#define PLATFORM_LINUX 0
#endif
#undef PLATFORM_WINRT
#if defined(DETAIL__TEMP_PLATFORM_WINRT_WAS_1)
#undef DETAIL__TEMP_PLATFORM_WINRT_WAS_1
#define PLATFORM_WINRT 1
#else
#define PLATFORM_WINRT 0
#endif
#undef PLATFORM_FAMILY_WINDOWSGAMES
#if defined(DETAIL__TEMP_PLATFORM_FAMILY_WINDOWSGAMES_WAS_1)
#undef DETAIL__TEMP_PLATFORM_FAMILY_WINDOWSGAMES_WAS_1
#define PLATFORM_FAMILY_WINDOWSGAMES 1
#else
#define PLATFORM_FAMILY_WINDOWSGAMES 0
#endif
#undef PLATFORM_WEBGL
#if defined(DETAIL__TEMP_PLATFORM_WEBGL_WAS_1)
#undef DETAIL__TEMP_PLATFORM_WEBGL_WAS_1
#define PLATFORM_WEBGL 1
#else
#define PLATFORM_WEBGL 0
#endif
#undef PLATFORM_ANDROID
#if defined(DETAIL__TEMP_PLATFORM_ANDROID_WAS_1)
#undef DETAIL__TEMP_PLATFORM_ANDROID_WAS_1
#define PLATFORM_ANDROID 1
#else
#define PLATFORM_ANDROID 0
#endif
#undef PLATFORM_PS4
#if defined(DETAIL__TEMP_PLATFORM_PS4_WAS_1)
#undef DETAIL__TEMP_PLATFORM_PS4_WAS_1
#define PLATFORM_PS4 1
#else
#define PLATFORM_PS4 0
#endif
#undef PLATFORM_IPHONE
#if defined(DETAIL__TEMP_PLATFORM_IPHONE_WAS_1)
#undef DETAIL__TEMP_PLATFORM_IPHONE_WAS_1
#define PLATFORM_IPHONE 1
#else
#define PLATFORM_IPHONE 0
#endif
#undef PLATFORM_IOS
#if defined(DETAIL__TEMP_PLATFORM_IOS_WAS_1)
#undef DETAIL__TEMP_PLATFORM_IOS_WAS_1
#define PLATFORM_IOS 1
#else
#define PLATFORM_IOS 0
#endif
#undef PLATFORM_TVOS
#if defined(DETAIL__TEMP_PLATFORM_TVOS_WAS_1)
#undef DETAIL__TEMP_PLATFORM_TVOS_WAS_1
#define PLATFORM_TVOS 1
#else
#define PLATFORM_TVOS 0
#endif
#undef PLATFORM_XBOXONE
#if defined(DETAIL__TEMP_PLATFORM_XBOXONE_WAS_1)
#undef DETAIL__TEMP_PLATFORM_XBOXONE_WAS_1
#define PLATFORM_XBOXONE 1
#else
#define PLATFORM_XBOXONE 0
#endif
#undef PLATFORM_SWITCH
#if defined(DETAIL__TEMP_PLATFORM_SWITCH_WAS_1)
#undef DETAIL__TEMP_PLATFORM_SWITCH_WAS_1
#define PLATFORM_SWITCH 1
#else
#define PLATFORM_SWITCH 0
#endif
#undef PLATFORM_LUMIN
#if defined(DETAIL__TEMP_PLATFORM_LUMIN_WAS_1)
#undef DETAIL__TEMP_PLATFORM_LUMIN_WAS_1
#define PLATFORM_LUMIN 1
#else
#define PLATFORM_LUMIN 0
#endif
#undef PLATFORM_GGP
#if defined(DETAIL__TEMP_PLATFORM_GGP_WAS_1)
#undef DETAIL__TEMP_PLATFORM_GGP_WAS_1
#define PLATFORM_GGP 1
#else
#define PLATFORM_GGP 0
#endif
#undef PLATFORM_NETBSD
#if defined(DETAIL__TEMP_PLATFORM_NETBSD_WAS_1)
#undef DETAIL__TEMP_PLATFORM_NETBSD_WAS_1
#define PLATFORM_NETBSD 1
#else
#define PLATFORM_NETBSD 0
#endif
#pragma once
void ShowActivityIndicator(UIView* parent, int style);
void ShowActivityIndicator(UIView* parent);
void HideActivityIndicator();
#include "ActivityIndicator.h"
#include "OrientationSupport.h"
@interface ActivityIndicator : UIActivityIndicatorView
{
UIView* _parent;
}
@end
static ActivityIndicator* _activityIndicator = nil;
@implementation ActivityIndicator
- (void)show:(UIView*)parent
{
_parent = parent;
[parent addSubview: self];
[self startAnimating];
}
- (void)layoutSubviews
{
self.center = CGPointMake([_parent bounds].size.width / 2, [_parent bounds].size.height / 2);
}
@end
void ShowActivityIndicator(UIView* parent, int style)
{
if (_activityIndicator != nil)
return;
if (style >= 0)
{
_activityIndicator = [[ActivityIndicator alloc] initWithActivityIndicatorStyle: (UIActivityIndicatorViewStyle)style];
_activityIndicator.contentScaleFactor = [UIScreen mainScreen].scale;
}
if (_activityIndicator != nil)
[_activityIndicator show: parent];
}
void ShowActivityIndicator(UIView* parent)
{
ShowActivityIndicator(parent, UnityGetShowActivityIndicatorOnLoading());
}
void HideActivityIndicator()
{
if (_activityIndicator)
{
[_activityIndicator stopAnimating];
[_activityIndicator removeFromSuperview];
_activityIndicator = nil;
}
}
extern "C" void UnityStartActivityIndicator()
{
// AppleTV does not support activity indicators
ShowActivityIndicator(UnityGetGLView());
}
extern "C" void UnityStopActivityIndicator()
{
HideActivityIndicator();
}
#pragma once
typedef struct
{
const char* text;
const char* placeholder;
UIKeyboardType keyboardType;
UITextAutocorrectionType autocorrectionType;
UITextSpellCheckingType spellcheckingType;
UIKeyboardAppearance appearance;
BOOL multiline;
BOOL secure;
int characterLimit;
}
KeyboardShowParam;
@interface KeyboardDelegate : NSObject<UITextFieldDelegate, UITextViewDelegate>
{
}
- (BOOL)textFieldShouldReturn:(UITextField*)textField;
- (void)textInputDone:(id)sender;
- (void)textInputCancel:(id)sender;
- (void)textInputLostFocus;
- (void)textViewDidChange:(UITextView *)textView;
- (void)keyboardWillShow:(NSNotification*)notification;
- (void)keyboardDidShow:(NSNotification*)notification;
- (void)keyboardWillHide:(NSNotification*)notification;
- (void)becomeFirstResponder;
// on older devices initial keyboard creation might be slow, so it is good to init in on initial loading.
// on the other hand, if you dont use keyboard (or use it rarely), you can avoid having all related stuff in memory:
// keyboard will be created on demand anyway (in Instance method)
+ (void)Initialize;
+ (KeyboardDelegate*)Instance;
+ (void)Destroy;
- (id)init;
- (void)setKeyboardParams:(KeyboardShowParam)param;
- (void)show;
- (void)hide;
- (void)positionInput:(CGRect)keyboardRect x:(float)x y:(float)y;
- (void)shouldHideInput:(BOOL)hide;
+ (void)StartReorientation;
+ (void)FinishReorientation;
- (CGRect)queryArea;
- (NSString*)getText;
- (void)setText:(NSString*)newText;
- (BOOL)hasExternalKeyboard;
@property (readonly, nonatomic, getter = queryArea) CGRect area;
@property (readonly, nonatomic) BOOL active;
@property (readonly, nonatomic) KeyboardStatus status;
@property (retain, nonatomic, getter = getText, setter = setText:) NSString* text;
@property (assign, nonatomic) int characterLimit;
@property (readonly, nonatomic) BOOL canGetSelection;
@property (nonatomic, getter = querySelection, setter = assignSelection:) NSRange selection;
@end
#pragma once
#include <CoreGraphics/CGAffineTransform.h>
#if !PLATFORM_TVOS
ScreenOrientation ConvertToUnityScreenOrientation(UIInterfaceOrientation hwOrient);
UIInterfaceOrientation ConvertToIosScreenOrientation(ScreenOrientation orient);
#endif
#if !PLATFORM_TVOS
UIInterfaceOrientation UIViewControllerInterfaceOrientation(UIViewController* controller);
#endif
ScreenOrientation UIViewControllerOrientation(UIViewController* controller);
CGAffineTransform TransformForOrientation(ScreenOrientation curOrient);
CGAffineTransform TransformBetweenOrientations(ScreenOrientation fromOrient, ScreenOrientation toOrient);
ScreenOrientation OrientationAfterTransform(ScreenOrientation curOrient, CGAffineTransform transform);
void OrientView(UIViewController* host, UIView* view, ScreenOrientation to);
#include "OrientationSupport.h"
#include <math.h>
CGAffineTransform TransformForOrientation(ScreenOrientation orient)
{
switch (orient)
{
case portrait: return CGAffineTransformIdentity;
case portraitUpsideDown: return CGAffineTransformMakeRotation(M_PI);
case landscapeLeft: return CGAffineTransformMakeRotation(M_PI_2);
case landscapeRight: return CGAffineTransformMakeRotation(-M_PI_2);
default: return CGAffineTransformIdentity;
}
return CGAffineTransformIdentity;
}
CGAffineTransform TransformBetweenOrientations(ScreenOrientation fromOrient, ScreenOrientation toOrient)
{
CGAffineTransform fromTransform = TransformForOrientation(fromOrient);
CGAffineTransform toTransform = TransformForOrientation(toOrient);
return CGAffineTransformConcat(CGAffineTransformInvert(fromTransform), toTransform);
}
#if !PLATFORM_TVOS
UIInterfaceOrientation ConvertToIosScreenOrientation(ScreenOrientation orient)
{
switch (orient)
{
case portrait: return UIInterfaceOrientationPortrait;
case portraitUpsideDown: return UIInterfaceOrientationPortraitUpsideDown;
// landscape left/right have switched values in device/screen orientation
// though unity docs are adjusted with device orientation values, so swap here
case landscapeLeft: return UIInterfaceOrientationLandscapeRight;
case landscapeRight: return UIInterfaceOrientationLandscapeLeft;
case orientationUnknown: return (UIInterfaceOrientation)UIInterfaceOrientationUnknown;
default: return UIInterfaceOrientationPortrait;
}
return UIInterfaceOrientationPortrait;
}
ScreenOrientation ConvertToUnityScreenOrientation(UIInterfaceOrientation orient)
{
switch (orient)
{
case UIInterfaceOrientationPortrait: return portrait;
case UIInterfaceOrientationPortraitUpsideDown: return portraitUpsideDown;
// landscape left/right have switched values in device/screen orientation
// though unity docs are adjusted with device orientation values, so swap here
case UIInterfaceOrientationLandscapeLeft: return landscapeRight;
case UIInterfaceOrientationLandscapeRight: return landscapeLeft;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wswitch"
case UIInterfaceOrientationUnknown: return orientationUnknown;
#pragma clang diagnostic pop
default: return portrait;
}
}
// Replacement for UIViewController.interfaceOrientation which is obsolete since iOS 8.0
UIInterfaceOrientation UIViewControllerInterfaceOrientation(UIViewController* c)
{
CGPoint fixedPoint = [c.view.window.screen.coordinateSpace convertPoint: CGPointMake(0.0, 0.0) toCoordinateSpace: c.view.window.screen.fixedCoordinateSpace];
if (fabs(fixedPoint.x) < FLT_EPSILON)
{
if (fabs(fixedPoint.y) < FLT_EPSILON)
return UIInterfaceOrientationPortrait;
else
return UIInterfaceOrientationLandscapeLeft;
}
else
{
if (fabs(fixedPoint.y) < FLT_EPSILON)
return UIInterfaceOrientationLandscapeRight;
else
return UIInterfaceOrientationPortraitUpsideDown;
}
}
#endif
ScreenOrientation UIViewControllerOrientation(UIViewController* controller)
{
#if PLATFORM_TVOS
return UNITY_TVOS_ORIENTATION;
#else
return ConvertToUnityScreenOrientation(UIViewControllerInterfaceOrientation(controller));
#endif
}
ScreenOrientation OrientationAfterTransform(ScreenOrientation curOrient, CGAffineTransform transform)
{
int rotDeg = (int)::roundf(::atan2f(transform.b, transform.a) * (180 / M_PI));
assert(rotDeg == 0 || rotDeg == 90 || rotDeg == -90 || rotDeg == 180 || rotDeg == -180);
if (rotDeg == 0)
{
return curOrient;
}
else if ((rotDeg == 180) || (rotDeg == -180))
{
if (curOrient == portrait)
return portraitUpsideDown;
else if (curOrient == portraitUpsideDown)
return portrait;
else if (curOrient == landscapeRight)
return landscapeLeft;
else if (curOrient == landscapeLeft)
return landscapeRight;
}
else if (rotDeg == 90)
{
if (curOrient == portrait)
return landscapeLeft;
else if (curOrient == portraitUpsideDown)
return landscapeRight;
else if (curOrient == landscapeRight)
return portrait;
else if (curOrient == landscapeLeft)
return portraitUpsideDown;
}
else if (rotDeg == -90)
{
if (curOrient == portrait)
return landscapeRight;
else if (curOrient == portraitUpsideDown)
return landscapeLeft;
else if (curOrient == landscapeRight)
return portraitUpsideDown;
else if (curOrient == landscapeLeft)
return portrait;
}
::printf("rotation unhandled: %d\n", rotDeg);
return curOrient;
}
void OrientView(UIViewController* host, UIView* view, ScreenOrientation to)
{
ScreenOrientation fromController = UIViewControllerOrientation(host);
CGAffineTransform transform = TransformBetweenOrientations(fromController, to);
// this is for unity-inited orientation. In that case we need to manually adjust bounds if changing portrait/landscape
// the easiest way would be to manually rotate current bounds (to acknowledge the fact that we do NOT rotate controller itself)
// NB: as we use current view bounds we need to use view transform to properly adjust them
CGRect rect = view.bounds;
CGSize ext = CGSizeApplyAffineTransform(rect.size, CGAffineTransformConcat(CGAffineTransformInvert(view.transform), transform));
view.transform = transform;
view.bounds = CGRectMake(0, 0, ::fabs(ext.width), ::fabs(ext.height));
}
#pragma once
#include "UnityViewControllerBase.h"
@interface SplashScreen : UIImageView
{
}
+ (SplashScreen*)Instance;
@end
@interface SplashScreenController : UnityViewControllerBase
{
}
+ (SplashScreenController*)Instance;
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator;
@end
void ShowSplashScreen(UIWindow* window);
void HideSplashScreen();
#include "SplashScreen.h"
#include "UnityViewControllerBase.h"
#include "OrientationSupport.h"
#include "Unity/ObjCRuntime.h"
#include "UI/UnityView.h"
#include <cstring>
#include "Unity/UnitySharedDecls.h"
#include <utility>
static SplashScreen* _splash = nil;
static SplashScreenController* _controller = nil;
@implementation SplashScreen
{
UIImageView* m_ImageView;
UIView* m_XibView;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame: frame];
return self;
}
- (void)createUI
{
NSString* launchScreen = [[NSBundle mainBundle].infoDictionary[@"UILaunchStoryboardName"] stringByDeletingPathExtension];
const bool hasXIB = [[NSBundle mainBundle] pathForResource: launchScreen ofType: @"nib"] != nil;
if (hasXIB)
{
self->m_XibView = [[[NSBundle mainBundle] loadNibNamed: launchScreen owner: nil options: nil] objectAtIndex: 0];
[self addSubview: self->m_XibView];
}
else
{
#if !PLATFORM_TVOS
NSAssert(NO, @"no storyboard/xib was provided.");
#endif
// we still support launch images on tvos, but unlike iOS there are only two options and no orientations
UIImage* launchImage = nil;
if ([UIScreen mainScreen].scale > 1.0)
launchImage = [UIImage imageNamed: @"LaunchImage@2x"];
if (!launchImage)
launchImage = [UIImage imageNamed: @"LaunchImage@"];
self->m_ImageView = [[UIImageView alloc] initWithImage: launchImage];
[self addSubview: self->m_ImageView];
}
}
- (void)updateOrientation:(ScreenOrientation)orient withSupportedOrientations:(const OrientationMask&)supportedOrientations
{
CGFloat scale = UnityScreenScaleFactor([UIScreen mainScreen]);
UnityReportResizeView(self.bounds.size.width * scale, self.bounds.size.height * scale, orient);
ReportSafeAreaChangeForView(self);
// for iOS only xib/storyboard are supported, for tvOS (launch images are supported) no orientation takes place at all
}
- (void)layoutSubviews
{
if (self->m_XibView)
self->m_XibView.frame = self.bounds;
else if (self->m_ImageView)
self->m_ImageView.frame = self.bounds;
}
+ (SplashScreen*)Instance
{
return _splash;
}
- (void)freeSubviews
{
m_ImageView = nil;
m_XibView = nil;
}
@end
@implementation SplashScreenController
{
OrientationMask _supportedOrientations;
}
- (id)init
{
self = [super init];
if (self)
{
self->_supportedOrientations = { false, false, false, false };
}
return self;
}
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
ScreenOrientation curOrient = UIViewControllerOrientation(self);
ScreenOrientation newOrient = OrientationAfterTransform(curOrient, [coordinator targetTransform]);
[_splash updateOrientation: newOrient withSupportedOrientations: self->_supportedOrientations];
[super viewWillTransitionToSize: size withTransitionCoordinator: coordinator];
}
- (void)initImpl
{
NSArray* supportedOrientation = [[[NSBundle mainBundle] infoDictionary] objectForKey: @"UISupportedInterfaceOrientations"];
// splash will be shown way before unity is inited so we need to override autorotation handling with values read from info.plist
self->_supportedOrientations.portrait = [supportedOrientation containsObject: @"UIInterfaceOrientationPortrait"];
self->_supportedOrientations.portraitUpsideDown = [supportedOrientation containsObject: @"UIInterfaceOrientationPortraitUpsideDown"];
self->_supportedOrientations.landscapeLeft = [supportedOrientation containsObject: @"UIInterfaceOrientationLandscapeRight"];
self->_supportedOrientations.landscapeRight = [supportedOrientation containsObject: @"UIInterfaceOrientationLandscapeLeft"];
// special handling of devices/ios that do not support upside down orientation
if (!UnityDeviceSupportsUpsideDown())
{
self->_supportedOrientations.portraitUpsideDown = false;
OrientationMask om = self->_supportedOrientations;
const bool anySupported = om.portrait || om.landscapeLeft || om.landscapeRight;
if (!anySupported)
{
self->_supportedOrientations.portrait = true;
printf_console("This device does not support UpsideDown orientation, so we switched to Portrait.\n");
}
}
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
if ((self = [super initWithCoder: coder]))
[self initImpl];
return self;
}
- (void)create:(UIWindow*)window
{
[self initImpl];
_splash = [[SplashScreen alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
_splash.contentScaleFactor = UnityScreenScaleFactor([UIScreen mainScreen]);
_splash.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
_splash.autoresizesSubviews = YES;
[_splash createUI];
window.rootViewController = self;
self.view = _splash;
[window addSubview: _splash];
[window bringSubviewToFront: _splash];
ScreenOrientation orient = UIViewControllerOrientation(self);
[_splash updateOrientation: orient withSupportedOrientations: self->_supportedOrientations];
OrientView([SplashScreenController Instance], _splash, orient);
}
#if PLATFORM_IOS
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
NSUInteger ret = 0;
if (self->_supportedOrientations.portrait)
ret |= (1 << UIInterfaceOrientationPortrait);
if (self->_supportedOrientations.portraitUpsideDown)
ret |= (1 << UIInterfaceOrientationPortraitUpsideDown);
if (self->_supportedOrientations.landscapeLeft)
ret |= (1 << UIInterfaceOrientationLandscapeRight);
if (self->_supportedOrientations.landscapeRight)
ret |= (1 << UIInterfaceOrientationLandscapeLeft);
return ret;
}
#endif
+ (SplashScreenController*)Instance
{
return _controller;
}
@end
void ShowSplashScreen(UIWindow* window)
{
NSString* launchScreen = [[NSBundle mainBundle].infoDictionary[@"UILaunchStoryboardName"] stringByDeletingPathExtension];
#if PLATFORM_IOS
// since launch images are no longer supported on ios we MUST have UILaunchStoryboardName filled
assert(launchScreen != nil && @"UILaunchStoryboardName key is missing from info.plist");
#endif
const bool hasStoryboard = launchScreen != nil && [[NSBundle mainBundle] pathForResource: launchScreen ofType: @"storyboardc"] != nil;
if (hasStoryboard)
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName: launchScreen bundle: [NSBundle mainBundle]];
// on ios13 we can finally tweak initial storyboard view controller: use unity base view controller
// this way we can handle orientations/status-bar/whatever-we-want-to-tweak uniformly
// as we still support xcode pre-11 we must do this weird dance of checking for both sdk and runtime version
// otherwise it fails to compile (due to unknown selector)
#if (PLATFORM_IOS && defined(__IPHONE_13_0)) || (PLATFORM_TVOS && defined(__TVOS_13_0))
if (@available(iOS 13.0, tvOS 13.0, *))
{
_controller = [storyboard instantiateInitialViewControllerWithCreator:^(NSCoder *coder) {
return [[SplashScreenController alloc] initWithCoder: coder];
}];
}
else
#endif
{
_controller = [storyboard instantiateInitialViewController];
}
window.rootViewController = _controller;
}
else
{
_controller = [[SplashScreenController alloc] init];
[_controller create: window];
}
[window makeKeyAndVisible];
}
void HideSplashScreen()
{
if (_splash)
{
[_splash removeFromSuperview];
[_splash freeSubviews];
}
_splash = nil;
_controller = nil;
}
#if PLATFORM_IOS
// This definition is here only for compiler to know about selector requestReview
@interface UnityStoreReviewController
+ + requestReview;
@end
bool UnityRequestStoreReview()
{
Class classSKStoreReviewController = NSClassFromString(@"SKStoreReviewController");
if (!classSKStoreReviewController || ![classSKStoreReviewController respondsToSelector: @selector(requestReview)])
return false;
[classSKStoreReviewController performSelector: @selector(requestReview)];
return true;
}
#endif
#pragma once
#include "UnityAppController.h"
#include <AvailabilityMacros.h>
@interface UnityAppController (ViewHandling)
// tweaking view hierarchy and handling of orientation
// there are 3 main uses cases regarding UI handling:
//
// 1. normal game case: you shouldnt care about all this at all
//
// 2. you need some not-so-trivial overlayed views and/or minor UI tweaking
// most likely all you need is to subscribe to "orientation changed" notification
// or in case you have per-orientation UI logic override willTransitionToViewController
//
// 3. you create UI-rich app where unity view is just one of many
// in that case you might want to create your own controllers and implement transitions on top
// also instead of orientUnity: (and Screen.orientation in script) you should use orientInterface
// override this if you need customized unityview (subclassing)
// if you simply want different root view, tweak view hierarchy in createAutorotatingUnityViewController
- (UnityView*)createUnityView;
// for view controllers we discern between platforms that do support orientation (e.g. iOS) and the ones that dont (e.g. tvOS)
// both have concept of "default" view controller: for iOS it will be auto-rotating one (with possible constraints) and "simple" controller otherwise
// in case of supporting orientation we will discern case of fixed-orientation view controller (that seems to be the only way to handle it robustly)
// _unityView will be inited at the point of calling any of "create view controller" methods
// please note that these are actual "create" methods: there is no need to tweak hierarchy right away
- (UIViewController*)createUnityViewControllerDefault;
#if UNITY_SUPPORT_ROTATION
- (UIViewController*)createUnityViewControllerForOrientation:(UIInterfaceOrientation)orient;
#endif
#if UNITY_SUPPORT_ROTATION
// if you override these you need to call super
// if your root controller is not subclassed from UnityViewControllerBase, call these when rotation is happening
- (void)interfaceWillChangeOrientationTo:(UIInterfaceOrientation)toInterfaceOrientation;
- (void)interfaceDidChangeOrientationFrom:(UIInterfaceOrientation)fromInterfaceOrientation;
#endif
// handling of changing ViewControllers:
// willStartWithViewController: will be called on startup, when creating view hierarchy
// willTransitionToViewController:fromViewController: didTransitionToViewController:fromViewController:
// are called before/after we are doing some magic to switch to new root controller due to forced orientation change
// by default:
// willStartWithViewController: will make _unityView as root view
// willTransitionToViewController:fromViewController: will do nothing
// didTransitionToViewController:fromViewController: will send orientation events to unity view
// you can use them to tweak view hierarchy if needed
- (void)willStartWithViewController:(UIViewController*)controller;
- (void)willTransitionToViewController:(UIViewController*)toController fromViewController:(UIViewController*)fromController;
- (void)didTransitionToViewController:(UIViewController*)toController fromViewController:(UIViewController*)fromController;
// override this if you want to have custom snapshot view.
// by default it will capture the frame drawn inside applicationWillResignActive specifically to let app respond to OnApplicationPause
// will be called on every applicationWillResignActive; returned view will be released in applicationDidBecomeActive
// NB: case of returning nil will be handled gracefully
- (UIView*)createSnapshotView;
// you should not override these methods
// creates initial UI hierarchy (e.g. splash screen) and calls willStartWithViewController
- (void)createUI;
// shows game itself (hides splash, and bring _rootView to front)
- (void)showGameUI;
// returns the topmost presentedViewController if there is one, or just rootViewController
- (UIViewController*)topMostController;
// will create the correct view controller for requested orientation/autorotation
- (UIViewController*)createRootViewController;
// old deprecated methods: no longer used
// the caveat is: there are some issues in clang related to method deprecation
// which results in warnings not being generated for overriding deprecated methods (in some circumstances).
// so instead of deprecating these methods we just remove them and will check at runtime if user have them and whine about it
//- (UnityView*)createUnityViewImpl DEPRECATED_MSG_ATTRIBUTE("Will not be called. Override createUnityView");
//- (void)createViewHierarchyImpl DEPRECATED_MSG_ATTRIBUTE("Will not be called. Override willStartWithViewController");
//- (void)createViewHierarchy DEPRECATED_MSG_ATTRIBUTE("Is not implemented. Use createUI");
@end
#if UNITY_SUPPORT_ROTATION
@interface UnityAppController (OrientationSupport)
// will create the correct view controller for given orientation
- (UIViewController*)createRootViewControllerForOrientation:(UIInterfaceOrientation)orientation;
// forcibly orient interface
- (void)orientInterface:(UIInterfaceOrientation)orient;
// check unity requested orientation and applies it
- (void)checkOrientationRequest;
- (void)orientUnity:(UIInterfaceOrientation)orient __deprecated_msg("use orientInterface instead.");
@end
#endif
#import "UnityView.h"
#include "UI/Keyboard.h"
#include <sys/time.h>
#include <map>
#include <vector>
static NSArray* keyboardCommands = nil;
extern "C" int UnityGetAppleTVRemoteAllowExitToMenu();
extern "C" void UnitySetAppleTVRemoteAllowExitToMenu(int val);
@implementation UnityView (Keyboard)
// Keyboard shortcuts don't provide events for key up
// Keyboard shortcut callbacks are called with 0.4 (first time) and 0.1 (following times) seconds interval while pressing the key
// Below we implement key expiration mechanism where key up event is generated if shortcut callback
// is not called for specific key for more than <kKeyTimeoutInSeconds>
typedef std::map<int, double> KeyMap;
static const double kKeyTimeoutInSeconds = 0.5;
static KeyMap& GetKeyMap()
{
static KeyMap s_Map;
return s_Map;
}
static double GetTimeInSeconds()
{
timeval now;
gettimeofday(&now, NULL);
return now.tv_sec + now.tv_usec / 1000000.0;
}
- (void)createKeyboard
{
// only English keyboard layout is supported
NSString* baseLayout = @"1234567890-=qwertyuiop[]asdfghjkl;'\\`zxcvbnm,./!@#$%^&*()_+{}:\"|<>?~ \t\r\b\\";
NSString* numpadLayout = @"1234567890-=*+/.\r";
NSString* upperCaseLetters = @"QWERTYUIOPASDFGHJKLZXCVBNM";
size_t sizeOfKeyboardCommands = baseLayout.length + numpadLayout.length + upperCaseLetters.length + 11;
NSMutableArray* commands = [NSMutableArray arrayWithCapacity: sizeOfKeyboardCommands];
for (NSInteger i = 0; i < baseLayout.length; ++i)
{
NSString* input = [baseLayout substringWithRange: NSMakeRange(i, 1)];
[commands addObject: [UIKeyCommand keyCommandWithInput: input modifierFlags: kNilOptions action: @selector(handleCommand:)]];
}
for (NSInteger i = 0; i < numpadLayout.length; ++i)
{
NSString* input = [numpadLayout substringWithRange: NSMakeRange(i, 1)];
[commands addObject: [UIKeyCommand keyCommandWithInput: input modifierFlags: UIKeyModifierNumericPad action: @selector(handleCommand:)]];
}
for (NSInteger i = 0; i < upperCaseLetters.length; ++i)
{
NSString* input = [upperCaseLetters substringWithRange: NSMakeRange(i, 1)];
[commands addObject: [UIKeyCommand keyCommandWithInput: input modifierFlags: UIKeyModifierShift action: @selector(handleCommand:)]];
}
// up, down, left, right, esc
[commands addObject: [UIKeyCommand keyCommandWithInput: UIKeyInputUpArrow modifierFlags: kNilOptions action: @selector(handleCommand:)]];
[commands addObject: [UIKeyCommand keyCommandWithInput: UIKeyInputDownArrow modifierFlags: kNilOptions action: @selector(handleCommand:)]];
[commands addObject: [UIKeyCommand keyCommandWithInput: UIKeyInputLeftArrow modifierFlags: kNilOptions action: @selector(handleCommand:)]];
[commands addObject: [UIKeyCommand keyCommandWithInput: UIKeyInputRightArrow modifierFlags: kNilOptions action: @selector(handleCommand:)]];
[commands addObject: [UIKeyCommand keyCommandWithInput: UIKeyInputEscape modifierFlags: kNilOptions action: @selector(handleCommand:)]];
// caps Lock, shift, control, option, command
[commands addObject: [UIKeyCommand keyCommandWithInput: @"" modifierFlags: UIKeyModifierAlphaShift action: @selector(handleCommand:)]];
[commands addObject: [UIKeyCommand keyCommandWithInput: @"" modifierFlags: UIKeyModifierShift action: @selector(handleCommand:)]];
[commands addObject: [UIKeyCommand keyCommandWithInput: @"" modifierFlags: UIKeyModifierControl action: @selector(handleCommand:)]];
[commands addObject: [UIKeyCommand keyCommandWithInput: @"" modifierFlags: UIKeyModifierAlternate action: @selector(handleCommand:)]];
[commands addObject: [UIKeyCommand keyCommandWithInput: @"" modifierFlags: UIKeyModifierCommand action: @selector(handleCommand:)]];
keyboardCommands = commands.copy;
}
- (NSArray*)keyCommands
{
//keyCommands take control of buttons over UITextView, that's why need to return nil if text input field is active or we have an external keyboard attached AND a first responder
if ([[KeyboardDelegate Instance] status] == Visible || ([[KeyboardDelegate Instance] hasExternalKeyboard] && [self hasFirstResponderInHeirachy: UnityGetGLView()]))
return nil;
if (keyboardCommands == nil)
{
[self createKeyboard];
}
return keyboardCommands;
}
- (bool)hasFirstResponderInHeirachy:(UIView*)view
{
if (view.isFirstResponder)
return true;
for (UIView* subview in view.subviews)
{
if ([self hasFirstResponderInHeirachy: subview])
return true;
}
return false;
}
- (bool)isValidCodeForButton:(int)code
{
return (code > 0 && code < 128);
}
- (void)handleCommand:(UIKeyCommand *)command
{
NSString* input = command.input;
UIKeyModifierFlags modifierFlags = command.modifierFlags;
char inputChar = ([input length] > 0) ? [input characterAtIndex: 0] : 0;
int code = (int)inputChar; // ASCII code
UnitySendKeyboardCommand(command);
if (![self isValidCodeForButton: code])
{
code = 0;
}
if ((modifierFlags & UIKeyModifierAlphaShift) != 0)
code = UnityStringToKey("caps lock");
if ((modifierFlags & UIKeyModifierShift) != 0)
code = UnityStringToKey("left shift");
if ((modifierFlags & UIKeyModifierControl) != 0)
code = UnityStringToKey("left ctrl");
if ((modifierFlags & UIKeyModifierAlternate) != 0)
code = UnityStringToKey("left alt");
if ((modifierFlags & UIKeyModifierCommand) != 0)
code = UnityStringToKey("left cmd");
if ((modifierFlags & UIKeyModifierNumericPad) != 0)
{
switch (inputChar)
{
case '0':
code = UnityStringToKey("[0]");
break;
case '1':
code = UnityStringToKey("[1]");
break;
case '2':
code = UnityStringToKey("[2]");
break;
case '3':
code = UnityStringToKey("[3]");
break;
case '4':
code = UnityStringToKey("[4]");
break;
case '5':
code = UnityStringToKey("[5]");
break;
case '6':
code = UnityStringToKey("[6]");
break;
case '7':
code = UnityStringToKey("[7]");
break;
case '8':
code = UnityStringToKey("[8]");
break;
case '9':
code = UnityStringToKey("[9]");
break;
case '-':
code = UnityStringToKey("[-]");
break;
case '=':
code = UnityStringToKey("equals");
break;
case '*':
code = UnityStringToKey("[*]");
break;
case '+':
code = UnityStringToKey("[+]");
break;
case '/':
code = UnityStringToKey("[/]");
break;
case '.':
code = UnityStringToKey("[.]");
break;
case '\r':
code = UnityStringToKey("enter");
break;
default:
break;
}
}
if (input == UIKeyInputUpArrow)
code = UnityStringToKey("up");
else if (input == UIKeyInputDownArrow)
code = UnityStringToKey("down");
else if (input == UIKeyInputRightArrow)
code = UnityStringToKey("right");
else if (input == UIKeyInputLeftArrow)
code = UnityStringToKey("left");
else if (input == UIKeyInputEscape)
code = UnityStringToKey("escape");
KeyMap::iterator item = GetKeyMap().find(code);
if (item == GetKeyMap().end())
{
// New key is down, register it and its time
UnitySetKeyboardKeyState(code, true);
GetKeyMap()[code] = GetTimeInSeconds();
}
else
{
// Still holding the key, update its time
item->second = GetTimeInSeconds();
}
}
- (void)processKeyboard
{
KeyMap& map = GetKeyMap();
if (map.size() == 0)
return;
std::vector<int> keysToUnpress;
double nowTime = GetTimeInSeconds();
for (KeyMap::iterator item = map.begin();
item != map.end();
item++)
{
// Key has expired, register it for key up event
if (nowTime - item->second > kKeyTimeoutInSeconds)
keysToUnpress.push_back(item->first);
}
for (std::vector<int>::iterator item = keysToUnpress.begin();
item != keysToUnpress.end();
item++)
{
map.erase(*item);
UnitySetKeyboardKeyState(*item, false);
}
}
@end
#pragma once
@interface UnityView (iOS)
// will simply update content orientation (it might be tweaked in layoutSubviews, due to disagreement between unity and view controller)
- (void)willRotateToOrientation:(UIInterfaceOrientation)toOrientation fromOrientation:(UIInterfaceOrientation)fromOrientation;
// will recreate gles backing if needed and repaint once to make sure we dont have black frame creeping in
- (void)didRotate;
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event;
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event;
- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event;
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event;
@end
此文件的差异太大,无法显示。
此文件类型无法预览
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。

105.5 KB | 宽: | 高:

60.3 KB | 宽: | 高:

resources/ZAA_Launch_Bg_1.jpg
resources/ZAA_Launch_Bg_1.jpg
resources/ZAA_Launch_Bg_1.jpg
resources/ZAA_Launch_Bg_1.jpg
  • 两方对比
  • 交换覆盖
  • 透明覆盖
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!