├── .gitignore ├── Assets ├── 01.Scenes.meta ├── 01.Scenes │ ├── SampleScene.unity │ └── SampleScene.unity.meta ├── 02.Scripts.meta ├── 02.Scripts │ ├── AppTrackingTransparency.meta │ └── AppTrackingTransparency │ │ ├── AppTrackingAuthorization.cs │ │ ├── AppTrackingAuthorization.cs.meta │ │ ├── AppTrackingTransparency.cs │ │ └── AppTrackingTransparency.cs.meta ├── 03.Prefebs.meta ├── 03.Prefebs │ ├── AppTrackingAuthorization.prefab │ └── AppTrackingAuthorization.prefab.meta ├── 10.Tools.meta ├── 10.Tools │ ├── AppTrackingTransparency.meta │ ├── AppTrackingTransparency │ │ ├── Editor.meta │ │ └── Editor │ │ │ ├── NSUserTrackingUsageDescription.txt │ │ │ ├── NSUserTrackingUsageDescription.txt.meta │ │ │ ├── SKAdNetworkItems.plist │ │ │ └── SKAdNetworkItems.plist.meta │ ├── NativeLocale.meta │ ├── NativeLocale │ │ ├── Editor.meta │ │ ├── Editor │ │ │ ├── NativeLocale.cs │ │ │ ├── NativeLocale.cs.meta │ │ │ ├── Xcode.meta │ │ │ └── Xcode │ │ │ │ ├── AssetCatalog.cs │ │ │ │ ├── AssetCatalog.cs.meta │ │ │ │ ├── JsonParser.cs │ │ │ │ ├── JsonParser.cs.meta │ │ │ │ ├── PBX.meta │ │ │ │ ├── PBX │ │ │ │ ├── Elements.cs │ │ │ │ ├── Elements.cs.meta │ │ │ │ ├── Lexer.cs │ │ │ │ ├── Lexer.cs.meta │ │ │ │ ├── Objects.cs │ │ │ │ ├── Objects.cs.meta │ │ │ │ ├── Parser.cs │ │ │ │ ├── Parser.cs.meta │ │ │ │ ├── Sections.cs │ │ │ │ ├── Sections.cs.meta │ │ │ │ ├── Serializer.cs │ │ │ │ ├── Serializer.cs.meta │ │ │ │ ├── Utils.cs │ │ │ │ └── Utils.cs.meta │ │ │ │ ├── PBXCapabilityType.cs │ │ │ │ ├── PBXCapabilityType.cs.meta │ │ │ │ ├── PBXPath.cs │ │ │ │ ├── PBXPath.cs.meta │ │ │ │ ├── PBXProject.cs │ │ │ │ ├── PBXProject.cs.meta │ │ │ │ ├── PBXProjectData.cs │ │ │ │ ├── PBXProjectData.cs.meta │ │ │ │ ├── PBXProjectExtensions.cs │ │ │ │ ├── PBXProjectExtensions.cs.meta │ │ │ │ ├── PlistParser.cs │ │ │ │ ├── PlistParser.cs.meta │ │ │ │ ├── ProjectCapabilityManager.cs │ │ │ │ └── ProjectCapabilityManager.cs.meta │ │ ├── iOS.meta │ │ └── iOS │ │ │ ├── Base.lproj.meta │ │ │ ├── Base.lproj │ │ │ ├── InfoPlist.strings │ │ │ └── InfoPlist.strings.meta │ │ │ ├── en.lproj.meta │ │ │ ├── en.lproj │ │ │ ├── InfoPlist.strings │ │ │ └── InfoPlist.strings.meta │ │ │ ├── ja.lproj.meta │ │ │ ├── ja.lproj │ │ │ ├── InfoPlist.strings │ │ │ └── InfoPlist.strings.meta │ │ │ ├── ko.lproj.meta │ │ │ ├── ko.lproj │ │ │ ├── InfoPlist.strings │ │ │ └── InfoPlist.strings.meta │ │ │ ├── zh-Hans.lproj.meta │ │ │ ├── zh-Hans.lproj │ │ │ ├── InfoPlist.strings │ │ │ └── InfoPlist.strings.meta │ │ │ ├── zh-Hant.lproj.meta │ │ │ └── zh-Hant.lproj │ │ │ ├── InfoPlist.strings │ │ │ └── InfoPlist.strings.meta │ ├── PostBuildProcess.meta │ └── PostBuildProcess │ │ ├── Editor.meta │ │ └── Editor │ │ ├── XcodeSettingsPostProcesser.cs │ │ └── XcodeSettingsPostProcesser.cs.meta ├── Plugins.meta └── Plugins │ ├── iOS.meta │ └── iOS │ ├── UnityAppTrackingTransparency.h │ ├── UnityAppTrackingTransparency.h.meta │ ├── UnityAppTrackingTransparency.mm │ ├── UnityAppTrackingTransparency.mm.meta │ ├── UnityBridgeAppTrackingTransparency.h │ ├── UnityBridgeAppTrackingTransparency.h.meta │ ├── UnityBridgeAppTrackingTransparency.mm │ └── UnityBridgeAppTrackingTransparency.mm.meta ├── LICENSE ├── Packages ├── manifest.json └── packages-lock.json ├── ProjectSettings ├── AudioManager.asset ├── ClusterInputManager.asset ├── DynamicsManager.asset ├── EditorBuildSettings.asset ├── EditorSettings.asset ├── GraphicsSettings.asset ├── InputManager.asset ├── NavMeshAreas.asset ├── NetworkManager.asset ├── PackageManagerSettings.asset ├── Physics2DSettings.asset ├── PresetManager.asset ├── ProjectSettings.asset ├── ProjectVersion.txt ├── QualitySettings.asset ├── TagManager.asset ├── TimeManager.asset ├── UnityConnectSettings.asset ├── VFXManager.asset └── XRSettings.asset ├── README.md └── SampleScreenShot ├── Image01.png ├── Image02.png ├── Image03.png ├── Image04.png ├── Image05.png ├── Image06.png └── Image07.png /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | Library 3 | Temp 4 | -------------------------------------------------------------------------------- /Assets/01.Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4e71904fe35044be2b473a9482b62320 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/01.Scenes/SampleScene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a0320b2cf50154fb1b1bddb7ce4ede96 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/02.Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3ed031d0daa9a43878a1f84236414932 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/02.Scripts/AppTrackingTransparency.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4057d324f9f76490195f02c40077d76a 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/02.Scripts/AppTrackingTransparency/AppTrackingAuthorization.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.iOS; 3 | using UnityEngine.UI; 4 | using Util.AD; 5 | 6 | // Do Not Modify Class 7 | public class AppTrackingAuthorization : MonoBehaviour 8 | { 9 | #region TEST CODE 10 | 11 | [SerializeField] 12 | private Text appTrackingStatus; 13 | [SerializeField] 14 | private Text advertisingIdentifier; 15 | 16 | 17 | private void Start() 18 | { 19 | DoTestView(AppTrackingTransparency.status); 20 | 21 | } 22 | 23 | private void DoTestView(AppTrackingTransparency.AuthorizationStatus myStatus) 24 | { 25 | DoSetAppTrackingStatus(myStatus); 26 | DoSetAdvertisingIdentifier(); 27 | } 28 | 29 | 30 | private void DoSetAppTrackingStatus(AppTrackingTransparency.AuthorizationStatus myAuthorizationStatus) 31 | { 32 | appTrackingStatus.text = $"{myAuthorizationStatus}"; 33 | } 34 | 35 | private void DoSetAdvertisingIdentifier() 36 | { 37 | advertisingIdentifier.text = Device.advertisingIdentifier; 38 | } 39 | 40 | 41 | public void OnClick() 42 | { 43 | // Request App Tracking Authorization 44 | AppTrackingTransparency.RequestAppTrackingAuthorization(); 45 | 46 | } 47 | #endregion 48 | 49 | 50 | #region AppTrackingAuthorization 51 | // Do Not Modify Method because Native Call DoOnCallBackAuthorization by UnitySendMessage("AppTrackingAuthorization", "DoOnCallBackAuthorization", ...) 52 | private void DoOnCallBackAuthorization(string myStatusData) 53 | { 54 | AppTrackingTransparency.AppTrackingCallBackData data = JsonUtility.FromJson(myStatusData); 55 | 56 | DoTestView((AppTrackingTransparency.AuthorizationStatus)data.statusCode); 57 | 58 | } 59 | 60 | // Do Not Modify Method, AppTrackingTransparency Call 61 | public void OnCallBackAuthorizationForNoneIOS(AppTrackingTransparency.AuthorizationStatus myStatus) 62 | { 63 | DoTestView(myStatus); 64 | 65 | } 66 | #endregion 67 | 68 | } 69 | -------------------------------------------------------------------------------- /Assets/02.Scripts/AppTrackingTransparency/AppTrackingAuthorization.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 772101f134b23480bbf62585e32954f8 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/02.Scripts/AppTrackingTransparency/AppTrackingTransparency.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | using System.Runtime.InteropServices; 6 | using AOT; 7 | 8 | namespace Util.AD 9 | { 10 | public class AppTrackingTransparency 11 | { 12 | public class AppTrackingCallBackData 13 | { 14 | public int statusCode; 15 | } 16 | 17 | public enum AuthorizationStatus 18 | { 19 | notDetermined = 0, 20 | restricted = 1, 21 | denied = 2, 22 | authorized = 3, 23 | } 24 | 25 | public static AuthorizationStatus status { get { return DoGetAppTrackingAuthorizationStatus(); } } 26 | 27 | public static void RequestAppTrackingAuthorization() 28 | { 29 | 30 | #if UNITY_IOS && !UNITY_EDITOR 31 | IOS_RequestAppTrackingAuthorization(); 32 | #else 33 | AppTrackingAuthorization ata = GameObject.FindObjectOfType(); 34 | ata.OnCallBackAuthorizationForNoneIOS(AuthorizationStatus.notDetermined); 35 | #endif 36 | } 37 | 38 | 39 | private static AuthorizationStatus DoGetAppTrackingAuthorizationStatus() 40 | { 41 | #if UNITY_IOS && !UNITY_EDITOR 42 | return (AuthorizationStatus)IOS_GetAppTrackingAuthorizationStatus(); 43 | #else 44 | return AuthorizationStatus.notDetermined; 45 | #endif 46 | } 47 | 48 | 49 | 50 | #if UNITY_IOS 51 | #region IOS Native Bridge 52 | 53 | [DllImport("__Internal")] 54 | private static extern int IOS_GetAppTrackingAuthorizationStatus(); 55 | 56 | [DllImport("__Internal")] 57 | private static extern void IOS_RequestAppTrackingAuthorization(); 58 | 59 | 60 | #endregion 61 | 62 | #endif 63 | } 64 | 65 | } 66 | 67 | -------------------------------------------------------------------------------- /Assets/02.Scripts/AppTrackingTransparency/AppTrackingTransparency.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cf735083c599147fe9cf28fb92ee2508 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/03.Prefebs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7976afeb47c464061a7bc0b7ea21d7af 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/03.Prefebs/AppTrackingAuthorization.prefab: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1 &5047218078277493923 4 | GameObject: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | serializedVersion: 6 10 | m_Component: 11 | - component: {fileID: 5047218078277493925} 12 | - component: {fileID: 5047218078277493924} 13 | m_Layer: 0 14 | m_Name: AppTrackingAuthorization 15 | m_TagString: Untagged 16 | m_Icon: {fileID: 0} 17 | m_NavMeshLayer: 0 18 | m_StaticEditorFlags: 0 19 | m_IsActive: 1 20 | --- !u!4 &5047218078277493925 21 | Transform: 22 | m_ObjectHideFlags: 0 23 | m_CorrespondingSourceObject: {fileID: 0} 24 | m_PrefabInstance: {fileID: 0} 25 | m_PrefabAsset: {fileID: 0} 26 | m_GameObject: {fileID: 5047218078277493923} 27 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 28 | m_LocalPosition: {x: 540, y: 979.13, z: 0} 29 | m_LocalScale: {x: 1, y: 1, z: 1} 30 | m_Children: [] 31 | m_Father: {fileID: 0} 32 | m_RootOrder: 0 33 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 34 | --- !u!114 &5047218078277493924 35 | MonoBehaviour: 36 | m_ObjectHideFlags: 0 37 | m_CorrespondingSourceObject: {fileID: 0} 38 | m_PrefabInstance: {fileID: 0} 39 | m_PrefabAsset: {fileID: 0} 40 | m_GameObject: {fileID: 5047218078277493923} 41 | m_Enabled: 1 42 | m_EditorHideFlags: 0 43 | m_Script: {fileID: 11500000, guid: 772101f134b23480bbf62585e32954f8, type: 3} 44 | m_Name: 45 | m_EditorClassIdentifier: 46 | appTrackingStatus: {fileID: 0} 47 | advertisingIdentifier: {fileID: 0} 48 | -------------------------------------------------------------------------------- /Assets/03.Prefebs/AppTrackingAuthorization.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: acab2f276ddec48d987e607591511010 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/10.Tools.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d153f6c1c9ba343e3bbdbcff425d373b 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/10.Tools/AppTrackingTransparency.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0ad39199163394bdda30501711aecd79 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/10.Tools/AppTrackingTransparency/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4a766f5b8a6bc43b8a228c1eec198ece 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/10.Tools/AppTrackingTransparency/Editor/NSUserTrackingUsageDescription.txt: -------------------------------------------------------------------------------- 1 | This is default NSUserTrackingUsageDescription! -------------------------------------------------------------------------------- /Assets/10.Tools/AppTrackingTransparency/Editor/NSUserTrackingUsageDescription.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cd4ab3c0e4c454ad880c5d34544655be 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/10.Tools/AppTrackingTransparency/Editor/SKAdNetworkItems.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SKAdNetworkItems 6 | 7 | 8 | 9 | SKAdNetworkIdentifier 10 | cstr6suwn9.skadnetwork 11 | 12 | 13 | 14 | SKAdNetworkIdentifier 15 | v9wttpbfk9.skadnetwork 16 | 17 | 18 | 19 | SKAdNetworkIdentifier 20 | 4DZT52R2T5.skadnetwork 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Assets/10.Tools/AppTrackingTransparency/Editor/SKAdNetworkItems.plist.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 32f140fbf54a9554dac757fd34cbf702 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 94f0ffe67f28647579afab7381aaeb7e 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 40ea972b444d54436a89e35bd5a77704 3 | folderAsset: yes 4 | timeCreated: 1496823339 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/NativeLocale.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEditor; 5 | using System.IO; 6 | using XcodeProjectForLocalization = ChillyRoom.UnityEditor.iOS.Xcode; 7 | using UnityEditor.iOS.Xcode; 8 | 9 | public class NativeLocale 10 | { 11 | public static void AddLocalizedStringsIOS(string projectPath, string localizedDirectoryPath) 12 | { 13 | DirectoryInfo dir = new DirectoryInfo(localizedDirectoryPath); 14 | if(!dir.Exists) 15 | return; 16 | 17 | DoAddLocalizationFolder(projectPath); 18 | 19 | List locales = new List(); 20 | var localeDirs = dir.GetDirectories("*.lproj", SearchOption.TopDirectoryOnly); 21 | 22 | foreach(var sub in localeDirs) 23 | { 24 | locales.Add(Path.GetFileNameWithoutExtension(sub.Name)); 25 | } 26 | 27 | 28 | AddLocalizedStringsIOS(projectPath, localizedDirectoryPath, locales); 29 | } 30 | 31 | private static void DoAddLocalizationFolder(string projectPath) 32 | { 33 | string pbxProjectPath = UnityEditor.iOS.Xcode.PBXProject.GetPBXProjectPath(projectPath); 34 | UnityEditor.iOS.Xcode.PBXProject originalProj = new UnityEditor.iOS.Xcode.PBXProject(); 35 | 36 | originalProj.ReadFromFile(pbxProjectPath); 37 | string localizationFolderPath = $"{projectPath}/Localization"; 38 | if (false == Directory.Exists(localizationFolderPath)) 39 | { 40 | Directory.CreateDirectory(localizationFolderPath); 41 | } 42 | originalProj.AddFolderReference(localizationFolderPath, "Localization"); 43 | originalProj.WriteToFile(pbxProjectPath); 44 | } 45 | 46 | 47 | public static void AddLocalizedStringsIOS(string projectPath, string localizedDirectoryPath, List validLocales) 48 | { 49 | string projPath = projectPath + "/Unity-iPhone.xcodeproj/project.pbxproj"; 50 | XcodeProjectForLocalization.PBXProject proj = new XcodeProjectForLocalization.PBXProject(); 51 | proj.ReadFromFile(projPath); 52 | 53 | string variantGroupName = "InfoPlist.strings"; 54 | proj.ClearVariantGroupEntries(variantGroupName); 55 | 56 | foreach (var locale in validLocales) 57 | { 58 | // copy contents in the localization directory to project directory 59 | string src = Path.Combine(localizedDirectoryPath, locale + ".lproj"); 60 | DirectoryCopy(src, Path.Combine(projectPath, "Localization/" + locale + ".lproj")); 61 | 62 | string fileRelatvePath = string.Format("Localization/{0}.lproj/InfoPlist.strings", locale); 63 | 64 | proj.AddLocalization(variantGroupName, locale, fileRelatvePath); 65 | } 66 | 67 | proj.WriteToFile(projPath); 68 | } 69 | 70 | 71 | private static void DirectoryCopy(string sourceDirName, string destDirName) 72 | { 73 | DirectoryInfo dir = new DirectoryInfo(sourceDirName); 74 | 75 | if (!dir.Exists) 76 | return; 77 | 78 | if (!Directory.Exists(destDirName)) 79 | { 80 | Directory.CreateDirectory(destDirName); 81 | } 82 | 83 | FileInfo[] files = dir.GetFiles(); 84 | 85 | foreach (FileInfo file in files) 86 | { 87 | // skip unity meta files 88 | if(file.FullName.EndsWith(".meta")) 89 | continue; 90 | string temppath = Path.Combine(destDirName, file.Name); 91 | file.CopyTo(temppath, true); 92 | } 93 | 94 | DirectoryInfo[] dirs = dir.GetDirectories(); 95 | foreach (DirectoryInfo subdir in dirs) 96 | { 97 | string temppath = Path.Combine(destDirName, subdir.Name); 98 | DirectoryCopy(subdir.FullName, temppath); 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/NativeLocale.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3a34fc5c202884be2881f0ddb1d611d7 3 | timeCreated: 1496821555 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bef53ee1a693a4d14adb39b28f71e82f 3 | folderAsset: yes 4 | timeCreated: 1496809275 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/AssetCatalog.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 46dd33873affe4e5caf86cb784bd831a 3 | timeCreated: 1496741691 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/JsonParser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | using System.Linq; 6 | 7 | namespace ChillyRoom.UnityEditor.iOS.Xcode 8 | { 9 | internal class JsonElement 10 | { 11 | protected JsonElement() {} 12 | 13 | // convenience methods 14 | public string AsString() { return ((JsonElementString)this).value; } 15 | public int AsInteger() { return ((JsonElementInteger)this).value; } 16 | public bool AsBoolean() { return ((JsonElementBoolean)this).value; } 17 | public JsonElementArray AsArray() { return (JsonElementArray)this; } 18 | public JsonElementDict AsDict() { return (JsonElementDict)this; } 19 | 20 | public JsonElement this[string key] 21 | { 22 | get { return AsDict()[key]; } 23 | set { AsDict()[key] = value; } 24 | } 25 | } 26 | 27 | internal class JsonElementString : JsonElement 28 | { 29 | public JsonElementString(string v) { value = v; } 30 | 31 | public string value; 32 | } 33 | 34 | internal class JsonElementInteger : JsonElement 35 | { 36 | public JsonElementInteger(int v) { value = v; } 37 | 38 | public int value; 39 | } 40 | 41 | internal class JsonElementBoolean : JsonElement 42 | { 43 | public JsonElementBoolean(bool v) { value = v; } 44 | 45 | public bool value; 46 | } 47 | 48 | internal class JsonElementDict : JsonElement 49 | { 50 | public JsonElementDict() : base() {} 51 | 52 | private SortedDictionary m_PrivateValue = new SortedDictionary(); 53 | public IDictionary values { get { return m_PrivateValue; }} 54 | 55 | new public JsonElement this[string key] 56 | { 57 | get { 58 | if (values.ContainsKey(key)) 59 | return values[key]; 60 | return null; 61 | } 62 | set { this.values[key] = value; } 63 | } 64 | 65 | public bool Contains(string key) 66 | { 67 | return values.ContainsKey(key); 68 | } 69 | 70 | public void Remove(string key) 71 | { 72 | values.Remove(key); 73 | } 74 | 75 | // convenience methods 76 | public void SetInteger(string key, int val) 77 | { 78 | values[key] = new JsonElementInteger(val); 79 | } 80 | 81 | public void SetString(string key, string val) 82 | { 83 | values[key] = new JsonElementString(val); 84 | } 85 | 86 | public void SetBoolean(string key, bool val) 87 | { 88 | values[key] = new JsonElementBoolean(val); 89 | } 90 | 91 | public JsonElementArray CreateArray(string key) 92 | { 93 | var v = new JsonElementArray(); 94 | values[key] = v; 95 | return v; 96 | } 97 | 98 | public JsonElementDict CreateDict(string key) 99 | { 100 | var v = new JsonElementDict(); 101 | values[key] = v; 102 | return v; 103 | } 104 | } 105 | 106 | internal class JsonElementArray : JsonElement 107 | { 108 | public JsonElementArray() : base() {} 109 | public List values = new List(); 110 | 111 | // convenience methods 112 | public void AddString(string val) 113 | { 114 | values.Add(new JsonElementString(val)); 115 | } 116 | 117 | public void AddInteger(int val) 118 | { 119 | values.Add(new JsonElementInteger(val)); 120 | } 121 | 122 | public void AddBoolean(bool val) 123 | { 124 | values.Add(new JsonElementBoolean(val)); 125 | } 126 | 127 | public JsonElementArray AddArray() 128 | { 129 | var v = new JsonElementArray(); 130 | values.Add(v); 131 | return v; 132 | } 133 | 134 | public JsonElementDict AddDict() 135 | { 136 | var v = new JsonElementDict(); 137 | values.Add(v); 138 | return v; 139 | } 140 | } 141 | 142 | internal class JsonDocument 143 | { 144 | public JsonElementDict root; 145 | public string indentString = " "; 146 | 147 | public JsonDocument() 148 | { 149 | root = new JsonElementDict(); 150 | } 151 | 152 | void AppendIndent(StringBuilder sb, int indent) 153 | { 154 | for (int i = 0; i < indent; ++i) 155 | sb.Append(indentString); 156 | } 157 | 158 | void WriteString(StringBuilder sb, string str) 159 | { 160 | // TODO: escape 161 | sb.Append('"'); 162 | sb.Append(str); 163 | sb.Append('"'); 164 | } 165 | 166 | void WriteBoolean(StringBuilder sb, bool value) 167 | { 168 | sb.Append(value ? "true" : "false"); 169 | } 170 | 171 | void WriteInteger(StringBuilder sb, int value) 172 | { 173 | sb.Append(value.ToString()); 174 | } 175 | 176 | void WriteDictKeyValue(StringBuilder sb, string key, JsonElement value, int indent) 177 | { 178 | sb.Append("\n"); 179 | AppendIndent(sb, indent); 180 | WriteString(sb, key); 181 | sb.Append(" : "); 182 | if (value is JsonElementString) 183 | WriteString(sb, value.AsString()); 184 | else if (value is JsonElementInteger) 185 | WriteInteger(sb, value.AsInteger()); 186 | else if (value is JsonElementBoolean) 187 | WriteBoolean(sb, value.AsBoolean()); 188 | else if (value is JsonElementDict) 189 | WriteDict(sb, value.AsDict(), indent); 190 | else if (value is JsonElementArray) 191 | WriteArray(sb, value.AsArray(), indent); 192 | } 193 | 194 | void WriteDict(StringBuilder sb, JsonElementDict el, int indent) 195 | { 196 | sb.Append("{"); 197 | bool hasElement = false; 198 | foreach (var key in el.values.Keys) 199 | { 200 | if (hasElement) 201 | sb.Append(","); // trailing commas not supported 202 | WriteDictKeyValue(sb, key, el[key], indent+1); 203 | hasElement = true; 204 | } 205 | sb.Append("\n"); 206 | AppendIndent(sb, indent); 207 | sb.Append("}"); 208 | } 209 | 210 | void WriteArray(StringBuilder sb, JsonElementArray el, int indent) 211 | { 212 | sb.Append("["); 213 | bool hasElement = false; 214 | foreach (var value in el.values) 215 | { 216 | if (hasElement) 217 | sb.Append(","); // trailing commas not supported 218 | sb.Append("\n"); 219 | AppendIndent(sb, indent+1); 220 | 221 | if (value is JsonElementString) 222 | WriteString(sb, value.AsString()); 223 | else if (value is JsonElementInteger) 224 | WriteInteger(sb, value.AsInteger()); 225 | else if (value is JsonElementBoolean) 226 | WriteBoolean(sb, value.AsBoolean()); 227 | else if (value is JsonElementDict) 228 | WriteDict(sb, value.AsDict(), indent+1); 229 | else if (value is JsonElementArray) 230 | WriteArray(sb, value.AsArray(), indent+1); 231 | hasElement = true; 232 | } 233 | sb.Append("\n"); 234 | AppendIndent(sb, indent); 235 | sb.Append("]"); 236 | } 237 | 238 | public void WriteToFile(string path) 239 | { 240 | File.WriteAllText(path, WriteToString()); 241 | } 242 | 243 | public void WriteToStream(TextWriter tw) 244 | { 245 | tw.Write(WriteToString()); 246 | } 247 | 248 | public string WriteToString() 249 | { 250 | var sb = new StringBuilder(); 251 | WriteDict(sb, root, 0); 252 | return sb.ToString(); 253 | } 254 | } 255 | 256 | 257 | } // namespace UnityEditor.iOS.Xcode -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/JsonParser.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 052ac8a8c9ae3466f94f7b3b6c5b61af 3 | timeCreated: 1496741691 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/PBX.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7625017be5ff149a6b0f20ee645ce11e 3 | folderAsset: yes 4 | timeCreated: 1496741689 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/PBX/Elements.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Collections; 3 | using System; 4 | 5 | 6 | namespace ChillyRoom.UnityEditor.iOS.Xcode.PBX 7 | { 8 | 9 | class PBXElement 10 | { 11 | protected PBXElement() {} 12 | 13 | // convenience methods 14 | public string AsString() { return ((PBXElementString)this).value; } 15 | public PBXElementArray AsArray() { return (PBXElementArray)this; } 16 | public PBXElementDict AsDict() { return (PBXElementDict)this; } 17 | 18 | public PBXElement this[string key] 19 | { 20 | get { return AsDict()[key]; } 21 | set { AsDict()[key] = value; } 22 | } 23 | } 24 | 25 | class PBXElementString : PBXElement 26 | { 27 | public PBXElementString(string v) { value = v; } 28 | 29 | public string value; 30 | } 31 | 32 | class PBXElementDict : PBXElement 33 | { 34 | public PBXElementDict() : base() {} 35 | 36 | private Dictionary m_PrivateValue = new Dictionary(); 37 | public IDictionary values { get { return m_PrivateValue; }} 38 | 39 | new public PBXElement this[string key] 40 | { 41 | get { 42 | if (values.ContainsKey(key)) 43 | return values[key]; 44 | return null; 45 | } 46 | set { this.values[key] = value; } 47 | } 48 | 49 | public bool Contains(string key) 50 | { 51 | return values.ContainsKey(key); 52 | } 53 | 54 | public void Remove(string key) 55 | { 56 | values.Remove(key); 57 | } 58 | 59 | public void SetString(string key, string val) 60 | { 61 | values[key] = new PBXElementString(val); 62 | } 63 | 64 | public PBXElementArray CreateArray(string key) 65 | { 66 | var v = new PBXElementArray(); 67 | values[key] = v; 68 | return v; 69 | } 70 | 71 | public PBXElementDict CreateDict(string key) 72 | { 73 | var v = new PBXElementDict(); 74 | values[key] = v; 75 | return v; 76 | } 77 | } 78 | 79 | class PBXElementArray : PBXElement 80 | { 81 | public PBXElementArray() : base() {} 82 | public List values = new List(); 83 | 84 | // convenience methods 85 | public void AddString(string val) 86 | { 87 | values.Add(new PBXElementString(val)); 88 | } 89 | 90 | public PBXElementArray AddArray() 91 | { 92 | var v = new PBXElementArray(); 93 | values.Add(v); 94 | return v; 95 | } 96 | 97 | public PBXElementDict AddDict() 98 | { 99 | var v = new PBXElementDict(); 100 | values.Add(v); 101 | return v; 102 | } 103 | } 104 | 105 | } // namespace UnityEditor.iOS.Xcode 106 | 107 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/PBX/Elements.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 83cffec4be0e045258109e9714cdaa5f 3 | timeCreated: 1496741691 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/PBX/Lexer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Text.RegularExpressions; 3 | using System.IO; 4 | using System.Linq; 5 | using System; 6 | 7 | 8 | namespace ChillyRoom.UnityEditor.iOS.Xcode.PBX 9 | { 10 | enum TokenType 11 | { 12 | EOF, 13 | Invalid, 14 | String, 15 | QuotedString, 16 | Comment, 17 | 18 | Semicolon, // ; 19 | Comma, // , 20 | Eq, // = 21 | LParen, // ( 22 | RParen, // ) 23 | LBrace, // { 24 | RBrace, // } 25 | } 26 | 27 | class Token 28 | { 29 | public TokenType type; 30 | 31 | // the line of the input stream the token starts in (0-based) 32 | public int line; 33 | 34 | // start and past-the-end positions of the token in the input stream 35 | public int begin, end; 36 | } 37 | 38 | class TokenList : List 39 | { 40 | } 41 | 42 | class Lexer 43 | { 44 | string text; 45 | int pos; 46 | int length; 47 | int line; 48 | 49 | public static TokenList Tokenize(string text) 50 | { 51 | var lexer = new Lexer(); 52 | lexer.SetText(text); 53 | return lexer.ScanAll(); 54 | } 55 | 56 | public void SetText(string text) 57 | { 58 | this.text = text + " "; // to prevent out-of-bounds access during look ahead 59 | pos = 0; 60 | length = text.Length; 61 | line = 0; 62 | } 63 | 64 | public TokenList ScanAll() 65 | { 66 | var tokens = new TokenList(); 67 | 68 | while (true) 69 | { 70 | var tok = new Token(); 71 | ScanOne(tok); 72 | tokens.Add(tok); 73 | if (tok.type == TokenType.EOF) 74 | break; 75 | } 76 | return tokens; 77 | } 78 | 79 | void UpdateNewlineStats(char ch) 80 | { 81 | if (ch == '\n') 82 | line++; 83 | } 84 | 85 | // tokens list is modified in the case when we add BrokenLine token and need to remove already 86 | // added tokens for the current line 87 | void ScanOne(Token tok) 88 | { 89 | while (true) 90 | { 91 | while (pos < length && Char.IsWhiteSpace(text[pos])) 92 | { 93 | UpdateNewlineStats(text[pos]); 94 | pos++; 95 | } 96 | 97 | if (pos >= length) 98 | { 99 | tok.type = TokenType.EOF; 100 | break; 101 | } 102 | 103 | char ch = text[pos]; 104 | char ch2 = text[pos+1]; 105 | 106 | if (ch == '\"') 107 | ScanQuotedString(tok); 108 | else if (ch == '/' && ch2 == '*') 109 | ScanMultilineComment(tok); 110 | else if (ch == '/' && ch2 == '/') 111 | ScanComment(tok); 112 | else if (IsOperator(ch)) 113 | ScanOperator(tok); 114 | else 115 | ScanString(tok); // be more robust and accept whatever is left 116 | return; 117 | } 118 | } 119 | 120 | void ScanString(Token tok) 121 | { 122 | tok.type = TokenType.String; 123 | tok.begin = pos; 124 | while (pos < length) 125 | { 126 | char ch = text[pos]; 127 | char ch2 = text[pos+1]; 128 | 129 | if (Char.IsWhiteSpace(ch)) 130 | break; 131 | else if (ch == '\"') 132 | break; 133 | else if (ch == '/' && ch2 == '*') 134 | break; 135 | else if (ch == '/' && ch2 == '/') 136 | break; 137 | else if (IsOperator(ch)) 138 | break; 139 | pos++; 140 | } 141 | tok.end = pos; 142 | tok.line = line; 143 | } 144 | 145 | void ScanQuotedString(Token tok) 146 | { 147 | tok.type = TokenType.QuotedString; 148 | tok.begin = pos; 149 | pos++; 150 | 151 | while (pos < length) 152 | { 153 | // ignore escaped quotes 154 | if (text[pos] == '\\' && text[pos+1] == '\"') 155 | { 156 | pos += 2; 157 | continue; 158 | } 159 | 160 | // note that we close unclosed quotes 161 | if (text[pos] == '\"') 162 | break; 163 | 164 | UpdateNewlineStats(text[pos]); 165 | pos++; 166 | } 167 | pos++; 168 | tok.end = pos; 169 | tok.line = line; 170 | } 171 | 172 | void ScanMultilineComment(Token tok) 173 | { 174 | tok.type = TokenType.Comment; 175 | tok.begin = pos; 176 | pos += 2; 177 | 178 | while (pos < length) 179 | { 180 | if (text[pos] == '*' && text[pos+1] == '/') 181 | break; 182 | 183 | // we support multiline comments 184 | UpdateNewlineStats(text[pos]); 185 | pos++; 186 | } 187 | pos += 2; 188 | tok.end = pos; 189 | tok.line = line; 190 | } 191 | 192 | void ScanComment(Token tok) 193 | { 194 | tok.type = TokenType.Comment; 195 | tok.begin = pos; 196 | pos += 2; 197 | 198 | while (pos < length) 199 | { 200 | if (text[pos] == '\n') 201 | break; 202 | pos++; 203 | } 204 | UpdateNewlineStats(text[pos]); 205 | pos++; 206 | tok.end = pos; 207 | tok.line = line; 208 | } 209 | 210 | bool IsOperator(char ch) 211 | { 212 | if (ch == ';' || ch == ',' || ch == '=' || ch == '(' || ch == ')' || ch == '{' || ch == '}') 213 | return true; 214 | return false; 215 | } 216 | 217 | void ScanOperator(Token tok) 218 | { 219 | switch (text[pos]) 220 | { 221 | case ';': ScanOperatorSpecific(tok, TokenType.Semicolon); return; 222 | case ',': ScanOperatorSpecific(tok, TokenType.Comma); return; 223 | case '=': ScanOperatorSpecific(tok, TokenType.Eq); return; 224 | case '(': ScanOperatorSpecific(tok, TokenType.LParen); return; 225 | case ')': ScanOperatorSpecific(tok, TokenType.RParen); return; 226 | case '{': ScanOperatorSpecific(tok, TokenType.LBrace); return; 227 | case '}': ScanOperatorSpecific(tok, TokenType.RBrace); return; 228 | default: return; 229 | } 230 | } 231 | 232 | void ScanOperatorSpecific(Token tok, TokenType type) 233 | { 234 | tok.type = type; 235 | tok.begin = pos; 236 | pos++; 237 | tok.end = pos; 238 | tok.line = line; 239 | } 240 | } 241 | 242 | 243 | } // namespace UnityEditor.iOS.Xcode -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/PBX/Lexer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9766f6c4eb5ef42f99c0d5f86e34ba84 3 | timeCreated: 1496741691 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/PBX/Objects.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 67cf10cf994604c719f706525399f867 3 | timeCreated: 1496741691 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/PBX/Parser.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Text.RegularExpressions; 3 | using System.IO; 4 | using System.Linq; 5 | using System; 6 | 7 | 8 | namespace ChillyRoom.UnityEditor.iOS.Xcode.PBX 9 | { 10 | 11 | class ValueAST {} 12 | 13 | // IdentifierAST := \ 14 | class IdentifierAST : ValueAST 15 | { 16 | public int value = 0; // token id 17 | } 18 | 19 | // TreeAST := '{' KeyValuePairList '}' 20 | // KeyValuePairList := KeyValuePair ',' KeyValuePairList 21 | // KeyValuePair ',' 22 | // (empty) 23 | class TreeAST : ValueAST 24 | { 25 | public List values = new List(); 26 | } 27 | 28 | // ListAST := '(' ValueList ')' 29 | // ValueList := ValueAST ',' ValueList 30 | // ValueAST ',' 31 | // (empty) 32 | class ArrayAST : ValueAST 33 | { 34 | public List values = new List(); 35 | } 36 | 37 | // KeyValueAST := IdentifierAST '=' ValueAST ';' 38 | // ValueAST := IdentifierAST | TreeAST | ListAST 39 | class KeyValueAST 40 | { 41 | public IdentifierAST key = null; 42 | public ValueAST value = null; // either IdentifierAST, TreeAST or ListAST 43 | } 44 | 45 | class Parser 46 | { 47 | TokenList tokens; 48 | int currPos; 49 | 50 | public Parser(TokenList tokens) 51 | { 52 | this.tokens = tokens; 53 | currPos = SkipComments(0); 54 | } 55 | 56 | int SkipComments(int pos) 57 | { 58 | while (pos < tokens.Count && tokens[pos].type == TokenType.Comment) 59 | { 60 | pos++; 61 | } 62 | return pos; 63 | } 64 | 65 | // returns new position 66 | int IncInternal(int pos) 67 | { 68 | if (pos >= tokens.Count) 69 | return pos; 70 | pos++; 71 | 72 | return SkipComments(pos); 73 | } 74 | 75 | // Increments current pointer if not past the end, returns previous pos 76 | int Inc() 77 | { 78 | int prev = currPos; 79 | currPos = IncInternal(currPos); 80 | return prev; 81 | } 82 | 83 | // Returns the token type of the current token 84 | TokenType Tok() 85 | { 86 | if (currPos >= tokens.Count) 87 | return TokenType.EOF; 88 | return tokens[currPos].type; 89 | } 90 | 91 | void SkipIf(TokenType type) 92 | { 93 | if (Tok() == type) 94 | Inc(); 95 | } 96 | 97 | string GetErrorMsg() 98 | { 99 | return "Invalid PBX project (parsing line " + tokens[currPos].line + ")"; 100 | } 101 | 102 | public IdentifierAST ParseIdentifier() 103 | { 104 | if (Tok() != TokenType.String && Tok() != TokenType.QuotedString) 105 | throw new Exception(GetErrorMsg()); 106 | var ast = new IdentifierAST(); 107 | ast.value = Inc(); 108 | return ast; 109 | } 110 | 111 | public TreeAST ParseTree() 112 | { 113 | if (Tok() != TokenType.LBrace) 114 | throw new Exception(GetErrorMsg()); 115 | Inc(); 116 | 117 | var ast = new TreeAST(); 118 | while (Tok() != TokenType.RBrace && Tok() != TokenType.EOF) 119 | { 120 | ast.values.Add(ParseKeyValue()); 121 | } 122 | SkipIf(TokenType.RBrace); 123 | return ast; 124 | } 125 | 126 | public ArrayAST ParseList() 127 | { 128 | if (Tok() != TokenType.LParen) 129 | throw new Exception(GetErrorMsg()); 130 | Inc(); 131 | 132 | var ast = new ArrayAST(); 133 | while (Tok() != TokenType.RParen && Tok() != TokenType.EOF) 134 | { 135 | ast.values.Add(ParseValue()); 136 | SkipIf(TokenType.Comma); 137 | } 138 | SkipIf(TokenType.RParen); 139 | return ast; 140 | } 141 | 142 | // throws on error 143 | public KeyValueAST ParseKeyValue() 144 | { 145 | var ast = new KeyValueAST(); 146 | ast.key = ParseIdentifier(); 147 | 148 | if (Tok() != TokenType.Eq) 149 | throw new Exception(GetErrorMsg()); 150 | Inc(); // skip '=' 151 | 152 | ast.value = ParseValue(); 153 | SkipIf(TokenType.Semicolon); 154 | 155 | return ast; 156 | } 157 | 158 | // throws on error 159 | public ValueAST ParseValue() 160 | { 161 | if (Tok() == TokenType.String || Tok() == TokenType.QuotedString) 162 | return ParseIdentifier(); 163 | else if (Tok() == TokenType.LBrace) 164 | return ParseTree(); 165 | else if (Tok() == TokenType.LParen) 166 | return ParseList(); 167 | throw new Exception(GetErrorMsg()); 168 | } 169 | } 170 | 171 | } // namespace UnityEditor.iOS.Xcode -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/PBX/Parser.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5ce5a244bc4e04a668ab097db4456665 3 | timeCreated: 1496741691 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/PBX/Sections.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | using System.Text.RegularExpressions; 6 | using System.IO; 7 | 8 | // Basr classes for section handling 9 | 10 | namespace ChillyRoom.UnityEditor.iOS.Xcode.PBX 11 | { 12 | 13 | // common base 14 | internal abstract class SectionBase 15 | { 16 | public abstract void AddObject(string key, PBXElementDict value); 17 | public abstract void WriteSection(StringBuilder sb, GUIDToCommentMap comments); 18 | } 19 | 20 | // known section: contains objects that we care about 21 | internal class KnownSectionBase : SectionBase where T : PBXObjectData, new() 22 | { 23 | private Dictionary m_Entries = new Dictionary(); 24 | 25 | private string m_Name; 26 | 27 | public KnownSectionBase(string sectionName) 28 | { 29 | m_Name = sectionName; 30 | } 31 | 32 | public IEnumerable> GetEntries() 33 | { 34 | return m_Entries; 35 | } 36 | 37 | public IEnumerable GetGuids() 38 | { 39 | return m_Entries.Keys; 40 | } 41 | 42 | public IEnumerable GetObjects() 43 | { 44 | return m_Entries.Values; 45 | } 46 | 47 | public override void AddObject(string key, PBXElementDict value) 48 | { 49 | T obj = new T(); 50 | obj.guid = key; 51 | obj.SetPropertiesWhenSerializing(value); 52 | obj.UpdateVars(); 53 | m_Entries[obj.guid] = obj; 54 | } 55 | 56 | public override void WriteSection(StringBuilder sb, GUIDToCommentMap comments) 57 | { 58 | if (m_Entries.Count == 0) 59 | return; // do not write empty sections 60 | 61 | sb.AppendFormat("\n\n/* Begin {0} section */", m_Name); 62 | var keys = new List(m_Entries.Keys); 63 | keys.Sort(StringComparer.Ordinal); 64 | foreach (string key in keys) 65 | { 66 | T obj = m_Entries[key]; 67 | obj.UpdateProps(); 68 | sb.Append("\n\t\t"); 69 | comments.WriteStringBuilder(sb, obj.guid); 70 | sb.Append(" = "); 71 | Serializer.WriteDict(sb, obj.GetPropertiesWhenSerializing(), 2, 72 | obj.shouldCompact, obj.checker, comments); 73 | sb.Append(";"); 74 | } 75 | sb.AppendFormat("\n/* End {0} section */", m_Name); 76 | } 77 | 78 | // returns null if not found 79 | public T this[string guid] 80 | { 81 | get { 82 | if (m_Entries.ContainsKey(guid)) 83 | return m_Entries[guid]; 84 | return null; 85 | } 86 | } 87 | 88 | public bool HasEntry(string guid) 89 | { 90 | return m_Entries.ContainsKey(guid); 91 | } 92 | 93 | public void AddEntry(T obj) 94 | { 95 | m_Entries[obj.guid] = obj; 96 | } 97 | 98 | public void RemoveEntry(string guid) 99 | { 100 | if (m_Entries.ContainsKey(guid)) 101 | m_Entries.Remove(guid); 102 | } 103 | } 104 | 105 | // we assume there is only one PBXProject entry 106 | internal class PBXProjectSection : KnownSectionBase 107 | { 108 | public PBXProjectSection() : base("PBXProject") 109 | { 110 | } 111 | 112 | public PBXProjectObjectData project 113 | { 114 | get { 115 | foreach (var kv in GetEntries()) 116 | return kv.Value; 117 | return null; 118 | } 119 | } 120 | } 121 | 122 | } // UnityEditor.iOS.Xcode 123 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/PBX/Sections.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 60639b138b83f4ce9b2448c38a6ba285 3 | timeCreated: 1496741691 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/PBX/Serializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Text.RegularExpressions; 5 | using System.IO; 6 | using System.Linq; 7 | 8 | namespace ChillyRoom.UnityEditor.iOS.Xcode.PBX 9 | { 10 | class PropertyCommentChecker 11 | { 12 | private int m_Level; 13 | private bool m_All; 14 | private List> m_Props; 15 | 16 | /* The argument is an array of matcher strings each of which determine 17 | whether a property with a certain path needs to be decorated with a 18 | comment. 19 | 20 | A path is a number of path elements concatenated by '/'. The last path 21 | element is either: 22 | the key if we're referring to a dict key 23 | the value if we're referring to a value in an array 24 | the value if we're referring to a value in a dict 25 | All other path elements are either: 26 | the key if the container is dict 27 | '*' if the container is array 28 | 29 | Path matcher has the same structure as a path, except that any of the 30 | elements may be '*'. Matcher matches a path if both have the same number 31 | of elements and for each pair matcher element is the same as path element 32 | or is '*'. 33 | 34 | a/b/c matches a/b/c but not a/b nor a/b/c/d 35 | a/* /c matches a/d/c but not a/b nor a/b/c/d 36 | * /* /* matches any path from three elements 37 | */ 38 | protected PropertyCommentChecker(int level, List> props) 39 | { 40 | m_Level = level; 41 | m_All = false; 42 | m_Props = props; 43 | } 44 | 45 | public PropertyCommentChecker() 46 | { 47 | m_Level = 0; 48 | m_All = false; 49 | m_Props = new List>(); 50 | } 51 | 52 | public PropertyCommentChecker(IEnumerable props) 53 | { 54 | m_Level = 0; 55 | m_All = false; 56 | m_Props = new List>(); 57 | foreach (var prop in props) 58 | { 59 | m_Props.Add(new List(prop.Split('/'))); 60 | } 61 | } 62 | 63 | bool CheckContained(string prop) 64 | { 65 | if (m_All) 66 | return true; 67 | foreach (var list in m_Props) 68 | { 69 | if (list.Count == m_Level+1) 70 | { 71 | if (list[m_Level] == prop) 72 | return true; 73 | if (list[m_Level] == "*") 74 | { 75 | m_All = true; // short-circuit all at this level 76 | return true; 77 | } 78 | } 79 | } 80 | return false; 81 | } 82 | 83 | public bool CheckStringValueInArray(string value) { return CheckContained(value); } 84 | public bool CheckKeyInDict(string key) { return CheckContained(key); } 85 | 86 | public bool CheckStringValueInDict(string key, string value) 87 | { 88 | foreach (var list in m_Props) 89 | { 90 | if (list.Count == m_Level + 2) 91 | { 92 | if ((list[m_Level] == "*" || list[m_Level] == key) && 93 | list[m_Level+1] == "*" || list[m_Level+1] == value) 94 | return true; 95 | } 96 | } 97 | return false; 98 | } 99 | 100 | public PropertyCommentChecker NextLevel(string prop) 101 | { 102 | var newList = new List>(); 103 | foreach (var list in m_Props) 104 | { 105 | if (list.Count <= m_Level+1) 106 | continue; 107 | if (list[m_Level] == "*" || list[m_Level] == prop) 108 | newList.Add(list); 109 | } 110 | return new PropertyCommentChecker(m_Level + 1, newList); 111 | } 112 | } 113 | 114 | class Serializer 115 | { 116 | public static PBXElementDict ParseTreeAST(TreeAST ast, TokenList tokens, string text) 117 | { 118 | var el = new PBXElementDict(); 119 | foreach (var kv in ast.values) 120 | { 121 | PBXElementString key = ParseIdentifierAST(kv.key, tokens, text); 122 | PBXElement value = ParseValueAST(kv.value, tokens, text); 123 | el[key.value] = value; 124 | } 125 | return el; 126 | } 127 | 128 | public static PBXElementArray ParseArrayAST(ArrayAST ast, TokenList tokens, string text) 129 | { 130 | var el = new PBXElementArray(); 131 | foreach (var v in ast.values) 132 | { 133 | el.values.Add(ParseValueAST(v, tokens, text)); 134 | } 135 | return el; 136 | } 137 | 138 | public static PBXElement ParseValueAST(ValueAST ast, TokenList tokens, string text) 139 | { 140 | if (ast is TreeAST) 141 | return ParseTreeAST((TreeAST)ast, tokens, text); 142 | if (ast is ArrayAST) 143 | return ParseArrayAST((ArrayAST)ast, tokens, text); 144 | if (ast is IdentifierAST) 145 | return ParseIdentifierAST((IdentifierAST)ast, tokens, text); 146 | return null; 147 | } 148 | 149 | public static PBXElementString ParseIdentifierAST(IdentifierAST ast, TokenList tokens, string text) 150 | { 151 | Token tok = tokens[ast.value]; 152 | string value; 153 | switch (tok.type) 154 | { 155 | case TokenType.String: 156 | value = text.Substring(tok.begin, tok.end - tok.begin); 157 | return new PBXElementString(value); 158 | case TokenType.QuotedString: 159 | value = text.Substring(tok.begin, tok.end - tok.begin); 160 | value = PBXStream.UnquoteString(value); 161 | return new PBXElementString(value); 162 | default: 163 | throw new Exception("Internal parser error"); 164 | } 165 | } 166 | 167 | static string k_Indent = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; 168 | 169 | static string GetIndent(int indent) 170 | { 171 | return k_Indent.Substring(0, indent); 172 | } 173 | 174 | static void WriteStringImpl(StringBuilder sb, string s, bool comment, GUIDToCommentMap comments) 175 | { 176 | if (comment) 177 | comments.WriteStringBuilder(sb, s); 178 | else 179 | sb.Append(PBXStream.QuoteStringIfNeeded(s)); 180 | } 181 | 182 | public static void WriteDictKeyValue(StringBuilder sb, string key, PBXElement value, int indent, bool compact, 183 | PropertyCommentChecker checker, GUIDToCommentMap comments) 184 | { 185 | if (!compact) 186 | { 187 | sb.Append("\n"); 188 | sb.Append(GetIndent(indent)); 189 | } 190 | WriteStringImpl(sb, key, checker.CheckKeyInDict(key), comments); 191 | sb.Append(" = "); 192 | 193 | if (value is PBXElementString) 194 | WriteStringImpl(sb, value.AsString(), checker.CheckStringValueInDict(key, value.AsString()), comments); 195 | else if (value is PBXElementDict) 196 | WriteDict(sb, value.AsDict(), indent, compact, checker.NextLevel(key), comments); 197 | else if (value is PBXElementArray) 198 | WriteArray(sb, value.AsArray(), indent, compact, checker.NextLevel(key), comments); 199 | sb.Append(";"); 200 | if (compact) 201 | sb.Append(" "); 202 | } 203 | 204 | public static void WriteDict(StringBuilder sb, PBXElementDict el, int indent, bool compact, 205 | PropertyCommentChecker checker, GUIDToCommentMap comments) 206 | { 207 | sb.Append("{"); 208 | 209 | if (el.Contains("isa")) 210 | WriteDictKeyValue(sb, "isa", el["isa"], indent+1, compact, checker, comments); 211 | var keys = new List(el.values.Keys); 212 | keys.Sort(StringComparer.Ordinal); 213 | foreach (var key in keys) 214 | { 215 | if (key != "isa") 216 | WriteDictKeyValue(sb, key, el[key], indent+1, compact, checker, comments); 217 | } 218 | if (!compact) 219 | { 220 | sb.Append("\n"); 221 | sb.Append(GetIndent(indent)); 222 | } 223 | sb.Append("}"); 224 | } 225 | 226 | public static void WriteArray(StringBuilder sb, PBXElementArray el, int indent, bool compact, 227 | PropertyCommentChecker checker, GUIDToCommentMap comments) 228 | { 229 | sb.Append("("); 230 | foreach (var value in el.values) 231 | { 232 | if (!compact) 233 | { 234 | sb.Append("\n"); 235 | sb.Append(GetIndent(indent+1)); 236 | } 237 | 238 | if (value is PBXElementString) 239 | WriteStringImpl(sb, value.AsString(), checker.CheckStringValueInArray(value.AsString()), comments); 240 | else if (value is PBXElementDict) 241 | WriteDict(sb, value.AsDict(), indent+1, compact, checker.NextLevel("*"), comments); 242 | else if (value is PBXElementArray) 243 | WriteArray(sb, value.AsArray(), indent+1, compact, checker.NextLevel("*"), comments); 244 | sb.Append(","); 245 | if (compact) 246 | sb.Append(" "); 247 | } 248 | 249 | if (!compact) 250 | { 251 | sb.Append("\n"); 252 | sb.Append(GetIndent(indent)); 253 | } 254 | sb.Append(")"); 255 | } 256 | } 257 | 258 | } // namespace UnityEditor.iOS.Xcode 259 | 260 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/PBX/Serializer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: afe8316bf614347729fac3466d7c77f2 3 | timeCreated: 1496741691 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/PBX/Utils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Text.RegularExpressions; 5 | using System.IO; 6 | 7 | namespace ChillyRoom.UnityEditor.iOS.Xcode.PBX 8 | { 9 | internal class GUIDToCommentMap 10 | { 11 | private Dictionary m_Dict = new Dictionary(); 12 | 13 | public string this[string guid] 14 | { 15 | get { 16 | if (m_Dict.ContainsKey(guid)) 17 | return m_Dict[guid]; 18 | return null; 19 | } 20 | } 21 | 22 | public void Add(string guid, string comment) 23 | { 24 | if (m_Dict.ContainsKey(guid)) 25 | return; 26 | m_Dict.Add(guid, comment); 27 | } 28 | 29 | public void Remove(string guid) 30 | { 31 | m_Dict.Remove(guid); 32 | } 33 | 34 | public string Write(string guid) 35 | { 36 | string comment = this[guid]; 37 | if (comment == null) 38 | return guid; 39 | return String.Format("{0} /* {1} */", guid, comment); 40 | } 41 | 42 | public void WriteStringBuilder(StringBuilder sb, string guid) 43 | { 44 | string comment = this[guid]; 45 | if (comment == null) 46 | sb.Append(guid); 47 | else 48 | { 49 | // {0} /* {1} */ 50 | sb.Append(guid).Append(" /* ").Append(comment).Append(" */"); 51 | } 52 | } 53 | } 54 | 55 | internal class PBXGUID 56 | { 57 | internal delegate string GuidGenerator(); 58 | 59 | // We allow changing Guid generator to make testing of PBXProject possible 60 | private static GuidGenerator guidGenerator = DefaultGuidGenerator; 61 | 62 | internal static string DefaultGuidGenerator() 63 | { 64 | return Guid.NewGuid().ToString("N").Substring(8).ToUpper(); 65 | } 66 | 67 | internal static void SetGuidGenerator(GuidGenerator generator) 68 | { 69 | guidGenerator = generator; 70 | } 71 | 72 | // Generates a GUID. 73 | public static string Generate() 74 | { 75 | return guidGenerator(); 76 | } 77 | } 78 | 79 | internal class PBXRegex 80 | { 81 | public static string GuidRegexString = "[A-Fa-f0-9]{24}"; 82 | } 83 | 84 | internal class PBXStream 85 | { 86 | static bool DontNeedQuotes(string src) 87 | { 88 | // using a regex instead of explicit matching slows down common cases by 40% 89 | if (src.Length == 0) 90 | return false; 91 | 92 | bool hasSlash = false; 93 | for (int i = 0; i < src.Length; ++i) 94 | { 95 | char c = src[i]; 96 | if (Char.IsLetterOrDigit(c) || c == '.' || c == '*' || c == '_') 97 | continue; 98 | if (c == '/') 99 | { 100 | hasSlash = true; 101 | continue; 102 | } 103 | return false; 104 | } 105 | if (hasSlash) 106 | { 107 | if (src.Contains("//") || src.Contains("/*") || src.Contains("*/")) 108 | return false; 109 | } 110 | return true; 111 | } 112 | 113 | // Quotes the given string if it contains special characters. Note: if the string already 114 | // contains quotes, then they are escaped and the entire string quoted again 115 | public static string QuoteStringIfNeeded(string src) 116 | { 117 | if (DontNeedQuotes(src)) 118 | return src; 119 | return "\"" + src.Replace("\\", "\\\\").Replace("\"", "\\\"").Replace("\n", "\\n") + "\""; 120 | } 121 | 122 | // If the given string is quoted, removes the quotes and unescapes any quotes within the string 123 | public static string UnquoteString(string src) 124 | { 125 | if (!src.StartsWith("\"") || !src.EndsWith("\"")) 126 | return src; 127 | return src.Substring(1, src.Length - 2).Replace("\\\\", "\u569f").Replace("\\\"", "\"") 128 | .Replace("\\n", "\n").Replace("\u569f", "\\"); // U+569f is a rarely used Chinese character 129 | } 130 | } 131 | 132 | internal enum PBXFileType 133 | { 134 | NotBuildable, 135 | Framework, 136 | Source, 137 | Resource, 138 | CopyFile 139 | } 140 | 141 | internal class FileTypeUtils 142 | { 143 | internal class FileTypeDesc 144 | { 145 | public FileTypeDesc(string typeName, PBXFileType type) 146 | { 147 | this.name = typeName; 148 | this.type = type; 149 | this.isExplicit = false; 150 | } 151 | 152 | public FileTypeDesc(string typeName, PBXFileType type, bool isExplicit) 153 | { 154 | this.name = typeName; 155 | this.type = type; 156 | this.isExplicit = isExplicit; 157 | } 158 | 159 | public string name; 160 | public PBXFileType type; 161 | public bool isExplicit; 162 | } 163 | 164 | private static readonly Dictionary types = 165 | new Dictionary 166 | { 167 | { "a", new FileTypeDesc("archive.ar", PBXFileType.Framework) }, 168 | { "app", new FileTypeDesc("wrapper.application", PBXFileType.NotBuildable, true) }, 169 | { "appex", new FileTypeDesc("wrapper.app-extension", PBXFileType.CopyFile) }, 170 | { "bin", new FileTypeDesc("archive.macbinary", PBXFileType.Resource) }, 171 | { "s", new FileTypeDesc("sourcecode.asm", PBXFileType.Source) }, 172 | { "c", new FileTypeDesc("sourcecode.c.c", PBXFileType.Source) }, 173 | { "cc", new FileTypeDesc("sourcecode.cpp.cpp", PBXFileType.Source) }, 174 | { "cpp", new FileTypeDesc("sourcecode.cpp.cpp", PBXFileType.Source) }, 175 | { "swift", new FileTypeDesc("sourcecode.swift", PBXFileType.Source) }, 176 | { "dll", new FileTypeDesc("file", PBXFileType.NotBuildable) }, 177 | { "framework", new FileTypeDesc("wrapper.framework", PBXFileType.Framework) }, 178 | { "h", new FileTypeDesc("sourcecode.c.h", PBXFileType.NotBuildable) }, 179 | { "pch", new FileTypeDesc("sourcecode.c.h", PBXFileType.NotBuildable) }, 180 | { "icns", new FileTypeDesc("image.icns", PBXFileType.Resource) }, 181 | { "xcassets", new FileTypeDesc("folder.assetcatalog", PBXFileType.Resource) }, 182 | { "inc", new FileTypeDesc("sourcecode.inc", PBXFileType.NotBuildable) }, 183 | { "m", new FileTypeDesc("sourcecode.c.objc", PBXFileType.Source) }, 184 | { "mm", new FileTypeDesc("sourcecode.cpp.objcpp", PBXFileType.Source ) }, 185 | { "nib", new FileTypeDesc("wrapper.nib", PBXFileType.Resource) }, 186 | { "plist", new FileTypeDesc("text.plist.xml", PBXFileType.Resource) }, 187 | { "png", new FileTypeDesc("image.png", PBXFileType.Resource) }, 188 | { "rtf", new FileTypeDesc("text.rtf", PBXFileType.Resource) }, 189 | { "tiff", new FileTypeDesc("image.tiff", PBXFileType.Resource) }, 190 | { "txt", new FileTypeDesc("text", PBXFileType.Resource) }, 191 | { "json", new FileTypeDesc("text.json", PBXFileType.Resource) }, 192 | { "xcodeproj", new FileTypeDesc("wrapper.pb-project", PBXFileType.NotBuildable) }, 193 | { "xib", new FileTypeDesc("file.xib", PBXFileType.Resource) }, 194 | { "strings", new FileTypeDesc("text.plist.strings", PBXFileType.Resource) }, 195 | { "storyboard",new FileTypeDesc("file.storyboard", PBXFileType.Resource) }, 196 | { "bundle", new FileTypeDesc("wrapper.plug-in", PBXFileType.Resource) }, 197 | { "dylib", new FileTypeDesc("compiled.mach-o.dylib", PBXFileType.Framework) }, 198 | { "tbd", new FileTypeDesc("sourcecode.text-based-dylib-definition", PBXFileType.Framework) } 199 | }; 200 | 201 | public static string TrimExtension(string ext) 202 | { 203 | return ext.TrimStart('.'); 204 | } 205 | 206 | public static bool IsKnownExtension(string ext) 207 | { 208 | ext = TrimExtension(ext); 209 | return types.ContainsKey(ext); 210 | } 211 | 212 | internal static bool IsFileTypeExplicit(string ext) 213 | { 214 | ext = TrimExtension(ext); 215 | if (types.ContainsKey(ext)) 216 | return types[ext].isExplicit; 217 | return false; 218 | } 219 | 220 | public static PBXFileType GetFileType(string ext, bool isFolderRef) 221 | { 222 | ext = TrimExtension(ext); 223 | if (isFolderRef) 224 | return PBXFileType.Resource; 225 | if (!types.ContainsKey(ext)) 226 | return PBXFileType.Resource; 227 | return types[ext].type; 228 | } 229 | 230 | public static string GetTypeName(string ext) 231 | { 232 | ext = TrimExtension(ext); 233 | if (types.ContainsKey(ext)) 234 | return types[ext].name; 235 | // Xcode actually checks the file contents to determine the file type. 236 | // Text files have "text" type and all other files have "file" type. 237 | // Since we can't reasonably determine whether the file in question is 238 | // a text file, we just take the safe route and return "file" type. 239 | return "file"; 240 | } 241 | 242 | public static bool IsBuildableFile(string ext) 243 | { 244 | ext = TrimExtension(ext); 245 | if (!types.ContainsKey(ext)) 246 | return true; 247 | if (types[ext].type != PBXFileType.NotBuildable) 248 | return true; 249 | return false; 250 | } 251 | 252 | public static bool IsBuildable(string ext, bool isFolderReference) 253 | { 254 | ext = TrimExtension(ext); 255 | if (isFolderReference) 256 | return true; 257 | return IsBuildableFile(ext); 258 | } 259 | 260 | private static readonly Dictionary sourceTree = new Dictionary 261 | { 262 | { PBXSourceTree.Absolute, "" }, 263 | { PBXSourceTree.Group, "" }, 264 | { PBXSourceTree.Build, "BUILT_PRODUCTS_DIR" }, 265 | { PBXSourceTree.Developer, "DEVELOPER_DIR" }, 266 | { PBXSourceTree.Sdk, "SDKROOT" }, 267 | { PBXSourceTree.Source, "SOURCE_ROOT" }, 268 | }; 269 | 270 | private static readonly Dictionary stringToSourceTreeMap = new Dictionary 271 | { 272 | { "", PBXSourceTree.Absolute }, 273 | { "", PBXSourceTree.Group }, 274 | { "BUILT_PRODUCTS_DIR", PBXSourceTree.Build }, 275 | { "DEVELOPER_DIR", PBXSourceTree.Developer }, 276 | { "SDKROOT", PBXSourceTree.Sdk }, 277 | { "SOURCE_ROOT", PBXSourceTree.Source }, 278 | }; 279 | 280 | internal static string SourceTreeDesc(PBXSourceTree tree) 281 | { 282 | return sourceTree[tree]; 283 | } 284 | 285 | // returns PBXSourceTree.Source on error 286 | internal static PBXSourceTree ParseSourceTree(string tree) 287 | { 288 | if (stringToSourceTreeMap.ContainsKey(tree)) 289 | return stringToSourceTreeMap[tree]; 290 | return PBXSourceTree.Source; 291 | } 292 | 293 | internal static List AllAbsoluteSourceTrees() 294 | { 295 | return new List{PBXSourceTree.Absolute, PBXSourceTree.Build, 296 | PBXSourceTree.Developer, PBXSourceTree.Sdk, PBXSourceTree.Source}; 297 | } 298 | } 299 | 300 | } // UnityEditor.iOS.Xcode 301 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/PBX/Utils.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8eafbccf2ded14760af588ffcb1ca0f5 3 | timeCreated: 1496741691 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/PBXCapabilityType.cs: -------------------------------------------------------------------------------- 1 | namespace ChillyRoom.UnityEditor.iOS.Xcode 2 | { 3 | /// 4 | /// List of all the capabilities available. 5 | /// 6 | public sealed class PBXCapabilityType 7 | { 8 | public static readonly PBXCapabilityType ApplePay = new PBXCapabilityType ("com.apple.ApplePay", true); 9 | public static readonly PBXCapabilityType AppGroups = new PBXCapabilityType ("com.apple.ApplicationGroups.iOS", true); 10 | public static readonly PBXCapabilityType AssociatedDomains = new PBXCapabilityType ("com.apple.SafariKeychain", true); 11 | public static readonly PBXCapabilityType BackgroundModes = new PBXCapabilityType ("com.apple.BackgroundModes", false); 12 | public static readonly PBXCapabilityType DataProtection = new PBXCapabilityType ("com.apple.DataProtection", true); 13 | public static readonly PBXCapabilityType GameCenter = new PBXCapabilityType ("com.apple.GameCenter", false, "GameKit.framework"); 14 | public static readonly PBXCapabilityType HealthKit = new PBXCapabilityType ("com.apple.HealthKit", true, "HealthKit.framework"); 15 | public static readonly PBXCapabilityType HomeKit = new PBXCapabilityType ("com.apple.HomeKit", true, "HomeKit.framework"); 16 | public static readonly PBXCapabilityType iCloud = new PBXCapabilityType("com.apple.iCloud", true, "CloudKit.framework", true); 17 | public static readonly PBXCapabilityType InAppPurchase = new PBXCapabilityType ("com.apple.InAppPurchase", false); 18 | public static readonly PBXCapabilityType InterAppAudio = new PBXCapabilityType ("com.apple.InterAppAudio", true, "AudioToolbox.framework"); 19 | public static readonly PBXCapabilityType KeychainSharing = new PBXCapabilityType ("com.apple.KeychainSharing", true); 20 | public static readonly PBXCapabilityType Maps = new PBXCapabilityType("com.apple.Maps.iOS", false, "MapKit.framework"); 21 | public static readonly PBXCapabilityType PersonalVPN = new PBXCapabilityType("com.apple.VPNLite", true, "NetworkExtension.framework"); 22 | public static readonly PBXCapabilityType PushNotifications = new PBXCapabilityType ("com.apple.Push", true); 23 | public static readonly PBXCapabilityType Siri = new PBXCapabilityType ("com.apple.Siri", true); 24 | public static readonly PBXCapabilityType Wallet = new PBXCapabilityType ("com.apple.Wallet", true, "PassKit.framework"); 25 | public static readonly PBXCapabilityType WirelessAccessoryConfiguration = new PBXCapabilityType("com.apple.WAC", true, "ExternalAccessory.framework"); 26 | 27 | private readonly string m_ID; 28 | private readonly bool m_RequiresEntitlements; 29 | private readonly string m_Framework; 30 | private readonly bool m_OptionalFramework; 31 | 32 | public bool optionalFramework 33 | { 34 | get { return m_OptionalFramework; } 35 | } 36 | 37 | public string framework 38 | { 39 | get { return m_Framework; } 40 | } 41 | 42 | public string id 43 | { 44 | get { return m_ID; } 45 | } 46 | 47 | public bool requiresEntitlements 48 | { 49 | get { return m_RequiresEntitlements; } 50 | } 51 | 52 | public struct TargetCapabilityPair 53 | { 54 | public string targetGuid; 55 | public PBXCapabilityType capability; 56 | 57 | public TargetCapabilityPair(string guid, PBXCapabilityType type) 58 | { 59 | targetGuid = guid; 60 | capability = type; 61 | } 62 | } 63 | 64 | /// 65 | /// This private object represents what a capability changes in the PBXProject file 66 | /// 67 | /// The string used in the PBXProject file to identify the capability and mark it as enabled. 68 | /// This capability requires an entitlements file therefore we need to add this entitlements file to the code signing entitlement. 69 | /// Specify which framework need to be added to the project for this capability, if "" no framework are added. 70 | /// Some capability (right now only iCloud) adds a framework, not all the time but just when some option are checked 71 | /// this parameter indicates if one of them is checked. 72 | private PBXCapabilityType(string _id, bool _requiresEntitlements, string _framework = "", bool _optionalFramework = false) 73 | { 74 | m_ID = _id; 75 | m_RequiresEntitlements = _requiresEntitlements; 76 | m_Framework = _framework; 77 | m_OptionalFramework = _optionalFramework; 78 | } 79 | 80 | public static PBXCapabilityType StringToPBXCapabilityType(string cap) 81 | { 82 | switch (cap) 83 | { 84 | case "com.apple.ApplePay": 85 | return ApplePay; 86 | case "com.apple.ApplicationGroups.iOS": 87 | return AppGroups; 88 | case "com.apple.SafariKeychain": 89 | return AssociatedDomains; 90 | case "com.apple.BackgroundModes": 91 | return BackgroundModes; 92 | case "com.apple.DataProtection": 93 | return DataProtection; 94 | case "com.apple.GameCenter": 95 | return GameCenter; 96 | case "com.apple.HealthKit": 97 | return HealthKit; 98 | case "com.apple.HomeKit": 99 | return HomeKit; 100 | case "com.apple.iCloud": 101 | return iCloud; 102 | case "com.apple.InAppPurchase": 103 | return InAppPurchase; 104 | case "com.apple.InterAppAudio": 105 | return InterAppAudio; 106 | case "com.apple.KeychainSharing": 107 | return KeychainSharing; 108 | case "com.apple.Maps.iOS": 109 | return Maps; 110 | case "com.apple.VPNLite": 111 | return PersonalVPN; 112 | case "com.apple.Push": 113 | return PushNotifications; 114 | case "com.apple.Siri": 115 | return Siri; 116 | case "com.apple.Wallet": 117 | return Wallet; 118 | case "WAC": 119 | return WirelessAccessoryConfiguration; 120 | default: 121 | return null; 122 | } 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/PBXCapabilityType.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 71f2dd6273cda4741b9b3bac41a9b765 3 | timeCreated: 1496741691 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/PBXPath.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Text.RegularExpressions; 5 | using System.IO; 6 | 7 | namespace ChillyRoom.UnityEditor.iOS.Xcode 8 | { 9 | internal class PBXPath 10 | { 11 | /// Replaces '\' with '/'. We need to apply this function to all paths that come from the user 12 | /// of the API because we store paths to pbxproj and on windows we may get path with '\' slashes 13 | /// instead of '/' slashes 14 | public static string FixSlashes(string path) 15 | { 16 | if (path == null) 17 | return null; 18 | return path.Replace('\\', '/'); 19 | } 20 | 21 | public static void Combine(string path1, PBXSourceTree tree1, string path2, PBXSourceTree tree2, 22 | out string resPath, out PBXSourceTree resTree) 23 | { 24 | if (tree2 == PBXSourceTree.Group) 25 | { 26 | resPath = Combine(path1, path2); 27 | resTree = tree1; 28 | return; 29 | } 30 | 31 | resPath = path2; 32 | resTree = tree2; 33 | } 34 | 35 | // Combines two paths 36 | public static string Combine(string path1, string path2) 37 | { 38 | if (path2.StartsWith("/")) 39 | return path2; 40 | if (path1.EndsWith("/")) 41 | return path1 + path2; 42 | if (path1 == "") 43 | return path2; 44 | if (path2 == "") 45 | return path1; 46 | return path1 + "/" + path2; 47 | } 48 | 49 | public static string GetDirectory(string path) 50 | { 51 | path = path.TrimEnd('/'); 52 | int pos = path.LastIndexOf('/'); 53 | if (pos == -1) 54 | return ""; 55 | else 56 | return path.Substring(0, pos); 57 | } 58 | 59 | public static string GetCurrentDirectory() 60 | { 61 | if (Environment.OSVersion.Platform != PlatformID.MacOSX && 62 | Environment.OSVersion.Platform != PlatformID.Unix) 63 | { 64 | throw new Exception("PBX project compatible current directory can only obtained on OSX"); 65 | } 66 | 67 | string path = Directory.GetCurrentDirectory(); 68 | path = FixSlashes(path); 69 | if (!IsPathRooted(path)) 70 | return "/" + path; 71 | return path; 72 | } 73 | 74 | public static string GetFilename(string path) 75 | { 76 | int pos = path.LastIndexOf('/'); 77 | if (pos == -1) 78 | return path; 79 | else 80 | return path.Substring(pos + 1); 81 | } 82 | 83 | public static bool IsPathRooted(string path) 84 | { 85 | if (path == null || path.Length == 0) 86 | return false; 87 | return path[0] == '/'; 88 | } 89 | 90 | public static string GetFullPath(string path) 91 | { 92 | if (IsPathRooted(path)) 93 | return path; 94 | else 95 | return Combine(GetCurrentDirectory(), path); 96 | } 97 | 98 | public static string[] Split(string path) 99 | { 100 | if (string.IsNullOrEmpty(path)) 101 | return new string[]{}; 102 | return path.Split(new[]{'/'}, StringSplitOptions.RemoveEmptyEntries); 103 | } 104 | } 105 | 106 | } // UnityEditor.iOS.Xcode 107 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/PBXPath.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 57be5de7dcd844631b3e835186497c25 3 | timeCreated: 1496741691 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/PBXProject.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5923416dbf32e48428afbeee2b4eb48e 3 | timeCreated: 1496741691 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/PBXProjectData.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 54c86bc46b87645c78e5b211a0eeada5 3 | timeCreated: 1496741691 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/PBXProjectExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Text; 3 | using System.Text.RegularExpressions; 4 | using System.IO; 5 | using System; 6 | using ChillyRoom.UnityEditor.iOS.Xcode.PBX; 7 | 8 | namespace ChillyRoom.UnityEditor.iOS.Xcode.Extensions 9 | { 10 | /* This class implements a number of static methods for performing common tasks 11 | on xcode projects. 12 | TODO: Make sure enough stuff is exposed so that it's possible to perform the tasks 13 | without using internal APIs 14 | */ 15 | public static class PBXProjectExtensions 16 | { 17 | // Create a wrapper class so that collection initializers work and we can have a 18 | // compact notation. Note that we can't use Dictionary because the keys may be duplicate 19 | internal class FlagList : List> 20 | { 21 | public void Add(string flag, string value) 22 | { 23 | Add(new KeyValuePair(flag, value)); 24 | } 25 | } 26 | 27 | internal static FlagList appExtensionReleaseBuildFlags = new FlagList 28 | { 29 | // { "INFOPLIST_FILE", }, 30 | { "LD_RUNPATH_SEARCH_PATHS", "$(inherited)" }, 31 | { "LD_RUNPATH_SEARCH_PATHS", "@executable_path/Frameworks" }, 32 | { "LD_RUNPATH_SEARCH_PATHS", "@executable_path/../../Frameworks" }, 33 | // { "PRODUCT_BUNDLE_IDENTIFIER", "" }, 34 | { "PRODUCT_NAME", "$(TARGET_NAME)" }, 35 | { "SKIP_INSTALL", "YES" }, 36 | }; 37 | 38 | internal static FlagList appExtensionDebugBuildFlags = new FlagList 39 | { 40 | // { "INFOPLIST_FILE", }, 41 | { "LD_RUNPATH_SEARCH_PATHS", "$(inherited)" }, 42 | { "LD_RUNPATH_SEARCH_PATHS", "@executable_path/Frameworks" }, 43 | { "LD_RUNPATH_SEARCH_PATHS", "@executable_path/../../Frameworks" }, 44 | // { "PRODUCT_BUNDLE_IDENTIFIER", "" }, 45 | { "PRODUCT_NAME", "$(TARGET_NAME)" }, 46 | { "SKIP_INSTALL", "YES" }, 47 | }; 48 | 49 | internal static FlagList watchExtensionReleaseBuildFlags = new FlagList 50 | { 51 | { "ASSETCATALOG_COMPILER_COMPLICATION_NAME", "Complication" }, 52 | { "CLANG_ANALYZER_NONNULL", "YES" }, 53 | { "CLANG_WARN_DOCUMENTATION_COMMENTS", "YES" }, 54 | { "CLANG_WARN_INFINITE_RECURSION", "YES" }, 55 | { "CLANG_WARN_SUSPICIOUS_MOVE", "YES" }, 56 | { "DEBUG_INFORMATION_FORMAT", "dwarf-with-dsym" }, 57 | { "GCC_NO_COMMON_BLOCKS", "YES" }, 58 | //{ "INFOPLIST_FILE", "" }, 59 | { "LD_RUNPATH_SEARCH_PATHS", "$(inherited)" }, 60 | { "LD_RUNPATH_SEARCH_PATHS", "@executable_path/Frameworks" }, 61 | { "LD_RUNPATH_SEARCH_PATHS", "@executable_path/../../Frameworks" }, 62 | // { "PRODUCT_BUNDLE_IDENTIFIER", "" }, 63 | { "PRODUCT_NAME", "${TARGET_NAME}" }, 64 | { "SDKROOT", "watchos" }, 65 | { "SKIP_INSTALL", "YES" }, 66 | { "TARGETED_DEVICE_FAMILY", "4" }, 67 | { "WATCHOS_DEPLOYMENT_TARGET", "3.1" }, 68 | // the following are needed to override project settings in Unity Xcode project 69 | { "ARCHS", "$(ARCHS_STANDARD)" }, 70 | { "SUPPORTED_PLATFORMS", "watchos" }, 71 | { "SUPPORTED_PLATFORMS", "watchsimulator" }, 72 | }; 73 | 74 | internal static FlagList watchExtensionDebugBuildFlags = new FlagList 75 | { 76 | { "ASSETCATALOG_COMPILER_COMPLICATION_NAME", "Complication" }, 77 | { "CLANG_ANALYZER_NONNULL", "YES" }, 78 | { "CLANG_WARN_DOCUMENTATION_COMMENTS", "YES" }, 79 | { "CLANG_WARN_INFINITE_RECURSION", "YES" }, 80 | { "CLANG_WARN_SUSPICIOUS_MOVE", "YES" }, 81 | { "DEBUG_INFORMATION_FORMAT", "dwarf" }, 82 | { "ENABLE_TESTABILITY", "YES" }, 83 | { "GCC_NO_COMMON_BLOCKS", "YES" }, 84 | // { "INFOPLIST_FILE", "" }, 85 | { "LD_RUNPATH_SEARCH_PATHS", "$(inherited)" }, 86 | { "LD_RUNPATH_SEARCH_PATHS", "@executable_path/Frameworks" }, 87 | { "LD_RUNPATH_SEARCH_PATHS", "@executable_path/../../Frameworks" }, 88 | // { "PRODUCT_BUNDLE_IDENTIFIER", "" }, 89 | { "PRODUCT_NAME", "${TARGET_NAME}" }, 90 | { "SDKROOT", "watchos" }, 91 | { "SKIP_INSTALL", "YES" }, 92 | { "TARGETED_DEVICE_FAMILY", "4" }, 93 | { "WATCHOS_DEPLOYMENT_TARGET", "3.1" }, 94 | // the following are needed to override project settings in Unity Xcode project 95 | { "ARCHS", "$(ARCHS_STANDARD)" }, 96 | { "SUPPORTED_PLATFORMS", "watchos" }, 97 | { "SUPPORTED_PLATFORMS", "watchsimulator" }, 98 | }; 99 | 100 | internal static FlagList watchAppReleaseBuildFlags = new FlagList 101 | { 102 | { "ASSETCATALOG_COMPILER_APPICON_NAME", "AppIcon" }, 103 | { "CLANG_ANALYZER_NONNULL", "YES" }, 104 | { "CLANG_WARN_DOCUMENTATION_COMMENTS", "YES" }, 105 | { "CLANG_WARN_INFINITE_RECURSION", "YES" }, 106 | { "CLANG_WARN_SUSPICIOUS_MOVE", "YES" }, 107 | { "DEBUG_INFORMATION_FORMAT", "dwarf-with-dsym" }, 108 | { "GCC_NO_COMMON_BLOCKS", "YES" }, 109 | //{ "IBSC_MODULE", "the extension target name with ' ' replaced with '_'" }, 110 | //{ "INFOPLIST_FILE", "" }, 111 | //{ "PRODUCT_BUNDLE_IDENTIFIER", "" }, 112 | { "PRODUCT_NAME", "$(TARGET_NAME)" }, 113 | { "SDKROOT", "watchos" }, 114 | { "SKIP_INSTALL", "YES" }, 115 | { "TARGETED_DEVICE_FAMILY", "4" }, 116 | { "WATCHOS_DEPLOYMENT_TARGET", "3.1" }, 117 | // the following are needed to override project settings in Unity Xcode project 118 | { "ARCHS", "$(ARCHS_STANDARD)" }, 119 | { "SUPPORTED_PLATFORMS", "watchos" }, 120 | { "SUPPORTED_PLATFORMS", "watchsimulator" }, 121 | }; 122 | 123 | internal static FlagList watchAppDebugBuildFlags = new FlagList 124 | { 125 | { "ASSETCATALOG_COMPILER_APPICON_NAME", "AppIcon" }, 126 | { "CLANG_ANALYZER_NONNULL", "YES" }, 127 | { "CLANG_WARN_DOCUMENTATION_COMMENTS", "YES" }, 128 | { "CLANG_WARN_INFINITE_RECURSION", "YES" }, 129 | { "CLANG_WARN_SUSPICIOUS_MOVE", "YES" }, 130 | { "DEBUG_INFORMATION_FORMAT", "dwarf" }, 131 | { "ENABLE_TESTABILITY", "YES" }, 132 | { "GCC_NO_COMMON_BLOCKS", "YES" }, 133 | //{ "IBSC_MODULE", "the extension target name with ' ' replaced with '_'" }, 134 | //{ "INFOPLIST_FILE", "" }, 135 | //{ "PRODUCT_BUNDLE_IDENTIFIER", "" }, 136 | { "PRODUCT_NAME", "$(TARGET_NAME)" }, 137 | { "SDKROOT", "watchos" }, 138 | { "SKIP_INSTALL", "YES" }, 139 | { "TARGETED_DEVICE_FAMILY", "4" }, 140 | { "WATCHOS_DEPLOYMENT_TARGET", "3.1" }, 141 | // the following are needed to override project settings in Unity Xcode project 142 | { "ARCHS", "$(ARCHS_STANDARD)" }, 143 | { "SUPPORTED_PLATFORMS", "watchos" }, 144 | { "SUPPORTED_PLATFORMS", "watchsimulator" }, 145 | }; 146 | 147 | static void SetBuildFlagsFromDict(this PBXProject proj, string configGuid, IEnumerable> data) 148 | { 149 | foreach (var kv in data) 150 | proj.AddBuildPropertyForConfig(configGuid, kv.Key, kv.Value); 151 | } 152 | 153 | internal static void SetDefaultAppExtensionReleaseBuildFlags(this PBXProject proj, string configGuid) 154 | { 155 | SetBuildFlagsFromDict(proj, configGuid, appExtensionReleaseBuildFlags); 156 | } 157 | 158 | internal static void SetDefaultAppExtensionDebugBuildFlags(this PBXProject proj, string configGuid) 159 | { 160 | SetBuildFlagsFromDict(proj, configGuid, appExtensionDebugBuildFlags); 161 | } 162 | 163 | internal static void SetDefaultWatchExtensionReleaseBuildFlags(this PBXProject proj, string configGuid) 164 | { 165 | SetBuildFlagsFromDict(proj, configGuid, watchExtensionReleaseBuildFlags); 166 | } 167 | 168 | internal static void SetDefaultWatchExtensionDebugBuildFlags(this PBXProject proj, string configGuid) 169 | { 170 | SetBuildFlagsFromDict(proj, configGuid, watchExtensionDebugBuildFlags); 171 | } 172 | 173 | internal static void SetDefaultWatchAppReleaseBuildFlags(this PBXProject proj, string configGuid) 174 | { 175 | SetBuildFlagsFromDict(proj, configGuid, watchAppReleaseBuildFlags); 176 | } 177 | 178 | internal static void SetDefaultWatchAppDebugBuildFlags(this PBXProject proj, string configGuid) 179 | { 180 | SetBuildFlagsFromDict(proj, configGuid, watchAppDebugBuildFlags); 181 | } 182 | 183 | /// 184 | /// Creates an app extension. 185 | /// 186 | /// The GUID of the new target. 187 | /// A project passed as this argument. 188 | /// The GUID of the main target to link the app to. 189 | /// The name of the app extension. 190 | /// The bundle ID of the app extension. The bundle ID must be 191 | /// prefixed with the parent app bundle ID. 192 | /// Path to the app extension Info.plist document. 193 | public static string AddAppExtension(this PBXProject proj, string mainTargetGuid, 194 | string name, string bundleId, string infoPlistPath) 195 | { 196 | string ext = ".appex"; 197 | var newTargetGuid = proj.AddTarget(name, ext, "com.apple.product-type.app-extension"); 198 | 199 | foreach (var configName in proj.BuildConfigNames()) 200 | { 201 | var configGuid = proj.BuildConfigByName(newTargetGuid, configName); 202 | if (configName.Contains("Debug")) 203 | SetDefaultAppExtensionDebugBuildFlags(proj, configGuid); 204 | else 205 | SetDefaultAppExtensionReleaseBuildFlags(proj, configGuid); 206 | proj.SetBuildPropertyForConfig(configGuid, "INFOPLIST_FILE", infoPlistPath); 207 | proj.SetBuildPropertyForConfig(configGuid, "PRODUCT_BUNDLE_IDENTIFIER", bundleId); 208 | } 209 | 210 | proj.AddSourcesBuildPhase(newTargetGuid); 211 | proj.AddResourcesBuildPhase(newTargetGuid); 212 | proj.AddFrameworksBuildPhase(newTargetGuid); 213 | string copyFilesPhaseGuid = proj.AddCopyFilesBuildPhase(mainTargetGuid, "Embed App Extensions", "", "13"); 214 | proj.AddFileToBuildSection(mainTargetGuid, copyFilesPhaseGuid, proj.GetTargetProductFileRef(newTargetGuid)); 215 | 216 | proj.AddTargetDependency(mainTargetGuid, newTargetGuid); 217 | 218 | return newTargetGuid; 219 | } 220 | 221 | /// 222 | /// Creates a watch application. 223 | /// 224 | /// The GUID of the new target. 225 | /// A project passed as this argument. 226 | /// The GUID of the main target to link the watch app to. 227 | /// The GUID of watch extension as returned by [[AddWatchExtension()]]. 228 | /// The name of the watch app. It must the same as the name of the watch extension. 229 | /// The bundle ID of the watch app. 230 | /// Path to the watch app Info.plist document. 231 | public static string AddWatchApp(this PBXProject proj, string mainTargetGuid, string watchExtensionTargetGuid, 232 | string name, string bundleId, string infoPlistPath) 233 | { 234 | var newTargetGuid = proj.AddTarget(name, ".app", "com.apple.product-type.application.watchapp2"); 235 | 236 | var isbcModuleName = proj.nativeTargets[watchExtensionTargetGuid].name.Replace(" ", "_"); 237 | 238 | foreach (var configName in proj.BuildConfigNames()) 239 | { 240 | var configGuid = proj.BuildConfigByName(newTargetGuid, configName); 241 | if (configName.Contains("Debug")) 242 | SetDefaultWatchAppDebugBuildFlags(proj, configGuid); 243 | else 244 | SetDefaultWatchAppReleaseBuildFlags(proj, configGuid); 245 | proj.SetBuildPropertyForConfig(configGuid, "PRODUCT_BUNDLE_IDENTIFIER", bundleId); 246 | proj.SetBuildPropertyForConfig(configGuid, "INFOPLIST_FILE", infoPlistPath); 247 | proj.SetBuildPropertyForConfig(configGuid, "IBSC_MODULE", isbcModuleName); 248 | } 249 | 250 | proj.AddResourcesBuildPhase(newTargetGuid); 251 | string copyFilesGuid = proj.AddCopyFilesBuildPhase(newTargetGuid, "Embed App Extensions", "", "13"); 252 | proj.AddFileToBuildSection(newTargetGuid, copyFilesGuid, proj.GetTargetProductFileRef(watchExtensionTargetGuid)); 253 | 254 | string copyWatchFilesGuid = proj.AddCopyFilesBuildPhase(mainTargetGuid, "Embed Watch Content", "$(CONTENTS_FOLDER_PATH)/Watch", "16"); 255 | proj.AddFileToBuildSection(mainTargetGuid, copyWatchFilesGuid, proj.GetTargetProductFileRef(newTargetGuid)); 256 | 257 | proj.AddTargetDependency(newTargetGuid, watchExtensionTargetGuid); 258 | proj.AddTargetDependency(mainTargetGuid, newTargetGuid); 259 | 260 | return newTargetGuid; 261 | } 262 | 263 | /// 264 | /// Creates a watch extension. 265 | /// 266 | /// The GUID of the new target. 267 | /// A project passed as this argument. 268 | /// The GUID of the main target to link the watch extension to. 269 | /// The name of the watch extension. 270 | /// The bundle ID of the watch extension. The bundle ID must be 271 | /// prefixed with the parent watch app bundle ID. 272 | /// Path to the watch extension Info.plist document. 273 | public static string AddWatchExtension(this PBXProject proj, string mainTarget, 274 | string name, string bundleId, string infoPlistPath) 275 | { 276 | var newTargetGuid = proj.AddTarget(name, ".appex", "com.apple.product-type.watchkit2-extension"); 277 | 278 | foreach (var configName in proj.BuildConfigNames()) 279 | { 280 | var configGuid = proj.BuildConfigByName(newTargetGuid, configName); 281 | if (configName.Contains("Debug")) 282 | SetDefaultWatchExtensionDebugBuildFlags(proj, configGuid); 283 | else 284 | SetDefaultWatchExtensionReleaseBuildFlags(proj, configGuid); 285 | proj.SetBuildPropertyForConfig(configGuid, "PRODUCT_BUNDLE_IDENTIFIER", bundleId); 286 | proj.SetBuildPropertyForConfig(configGuid, "INFOPLIST_FILE", infoPlistPath); 287 | } 288 | 289 | proj.AddSourcesBuildPhase(newTargetGuid); 290 | proj.AddResourcesBuildPhase(newTargetGuid); 291 | proj.AddFrameworksBuildPhase(newTargetGuid); 292 | 293 | return newTargetGuid; 294 | } 295 | } 296 | } // namespace UnityEditor.iOS.Xcode 297 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/PBXProjectExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b84f17869f54f4d7a952c9f63e5744d6 3 | timeCreated: 1496741691 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/PlistParser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Xml; 6 | using System.Xml.Linq; 7 | using System.Xml.XPath; 8 | 9 | namespace ChillyRoom.UnityEditor.iOS.Xcode 10 | { 11 | 12 | public class PlistElement 13 | { 14 | protected PlistElement() {} 15 | 16 | // convenience methods 17 | public string AsString() { return ((PlistElementString)this).value; } 18 | public int AsInteger() { return ((PlistElementInteger)this).value; } 19 | public bool AsBoolean() { return ((PlistElementBoolean)this).value; } 20 | public PlistElementArray AsArray() { return (PlistElementArray)this; } 21 | public PlistElementDict AsDict() { return (PlistElementDict)this; } 22 | 23 | public PlistElement this[string key] 24 | { 25 | get { return AsDict()[key]; } 26 | set { AsDict()[key] = value; } 27 | } 28 | } 29 | 30 | public class PlistElementString : PlistElement 31 | { 32 | public PlistElementString(string v) { value = v; } 33 | 34 | public string value; 35 | } 36 | 37 | public class PlistElementInteger : PlistElement 38 | { 39 | public PlistElementInteger(int v) { value = v; } 40 | 41 | public int value; 42 | } 43 | 44 | public class PlistElementBoolean : PlistElement 45 | { 46 | public PlistElementBoolean(bool v) { value = v; } 47 | 48 | public bool value; 49 | } 50 | 51 | public class PlistElementDict : PlistElement 52 | { 53 | public PlistElementDict() : base() {} 54 | 55 | private SortedDictionary m_PrivateValue = new SortedDictionary(); 56 | public IDictionary values { get { return m_PrivateValue; }} 57 | 58 | new public PlistElement this[string key] 59 | { 60 | get { 61 | if (values.ContainsKey(key)) 62 | return values[key]; 63 | return null; 64 | } 65 | set { this.values[key] = value; } 66 | } 67 | 68 | 69 | // convenience methods 70 | public void SetInteger(string key, int val) 71 | { 72 | values[key] = new PlistElementInteger(val); 73 | } 74 | 75 | public void SetString(string key, string val) 76 | { 77 | values[key] = new PlistElementString(val); 78 | } 79 | 80 | public void SetBoolean(string key, bool val) 81 | { 82 | values[key] = new PlistElementBoolean(val); 83 | } 84 | 85 | public PlistElementArray CreateArray(string key) 86 | { 87 | var v = new PlistElementArray(); 88 | values[key] = v; 89 | return v; 90 | } 91 | 92 | public PlistElementDict CreateDict(string key) 93 | { 94 | var v = new PlistElementDict(); 95 | values[key] = v; 96 | return v; 97 | } 98 | } 99 | 100 | public class PlistElementArray : PlistElement 101 | { 102 | public PlistElementArray() : base() {} 103 | public List values = new List(); 104 | 105 | // convenience methods 106 | public void AddString(string val) 107 | { 108 | values.Add(new PlistElementString(val)); 109 | } 110 | 111 | public void AddInteger(int val) 112 | { 113 | values.Add(new PlistElementInteger(val)); 114 | } 115 | 116 | public void AddBoolean(bool val) 117 | { 118 | values.Add(new PlistElementBoolean(val)); 119 | } 120 | 121 | public PlistElementArray AddArray() 122 | { 123 | var v = new PlistElementArray(); 124 | values.Add(v); 125 | return v; 126 | } 127 | 128 | public PlistElementDict AddDict() 129 | { 130 | var v = new PlistElementDict(); 131 | values.Add(v); 132 | return v; 133 | } 134 | } 135 | 136 | public class PlistDocument 137 | { 138 | public PlistElementDict root; 139 | public string version; 140 | 141 | public PlistDocument() 142 | { 143 | root = new PlistElementDict(); 144 | version = "1.0"; 145 | } 146 | 147 | // Parses a string that contains a XML file. No validation is done. 148 | internal static XDocument ParseXmlNoDtd(string text) 149 | { 150 | XmlReaderSettings settings = new XmlReaderSettings(); 151 | settings.ProhibitDtd = false; 152 | settings.XmlResolver = null; // prevent DTD download 153 | 154 | XmlReader xmlReader = XmlReader.Create(new StringReader(text), settings); 155 | return XDocument.Load(xmlReader); 156 | } 157 | 158 | // LINQ serializes XML DTD declaration with an explicit empty 'internal subset' 159 | // (a pair of square brackets at the end of Doctype declaration). 160 | // Even though this is valid XML, XCode does not like it, hence this workaround. 161 | internal static string CleanDtdToString(XDocument doc) 162 | { 163 | // LINQ does not support changing the DTD of existing XDocument instances, 164 | // so we create a dummy document for printing of the Doctype declaration. 165 | // A single dummy element is added to force LINQ not to omit the declaration. 166 | // Also, utf-8 encoding is forced since this is the encoding we use when writing to file in UpdateInfoPlist. 167 | if (doc.DocumentType != null) 168 | { 169 | XDocument tmpDoc = 170 | new XDocument(new XDeclaration("1.0", "utf-8", null), 171 | new XDocumentType(doc.DocumentType.Name, doc.DocumentType.PublicId, doc.DocumentType.SystemId, null), 172 | new XElement(doc.Root.Name)); 173 | return "" + tmpDoc.Declaration + "\n" + tmpDoc.DocumentType + "\n" + doc.Root; 174 | } 175 | else 176 | { 177 | XDocument tmpDoc = new XDocument(new XDeclaration("1.0", "utf-8", null), new XElement(doc.Root.Name)); 178 | return "" + tmpDoc.Declaration + Environment.NewLine + doc.Root; 179 | } 180 | } 181 | 182 | private static string GetText(XElement xml) 183 | { 184 | return String.Join("", xml.Nodes().OfType().Select(x => x.Value).ToArray()); 185 | } 186 | 187 | private static PlistElement ReadElement(XElement xml) 188 | { 189 | switch (xml.Name.LocalName) 190 | { 191 | case "dict": 192 | { 193 | List children = xml.Elements().ToList(); 194 | var el = new PlistElementDict(); 195 | 196 | if (children.Count % 2 == 1) 197 | throw new Exception("Malformed plist file"); 198 | 199 | for (int i = 0; i < children.Count - 1; i++) 200 | { 201 | if (children[i].Name != "key") 202 | throw new Exception("Malformed plist file"); 203 | string key = GetText(children[i]).Trim(); 204 | var newChild = ReadElement(children[i+1]); 205 | if (newChild != null) 206 | { 207 | i++; 208 | el[key] = newChild; 209 | } 210 | } 211 | return el; 212 | } 213 | case "array": 214 | { 215 | List children = xml.Elements().ToList(); 216 | var el = new PlistElementArray(); 217 | 218 | foreach (var childXml in children) 219 | { 220 | var newChild = ReadElement(childXml); 221 | if (newChild != null) 222 | el.values.Add(newChild); 223 | } 224 | return el; 225 | } 226 | case "string": 227 | return new PlistElementString(GetText(xml)); 228 | case "integer": 229 | { 230 | int r; 231 | if (int.TryParse(GetText(xml), out r)) 232 | return new PlistElementInteger(r); 233 | return null; 234 | } 235 | case "true": 236 | return new PlistElementBoolean(true); 237 | case "false": 238 | return new PlistElementBoolean(false); 239 | default: 240 | return null; 241 | } 242 | } 243 | 244 | public void Create() 245 | { 246 | const string doc = "" + 247 | "" + 248 | "" + 249 | "" + 250 | "" + 251 | ""; 252 | ReadFromString(doc); 253 | } 254 | 255 | public void ReadFromFile(string path) 256 | { 257 | ReadFromString(File.ReadAllText(path)); 258 | } 259 | 260 | public void ReadFromStream(TextReader tr) 261 | { 262 | ReadFromString(tr.ReadToEnd()); 263 | } 264 | 265 | public void ReadFromString(string text) 266 | { 267 | XDocument doc = ParseXmlNoDtd(text); 268 | version = (string) doc.Root.Attribute("version"); 269 | XElement xml = doc.XPathSelectElement("plist/dict"); 270 | 271 | var dict = ReadElement(xml); 272 | if (dict == null) 273 | throw new Exception("Error parsing plist file"); 274 | root = dict as PlistElementDict; 275 | if (root == null) 276 | throw new Exception("Malformed plist file"); 277 | } 278 | 279 | private static XElement WriteElement(PlistElement el) 280 | { 281 | if (el is PlistElementBoolean) 282 | { 283 | var realEl = el as PlistElementBoolean; 284 | return new XElement(realEl.value ? "true" : "false"); 285 | } 286 | if (el is PlistElementInteger) 287 | { 288 | var realEl = el as PlistElementInteger; 289 | return new XElement("integer", realEl.value.ToString()); 290 | } 291 | if (el is PlistElementString) 292 | { 293 | var realEl = el as PlistElementString; 294 | return new XElement("string", realEl.value); 295 | } 296 | if (el is PlistElementDict) 297 | { 298 | var realEl = el as PlistElementDict; 299 | var dictXml = new XElement("dict"); 300 | foreach (var kv in realEl.values) 301 | { 302 | var keyXml = new XElement("key", kv.Key); 303 | var valueXml = WriteElement(kv.Value); 304 | if (valueXml != null) 305 | { 306 | dictXml.Add(keyXml); 307 | dictXml.Add(valueXml); 308 | } 309 | } 310 | return dictXml; 311 | } 312 | if (el is PlistElementArray) 313 | { 314 | var realEl = el as PlistElementArray; 315 | var arrayXml = new XElement("array"); 316 | foreach (var v in realEl.values) 317 | { 318 | var elXml = WriteElement(v); 319 | if (elXml != null) 320 | arrayXml.Add(elXml); 321 | } 322 | return arrayXml; 323 | } 324 | return null; 325 | } 326 | 327 | public void WriteToFile(string path) 328 | { 329 | System.Text.Encoding utf8WithoutBom = new System.Text.UTF8Encoding(false); 330 | File.WriteAllText(path, WriteToString(), utf8WithoutBom); 331 | } 332 | 333 | public void WriteToStream(TextWriter tw) 334 | { 335 | tw.Write(WriteToString()); 336 | } 337 | 338 | public string WriteToString() 339 | { 340 | var el = WriteElement(root); 341 | var rootEl = new XElement("plist"); 342 | rootEl.Add(new XAttribute("version", version)); 343 | rootEl.Add(el); 344 | 345 | var doc = new XDocument(); 346 | doc.Add(rootEl); 347 | return CleanDtdToString(doc).Replace("\r\n", "\n"); 348 | } 349 | } 350 | 351 | } // namespace UnityEditor.iOS.XCode 352 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/PlistParser.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c2ed9743fe9634c808ea1dc01c20e01e 3 | timeCreated: 1496741691 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/Editor/Xcode/ProjectCapabilityManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2bfeebf480ee141979c8981b78c0a488 3 | timeCreated: 1496741691 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/iOS.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 77afa52f779dc41d9973eedade029110 3 | folderAsset: yes 4 | timeCreated: 1496821945 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/iOS/Base.lproj.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 444bc8da48ff944fe98ba992a59c94cd 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/iOS/Base.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* 2 | InfoPlist.strings 3 | Unity-iPhone 4 | 5 | Created by 버프스튜디오 on 2021/02/04. 6 | 7 | */ 8 | CFBundleDisplayName = "BaseAppName"; 9 | CFBundleName = "BaseAppName"; 10 | NSUserTrackingUsageDescription = "This BASE is Test of NSUserTrackingUsageDescription."; 11 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/iOS/Base.lproj/InfoPlist.strings.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 71848733719794c9283a19bfe5061e00 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/iOS/en.lproj.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: aad0f884e60724b578762b523bf52624 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/iOS/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* 2 | InfoPlist.strings 3 | Unity-iPhone 4 | 5 | Created by 버프스튜디오 on 2021/02/04. 6 | 7 | */ 8 | CFBundleDisplayName = "EngAppName"; 9 | CFBundleName = "EngAppName"; 10 | NSUserTrackingUsageDescription = "This is Test of NSUserTrackingUsageDescription."; 11 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/iOS/en.lproj/InfoPlist.strings.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3ae6c5ce6146a4c95b1db65ee01a7398 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/iOS/ja.lproj.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5034c7039f30b443b861c1a4677bf786 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/iOS/ja.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* 2 | InfoPlist.strings 3 | Unity-iPhone 4 | 5 | Created by 버프스튜디오 on 2021/02/04. 6 | 7 | */ 8 | CFBundleDisplayName = "あなたの名前"; 9 | CFBundleName = "あなたの名前"; 10 | NSUserTrackingUsageDescription = "これはテストNSUserTrackingUsageDescriptionです。"; 11 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/iOS/ja.lproj/InfoPlist.strings.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 161b67293b7044ca99161aa64c9ecc76 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/iOS/ko.lproj.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c6f6d19d0add54230a95599d1c3db474 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/iOS/ko.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* 2 | InfoPlist.strings 3 | Unity-iPhone 4 | 5 | Created by 버프스튜디오 on 2021/02/04. 6 | 7 | */ 8 | CFBundleDisplayName = "한글앱이름"; 9 | CFBundleName = "한글앱이름"; 10 | NSUserTrackingUsageDescription = "이것은 NSUserTrackingUsageDescription 테스트입니다."; 11 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/iOS/ko.lproj/InfoPlist.strings.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 864851f2941af4844a5dbd86881eded3 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/iOS/zh-Hans.lproj.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 260c971a2a7e2492080bb81c3e3f176f 3 | folderAsset: yes 4 | timeCreated: 1496742433 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/iOS/zh-Hans.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* 2 | InfoPlist.strings 3 | test 4 | 5 | Created by Zeyang Li on 6/6/17. 6 | Copyright © 2017 Zeyang Li. All rights reserved. 7 | */ 8 | CFBundleDisplayName = "应用名称"; 9 | CFBundleName = "应用名称"; 10 | NSUserTrackingUsageDescription = "这是NSUserTrackingUsageDescription的测试。"; 11 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/iOS/zh-Hans.lproj/InfoPlist.strings.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 03455b27543ac4a6da3bf3a74c353e07 3 | timeCreated: 1496742433 4 | licenseType: Free 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/iOS/zh-Hant.lproj.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: afca92fa1b3d34d0abb376269ad19f8c 3 | folderAsset: yes 4 | timeCreated: 1496742433 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/iOS/zh-Hant.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* 2 | InfoPlist.strings 3 | test 4 | 5 | Created by Zeyang Li on 6/6/17. 6 | Copyright © 2017 Zeyang Li. All rights reserved. 7 | */ 8 | CFBundleDisplayName = "應用名稱"; 9 | CFBundleName = "應用名稱"; 10 | NSUserTrackingUsageDescription = "這是NSUserTrackingUsageDescription的測試。"; 11 | -------------------------------------------------------------------------------- /Assets/10.Tools/NativeLocale/iOS/zh-Hant.lproj/InfoPlist.strings.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a5c0f1d054d1c4320b22169a52167bd0 3 | timeCreated: 1496742433 4 | licenseType: Free 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/10.Tools/PostBuildProcess.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5f126f5f1b925400d8527baa7dc9f7f9 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/10.Tools/PostBuildProcess/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 91769e9b372a7466db1bcd6cae762512 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/10.Tools/PostBuildProcess/Editor/XcodeSettingsPostProcesser.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using UnityEditor.Callbacks; 4 | using System.IO; 5 | using UnityEditor.iOS.Xcode; 6 | 7 | public class XcodeSettingsPostProcesser 8 | { 9 | [PostProcessBuild(9999)] 10 | public static void OnPostprocessBuild(BuildTarget target, string path) 11 | { 12 | if (target == BuildTarget.iOS) 13 | { 14 | OnIOSBuild(target, path); 15 | } 16 | } 17 | 18 | private static void OnIOSBuild(BuildTarget target, string path) 19 | { 20 | DoAddAppTrackingFramework(path); 21 | DoAddNSUserTrackingUsageDescriptionToInfo(path); 22 | DoAddSKAdNetworkItemsToInfo(path); 23 | NativeLocale.AddLocalizedStringsIOS(path, Path.Combine(Application.dataPath, "10.Tools/NativeLocale/iOS")); 24 | } 25 | 26 | private static void DoAddAppTrackingFramework(string projectPath) 27 | { 28 | string pbxProjectPath = PBXProject.GetPBXProjectPath(projectPath); 29 | PBXProject pbxProj = new PBXProject(); 30 | pbxProj.ReadFromFile(pbxProjectPath); 31 | 32 | #if UNITY_2019_3_OR_NEWER 33 | string target = pbxProj.GetUnityFrameworkTargetGuid(); 34 | #else 35 | string target = originalProj.TargetGuidByName("Unity-iPhone"); 36 | #endif 37 | pbxProj.AddFrameworkToProject(target, "AppTrackingTransparency.framework", false); 38 | pbxProj.WriteToFile(pbxProjectPath); 39 | 40 | } 41 | 42 | private static void DoAddNSUserTrackingUsageDescriptionToInfo(string projectPath) 43 | { 44 | // NSUserTrackingUsageDescription 45 | string Key = @"NSUserTrackingUsageDescription"; 46 | string infoPlistPath = Path.Combine(projectPath, "Info.plist"); 47 | 48 | PlistDocument plistDoc = new PlistDocument(); 49 | plistDoc.ReadFromFile(infoPlistPath); 50 | if (plistDoc.root != null) 51 | { 52 | TextAsset textAsset = AssetDatabase.LoadAssetAtPath("Assets/10.Tools/AppTrackingTransparency/Editor/NSUserTrackingUsageDescription.txt", typeof(TextAsset)) as TextAsset; 53 | 54 | plistDoc.root.SetString(Key, textAsset.text); 55 | 56 | 57 | plistDoc.WriteToFile(infoPlistPath); 58 | } 59 | else 60 | { 61 | Debug.LogError("Error: Can't open " + infoPlistPath); 62 | } 63 | 64 | } 65 | 66 | private static void DoAddSKAdNetworkItemsToInfo(string projectPath) 67 | { 68 | string infoPlistPath = Path.Combine(projectPath, "Info.plist"); 69 | 70 | PlistDocument plistDoc = new PlistDocument(); 71 | plistDoc.ReadFromFile(infoPlistPath); 72 | if (plistDoc.root != null) 73 | { 74 | 75 | PlistElementDict rootDict = plistDoc.root; 76 | 77 | PlistElement elementSKAdNetworkItems = rootDict["SKAdNetworkItems"]; 78 | 79 | if (null == elementSKAdNetworkItems) 80 | { 81 | rootDict["SKAdNetworkItems"] = new PlistElementArray(); 82 | 83 | elementSKAdNetworkItems = rootDict["SKAdNetworkItems"]; 84 | } 85 | else 86 | { 87 | PlistElementArray arrayAdNetworkItems = elementSKAdNetworkItems.AsArray(); 88 | int count = arrayAdNetworkItems.values.Count; 89 | arrayAdNetworkItems.values.RemoveRange(0, count); 90 | } 91 | 92 | PlistElementArray arrayItems = elementSKAdNetworkItems.AsArray(); 93 | 94 | PlistElementArray addAdNetworks = DoGetAdNetworks(); 95 | 96 | for (int i = 0; i < addAdNetworks.values.Count; i++) 97 | { 98 | PlistElementDict item = addAdNetworks.values[i] as PlistElementDict; 99 | arrayItems.values.Add(item); 100 | } 101 | 102 | plistDoc.WriteToFile(infoPlistPath); 103 | } 104 | else 105 | { 106 | Debug.LogError("Error: Can't open " + infoPlistPath); 107 | } 108 | 109 | } 110 | 111 | private static PlistElementArray DoGetAdNetworks() 112 | { 113 | 114 | string adNetworksPlistPath = Path.Combine(DoGetProjectFolder(), "Assets/10.Tools/AppTrackingTransparency/Editor/SKAdNetworkItems.plist"); 115 | 116 | PlistDocument plistDoc = new PlistDocument(); 117 | plistDoc.ReadFromFile(adNetworksPlistPath); 118 | 119 | PlistElement elementSKAdNetworkItems = plistDoc.root["SKAdNetworkItems"]; 120 | 121 | if (null == elementSKAdNetworkItems) 122 | { 123 | plistDoc.root["SKAdNetworkItems"] = new PlistElementArray(); 124 | 125 | elementSKAdNetworkItems = plistDoc.root["SKAdNetworkItems"]; 126 | } 127 | 128 | PlistElementArray arrayItems = elementSKAdNetworkItems.AsArray(); 129 | 130 | return arrayItems; 131 | 132 | 133 | } 134 | 135 | private static string DoGetProjectFolder() 136 | { 137 | int position = Application.dataPath.IndexOf("/Assets"); 138 | string projectPath = Application.dataPath.Substring(0, position); 139 | 140 | return projectPath; 141 | } 142 | 143 | } 144 | -------------------------------------------------------------------------------- /Assets/10.Tools/PostBuildProcess/Editor/XcodeSettingsPostProcesser.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 777d9d98c8cc74401891e2401fe521ea 3 | timeCreated: 1496809301 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Plugins.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 925b2ebd90160af44b547463f9ad889f 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Plugins/iOS.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 425badd5577714ab8937ef24d6aa7857 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Plugins/iOS/UnityAppTrackingTransparency.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @protocol DelegateCallBackRequestAppTrackingAuthorization 4 | - (void)ResultStatus:(int)myStatus; 5 | @end 6 | 7 | @interface UnityAppTrackingTransparency : NSObject 8 | + (int)AppTrackingAuthorizationStatus; 9 | + (void)RequestAppTrackingAuthorization:(id)myDelegateCallBack; 10 | + (void)SendStatusToDelegate:(id)myDelegateCallBack status:(int)myStatus; 11 | @end 12 | -------------------------------------------------------------------------------- /Assets/Plugins/iOS/UnityAppTrackingTransparency.h.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 641c5013ed438478aa719139d9a275c3 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 0 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | Any: 16 | second: 17 | enabled: 0 18 | settings: {} 19 | - first: 20 | Editor: Editor 21 | second: 22 | enabled: 0 23 | settings: 24 | DefaultValueInitialized: true 25 | - first: 26 | iPhone: iOS 27 | second: 28 | enabled: 1 29 | settings: 30 | AddToEmbeddedBinaries: false 31 | userData: 32 | assetBundleName: 33 | assetBundleVariant: 34 | -------------------------------------------------------------------------------- /Assets/Plugins/iOS/UnityAppTrackingTransparency.mm: -------------------------------------------------------------------------------- 1 | #import "UnityAppTrackingTransparency.h" 2 | #import 3 | 4 | @implementation UnityAppTrackingTransparency 5 | 6 | + (int) AppTrackingAuthorizationStatus 7 | { 8 | int result = 0; 9 | if (@available(iOS 14.5, *)) 10 | { 11 | result = (int)[ATTrackingManager trackingAuthorizationStatus]; 12 | } 13 | 14 | return result; 15 | } 16 | 17 | + (void)SendStatusToDelegate:(id)myDelegateCallBack status:(int)myStatus 18 | { 19 | if (myDelegateCallBack && [myDelegateCallBack respondsToSelector:@selector(ResultStatus:)]) 20 | { 21 | [myDelegateCallBack ResultStatus:myStatus]; 22 | } 23 | } 24 | 25 | 26 | + (void)RequestAppTrackingAuthorization:(id)myDelegateCallBack 27 | { 28 | if (@available(iOS 14.5, *)) 29 | { 30 | // ATT 알림을 통한 권한 요청 31 | [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus myStatus) 32 | { 33 | [self SendStatusToDelegate:myDelegateCallBack status:(int)myStatus]; 34 | 35 | }]; 36 | } 37 | else 38 | { 39 | [self SendStatusToDelegate:myDelegateCallBack status:0]; 40 | } 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /Assets/Plugins/iOS/UnityAppTrackingTransparency.mm.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cfb7cfec9113f4309b1ef469032e9aa4 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 0 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | Any: 16 | second: 17 | enabled: 0 18 | settings: {} 19 | - first: 20 | Editor: Editor 21 | second: 22 | enabled: 0 23 | settings: 24 | DefaultValueInitialized: true 25 | - first: 26 | iPhone: iOS 27 | second: 28 | enabled: 1 29 | settings: 30 | AddToEmbeddedBinaries: false 31 | userData: 32 | assetBundleName: 33 | assetBundleVariant: 34 | -------------------------------------------------------------------------------- /Assets/Plugins/iOS/UnityBridgeAppTrackingTransparency.h: -------------------------------------------------------------------------------- 1 | #import "UnityAppTrackingTransparency.h" 2 | 3 | extern "C" 4 | { 5 | int IOS_GetAppTrackingAuthorizationStatus(); 6 | void IOS_RequestAppTrackingAuthorization(); 7 | } 8 | -------------------------------------------------------------------------------- /Assets/Plugins/iOS/UnityBridgeAppTrackingTransparency.h.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: da7d6936400964d4da34a64c753da8ec 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 0 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | Any: 16 | second: 17 | enabled: 0 18 | settings: {} 19 | - first: 20 | Editor: Editor 21 | second: 22 | enabled: 0 23 | settings: 24 | DefaultValueInitialized: true 25 | - first: 26 | iPhone: iOS 27 | second: 28 | enabled: 1 29 | settings: 30 | AddToEmbeddedBinaries: false 31 | userData: 32 | assetBundleName: 33 | assetBundleVariant: 34 | -------------------------------------------------------------------------------- /Assets/Plugins/iOS/UnityBridgeAppTrackingTransparency.mm: -------------------------------------------------------------------------------- 1 | #import "UnityBridgeAppTrackingTransparency.h" 2 | 3 | @interface UnityBridgeAppTrackingTransparency : NSObject 4 | @end 5 | 6 | static UnityBridgeAppTrackingTransparency *_delegateBrigde = nil; 7 | 8 | int IOS_GetAppTrackingAuthorizationStatus() 9 | { 10 | return [UnityAppTrackingTransparency AppTrackingAuthorizationStatus]; 11 | } 12 | 13 | void IOS_RequestAppTrackingAuthorization() 14 | { 15 | if (!_delegateBrigde) 16 | { 17 | _delegateBrigde = [[UnityBridgeAppTrackingTransparency alloc] init]; 18 | } 19 | 20 | [UnityAppTrackingTransparency RequestAppTrackingAuthorization:_delegateBrigde]; 21 | } 22 | 23 | @implementation UnityBridgeAppTrackingTransparency 24 | 25 | -(void)ResultStatus:(int)myStatus 26 | { 27 | NSDictionary *jsonDic = @{ @"statusCode": [NSNumber numberWithInt:myStatus] }; 28 | NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonDic options:kNilOptions error:nil]; 29 | NSString* jsonDataStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; 30 | UnitySendMessage("AppTrackingAuthorization", "DoOnCallBackAuthorization", [jsonDataStr UTF8String]); 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /Assets/Plugins/iOS/UnityBridgeAppTrackingTransparency.mm.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c66b4214931e6403e88aab83f1628b32 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 0 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | Any: 16 | second: 17 | enabled: 0 18 | settings: {} 19 | - first: 20 | Editor: Editor 21 | second: 22 | enabled: 0 23 | settings: 24 | DefaultValueInitialized: true 25 | - first: 26 | iPhone: iOS 27 | second: 28 | enabled: 1 29 | settings: 30 | AddToEmbeddedBinaries: false 31 | userData: 32 | assetBundleName: 33 | assetBundleVariant: 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Packages/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "com.unity.2d.sprite": "1.0.0", 4 | "com.unity.2d.tilemap": "1.0.0", 5 | "com.unity.ads": "3.4.9", 6 | "com.unity.analytics": "3.3.5", 7 | "com.unity.collab-proxy": "1.2.16", 8 | "com.unity.ide.rider": "1.1.4", 9 | "com.unity.ide.vscode": "1.2.2", 10 | "com.unity.multiplayer-hlapi": "1.0.6", 11 | "com.unity.purchasing": "2.1.1", 12 | "com.unity.test-framework": "1.1.18", 13 | "com.unity.textmeshpro": "2.0.1", 14 | "com.unity.timeline": "1.2.6", 15 | "com.unity.ugui": "1.0.0", 16 | "com.unity.xr.legacyinputhelpers": "2.1.4", 17 | "com.unity.modules.ai": "1.0.0", 18 | "com.unity.modules.androidjni": "1.0.0", 19 | "com.unity.modules.animation": "1.0.0", 20 | "com.unity.modules.assetbundle": "1.0.0", 21 | "com.unity.modules.audio": "1.0.0", 22 | "com.unity.modules.cloth": "1.0.0", 23 | "com.unity.modules.director": "1.0.0", 24 | "com.unity.modules.imageconversion": "1.0.0", 25 | "com.unity.modules.imgui": "1.0.0", 26 | "com.unity.modules.jsonserialize": "1.0.0", 27 | "com.unity.modules.particlesystem": "1.0.0", 28 | "com.unity.modules.physics": "1.0.0", 29 | "com.unity.modules.physics2d": "1.0.0", 30 | "com.unity.modules.screencapture": "1.0.0", 31 | "com.unity.modules.terrain": "1.0.0", 32 | "com.unity.modules.terrainphysics": "1.0.0", 33 | "com.unity.modules.tilemap": "1.0.0", 34 | "com.unity.modules.ui": "1.0.0", 35 | "com.unity.modules.uielements": "1.0.0", 36 | "com.unity.modules.umbra": "1.0.0", 37 | "com.unity.modules.unityanalytics": "1.0.0", 38 | "com.unity.modules.unitywebrequest": "1.0.0", 39 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0", 40 | "com.unity.modules.unitywebrequestaudio": "1.0.0", 41 | "com.unity.modules.unitywebrequesttexture": "1.0.0", 42 | "com.unity.modules.unitywebrequestwww": "1.0.0", 43 | "com.unity.modules.vehicles": "1.0.0", 44 | "com.unity.modules.video": "1.0.0", 45 | "com.unity.modules.vr": "1.0.0", 46 | "com.unity.modules.wind": "1.0.0", 47 | "com.unity.modules.xr": "1.0.0" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Packages/packages-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "com.unity.2d.sprite": { 4 | "version": "1.0.0", 5 | "depth": 0, 6 | "source": "builtin", 7 | "dependencies": {} 8 | }, 9 | "com.unity.2d.tilemap": { 10 | "version": "1.0.0", 11 | "depth": 0, 12 | "source": "builtin", 13 | "dependencies": {} 14 | }, 15 | "com.unity.ads": { 16 | "version": "3.4.9", 17 | "depth": 0, 18 | "source": "registry", 19 | "dependencies": { 20 | "com.unity.ugui": "1.0.0" 21 | }, 22 | "url": "https://packages.unity.com" 23 | }, 24 | "com.unity.analytics": { 25 | "version": "3.3.5", 26 | "depth": 0, 27 | "source": "registry", 28 | "dependencies": { 29 | "com.unity.ugui": "1.0.0" 30 | }, 31 | "url": "https://packages.unity.com" 32 | }, 33 | "com.unity.collab-proxy": { 34 | "version": "1.2.16", 35 | "depth": 0, 36 | "source": "registry", 37 | "dependencies": {}, 38 | "url": "https://packages.unity.com" 39 | }, 40 | "com.unity.ext.nunit": { 41 | "version": "1.0.0", 42 | "depth": 1, 43 | "source": "registry", 44 | "dependencies": {}, 45 | "url": "https://packages.unity.com" 46 | }, 47 | "com.unity.ide.rider": { 48 | "version": "1.1.4", 49 | "depth": 0, 50 | "source": "registry", 51 | "dependencies": { 52 | "com.unity.test-framework": "1.1.1" 53 | }, 54 | "url": "https://packages.unity.com" 55 | }, 56 | "com.unity.ide.vscode": { 57 | "version": "1.2.2", 58 | "depth": 0, 59 | "source": "registry", 60 | "dependencies": {}, 61 | "url": "https://packages.unity.com" 62 | }, 63 | "com.unity.multiplayer-hlapi": { 64 | "version": "1.0.6", 65 | "depth": 0, 66 | "source": "registry", 67 | "dependencies": { 68 | "nuget.mono-cecil": "0.1.6-preview" 69 | }, 70 | "url": "https://packages.unity.com" 71 | }, 72 | "com.unity.purchasing": { 73 | "version": "2.1.1", 74 | "depth": 0, 75 | "source": "registry", 76 | "dependencies": { 77 | "com.unity.ugui": "1.0.0" 78 | }, 79 | "url": "https://packages.unity.com" 80 | }, 81 | "com.unity.test-framework": { 82 | "version": "1.1.18", 83 | "depth": 0, 84 | "source": "registry", 85 | "dependencies": { 86 | "com.unity.ext.nunit": "1.0.0", 87 | "com.unity.modules.imgui": "1.0.0", 88 | "com.unity.modules.jsonserialize": "1.0.0" 89 | }, 90 | "url": "https://packages.unity.com" 91 | }, 92 | "com.unity.textmeshpro": { 93 | "version": "2.0.1", 94 | "depth": 0, 95 | "source": "registry", 96 | "dependencies": { 97 | "com.unity.ugui": "1.0.0" 98 | }, 99 | "url": "https://packages.unity.com" 100 | }, 101 | "com.unity.timeline": { 102 | "version": "1.2.6", 103 | "depth": 0, 104 | "source": "registry", 105 | "dependencies": {}, 106 | "url": "https://packages.unity.com" 107 | }, 108 | "com.unity.ugui": { 109 | "version": "1.0.0", 110 | "depth": 0, 111 | "source": "builtin", 112 | "dependencies": { 113 | "com.unity.modules.ui": "1.0.0", 114 | "com.unity.modules.imgui": "1.0.0" 115 | } 116 | }, 117 | "com.unity.xr.legacyinputhelpers": { 118 | "version": "2.1.4", 119 | "depth": 0, 120 | "source": "registry", 121 | "dependencies": {}, 122 | "url": "https://packages.unity.com" 123 | }, 124 | "nuget.mono-cecil": { 125 | "version": "0.1.6-preview", 126 | "depth": 1, 127 | "source": "registry", 128 | "dependencies": {}, 129 | "url": "https://packages.unity.com" 130 | }, 131 | "com.unity.modules.ai": { 132 | "version": "1.0.0", 133 | "depth": 0, 134 | "source": "builtin", 135 | "dependencies": {} 136 | }, 137 | "com.unity.modules.androidjni": { 138 | "version": "1.0.0", 139 | "depth": 0, 140 | "source": "builtin", 141 | "dependencies": {} 142 | }, 143 | "com.unity.modules.animation": { 144 | "version": "1.0.0", 145 | "depth": 0, 146 | "source": "builtin", 147 | "dependencies": {} 148 | }, 149 | "com.unity.modules.assetbundle": { 150 | "version": "1.0.0", 151 | "depth": 0, 152 | "source": "builtin", 153 | "dependencies": {} 154 | }, 155 | "com.unity.modules.audio": { 156 | "version": "1.0.0", 157 | "depth": 0, 158 | "source": "builtin", 159 | "dependencies": {} 160 | }, 161 | "com.unity.modules.cloth": { 162 | "version": "1.0.0", 163 | "depth": 0, 164 | "source": "builtin", 165 | "dependencies": { 166 | "com.unity.modules.physics": "1.0.0" 167 | } 168 | }, 169 | "com.unity.modules.director": { 170 | "version": "1.0.0", 171 | "depth": 0, 172 | "source": "builtin", 173 | "dependencies": { 174 | "com.unity.modules.audio": "1.0.0", 175 | "com.unity.modules.animation": "1.0.0" 176 | } 177 | }, 178 | "com.unity.modules.imageconversion": { 179 | "version": "1.0.0", 180 | "depth": 0, 181 | "source": "builtin", 182 | "dependencies": {} 183 | }, 184 | "com.unity.modules.imgui": { 185 | "version": "1.0.0", 186 | "depth": 0, 187 | "source": "builtin", 188 | "dependencies": {} 189 | }, 190 | "com.unity.modules.jsonserialize": { 191 | "version": "1.0.0", 192 | "depth": 0, 193 | "source": "builtin", 194 | "dependencies": {} 195 | }, 196 | "com.unity.modules.particlesystem": { 197 | "version": "1.0.0", 198 | "depth": 0, 199 | "source": "builtin", 200 | "dependencies": {} 201 | }, 202 | "com.unity.modules.physics": { 203 | "version": "1.0.0", 204 | "depth": 0, 205 | "source": "builtin", 206 | "dependencies": {} 207 | }, 208 | "com.unity.modules.physics2d": { 209 | "version": "1.0.0", 210 | "depth": 0, 211 | "source": "builtin", 212 | "dependencies": {} 213 | }, 214 | "com.unity.modules.screencapture": { 215 | "version": "1.0.0", 216 | "depth": 0, 217 | "source": "builtin", 218 | "dependencies": { 219 | "com.unity.modules.imageconversion": "1.0.0" 220 | } 221 | }, 222 | "com.unity.modules.subsystems": { 223 | "version": "1.0.0", 224 | "depth": 1, 225 | "source": "builtin", 226 | "dependencies": { 227 | "com.unity.modules.jsonserialize": "1.0.0" 228 | } 229 | }, 230 | "com.unity.modules.terrain": { 231 | "version": "1.0.0", 232 | "depth": 0, 233 | "source": "builtin", 234 | "dependencies": {} 235 | }, 236 | "com.unity.modules.terrainphysics": { 237 | "version": "1.0.0", 238 | "depth": 0, 239 | "source": "builtin", 240 | "dependencies": { 241 | "com.unity.modules.physics": "1.0.0", 242 | "com.unity.modules.terrain": "1.0.0" 243 | } 244 | }, 245 | "com.unity.modules.tilemap": { 246 | "version": "1.0.0", 247 | "depth": 0, 248 | "source": "builtin", 249 | "dependencies": { 250 | "com.unity.modules.physics2d": "1.0.0" 251 | } 252 | }, 253 | "com.unity.modules.ui": { 254 | "version": "1.0.0", 255 | "depth": 0, 256 | "source": "builtin", 257 | "dependencies": {} 258 | }, 259 | "com.unity.modules.uielements": { 260 | "version": "1.0.0", 261 | "depth": 0, 262 | "source": "builtin", 263 | "dependencies": { 264 | "com.unity.modules.imgui": "1.0.0", 265 | "com.unity.modules.jsonserialize": "1.0.0" 266 | } 267 | }, 268 | "com.unity.modules.umbra": { 269 | "version": "1.0.0", 270 | "depth": 0, 271 | "source": "builtin", 272 | "dependencies": {} 273 | }, 274 | "com.unity.modules.unityanalytics": { 275 | "version": "1.0.0", 276 | "depth": 0, 277 | "source": "builtin", 278 | "dependencies": { 279 | "com.unity.modules.unitywebrequest": "1.0.0", 280 | "com.unity.modules.jsonserialize": "1.0.0" 281 | } 282 | }, 283 | "com.unity.modules.unitywebrequest": { 284 | "version": "1.0.0", 285 | "depth": 0, 286 | "source": "builtin", 287 | "dependencies": {} 288 | }, 289 | "com.unity.modules.unitywebrequestassetbundle": { 290 | "version": "1.0.0", 291 | "depth": 0, 292 | "source": "builtin", 293 | "dependencies": { 294 | "com.unity.modules.assetbundle": "1.0.0", 295 | "com.unity.modules.unitywebrequest": "1.0.0" 296 | } 297 | }, 298 | "com.unity.modules.unitywebrequestaudio": { 299 | "version": "1.0.0", 300 | "depth": 0, 301 | "source": "builtin", 302 | "dependencies": { 303 | "com.unity.modules.unitywebrequest": "1.0.0", 304 | "com.unity.modules.audio": "1.0.0" 305 | } 306 | }, 307 | "com.unity.modules.unitywebrequesttexture": { 308 | "version": "1.0.0", 309 | "depth": 0, 310 | "source": "builtin", 311 | "dependencies": { 312 | "com.unity.modules.unitywebrequest": "1.0.0", 313 | "com.unity.modules.imageconversion": "1.0.0" 314 | } 315 | }, 316 | "com.unity.modules.unitywebrequestwww": { 317 | "version": "1.0.0", 318 | "depth": 0, 319 | "source": "builtin", 320 | "dependencies": { 321 | "com.unity.modules.unitywebrequest": "1.0.0", 322 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0", 323 | "com.unity.modules.unitywebrequestaudio": "1.0.0", 324 | "com.unity.modules.audio": "1.0.0", 325 | "com.unity.modules.assetbundle": "1.0.0", 326 | "com.unity.modules.imageconversion": "1.0.0" 327 | } 328 | }, 329 | "com.unity.modules.vehicles": { 330 | "version": "1.0.0", 331 | "depth": 0, 332 | "source": "builtin", 333 | "dependencies": { 334 | "com.unity.modules.physics": "1.0.0" 335 | } 336 | }, 337 | "com.unity.modules.video": { 338 | "version": "1.0.0", 339 | "depth": 0, 340 | "source": "builtin", 341 | "dependencies": { 342 | "com.unity.modules.audio": "1.0.0", 343 | "com.unity.modules.ui": "1.0.0", 344 | "com.unity.modules.unitywebrequest": "1.0.0" 345 | } 346 | }, 347 | "com.unity.modules.vr": { 348 | "version": "1.0.0", 349 | "depth": 0, 350 | "source": "builtin", 351 | "dependencies": { 352 | "com.unity.modules.jsonserialize": "1.0.0", 353 | "com.unity.modules.physics": "1.0.0", 354 | "com.unity.modules.xr": "1.0.0" 355 | } 356 | }, 357 | "com.unity.modules.wind": { 358 | "version": "1.0.0", 359 | "depth": 0, 360 | "source": "builtin", 361 | "dependencies": {} 362 | }, 363 | "com.unity.modules.xr": { 364 | "version": "1.0.0", 365 | "depth": 0, 366 | "source": "builtin", 367 | "dependencies": { 368 | "com.unity.modules.physics": "1.0.0", 369 | "com.unity.modules.jsonserialize": "1.0.0", 370 | "com.unity.modules.subsystems": "1.0.0" 371 | } 372 | } 373 | } 374 | } 375 | -------------------------------------------------------------------------------- /ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!11 &1 4 | AudioManager: 5 | m_ObjectHideFlags: 0 6 | m_Volume: 1 7 | Rolloff Scale: 1 8 | Doppler Factor: 1 9 | Default Speaker Mode: 2 10 | m_SampleRate: 0 11 | m_DSPBufferSize: 1024 12 | m_VirtualVoiceCount: 512 13 | m_RealVoiceCount: 32 14 | m_SpatializerPlugin: 15 | m_AmbisonicDecoderPlugin: 16 | m_DisableAudio: 0 17 | m_VirtualizeEffects: 1 18 | -------------------------------------------------------------------------------- /ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!236 &1 4 | ClusterInputManager: 5 | m_ObjectHideFlags: 0 6 | m_Inputs: [] 7 | -------------------------------------------------------------------------------- /ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!55 &1 4 | PhysicsManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 8 7 | m_Gravity: {x: 0, y: -9.81, z: 0} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_BounceThreshold: 2 10 | m_SleepThreshold: 0.005 11 | m_DefaultContactOffset: 0.01 12 | m_DefaultSolverIterations: 6 13 | m_DefaultSolverVelocityIterations: 1 14 | m_QueriesHitBackfaces: 0 15 | m_QueriesHitTriggers: 1 16 | m_EnableAdaptiveForce: 0 17 | m_ClothInterCollisionDistance: 0 18 | m_ClothInterCollisionStiffness: 0 19 | m_ContactsGeneration: 1 20 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 21 | m_AutoSimulation: 1 22 | m_AutoSyncTransforms: 0 23 | m_ReuseCollisionCallbacks: 1 24 | m_ClothInterCollisionSettingsToggle: 0 25 | m_ContactPairsMode: 0 26 | m_BroadphaseType: 0 27 | m_WorldBounds: 28 | m_Center: {x: 0, y: 0, z: 0} 29 | m_Extent: {x: 250, y: 250, z: 250} 30 | m_WorldSubdivisions: 8 31 | -------------------------------------------------------------------------------- /ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1045 &1 4 | EditorBuildSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Scenes: 8 | - enabled: 1 9 | path: Assets/01.Scenes/SampleScene.unity 10 | guid: a0320b2cf50154fb1b1bddb7ce4ede96 11 | m_configObjects: {} 12 | -------------------------------------------------------------------------------- /ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!159 &1 4 | EditorSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 9 7 | m_ExternalVersionControlSupport: Visible Meta Files 8 | m_SerializationMode: 2 9 | m_LineEndingsForNewScripts: 2 10 | m_DefaultBehaviorMode: 0 11 | m_PrefabRegularEnvironment: {fileID: 0} 12 | m_PrefabUIEnvironment: {fileID: 0} 13 | m_SpritePackerMode: 0 14 | m_SpritePackerPaddingPower: 1 15 | m_EtcTextureCompressorBehavior: 1 16 | m_EtcTextureFastCompressor: 1 17 | m_EtcTextureNormalCompressor: 2 18 | m_EtcTextureBestCompressor: 4 19 | m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmref 20 | m_ProjectGenerationRootNamespace: 21 | m_CollabEditorSettings: 22 | inProgressEnabled: 1 23 | m_EnableTextureStreamingInEditMode: 1 24 | m_EnableTextureStreamingInPlayMode: 1 25 | m_AsyncShaderCompilation: 1 26 | m_EnterPlayModeOptionsEnabled: 0 27 | m_EnterPlayModeOptions: 3 28 | m_ShowLightmapResolutionOverlay: 1 29 | m_UseLegacyProbeSampleCount: 1 30 | m_AssetPipelineMode: 1 31 | m_CacheServerMode: 0 32 | m_CacheServerEndpoint: 33 | m_CacheServerNamespacePrefix: default 34 | m_CacheServerEnableDownload: 1 35 | m_CacheServerEnableUpload: 1 36 | -------------------------------------------------------------------------------- /ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!30 &1 4 | GraphicsSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 13 7 | m_Deferred: 8 | m_Mode: 1 9 | m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} 10 | m_DeferredReflections: 11 | m_Mode: 1 12 | m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} 13 | m_ScreenSpaceShadows: 14 | m_Mode: 1 15 | m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} 16 | m_LegacyDeferred: 17 | m_Mode: 1 18 | m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} 19 | m_DepthNormals: 20 | m_Mode: 1 21 | m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} 22 | m_MotionVectors: 23 | m_Mode: 1 24 | m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} 25 | m_LightHalo: 26 | m_Mode: 1 27 | m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} 28 | m_LensFlare: 29 | m_Mode: 1 30 | m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} 31 | m_AlwaysIncludedShaders: 32 | - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} 33 | - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} 34 | - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} 35 | - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} 36 | - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} 37 | - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} 38 | - {fileID: 10783, guid: 0000000000000000f000000000000000, type: 0} 39 | - {fileID: 16000, guid: 0000000000000000f000000000000000, type: 0} 40 | - {fileID: 17000, guid: 0000000000000000f000000000000000, type: 0} 41 | - {fileID: 16001, guid: 0000000000000000f000000000000000, type: 0} 42 | m_PreloadedShaders: [] 43 | m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, 44 | type: 0} 45 | m_CustomRenderPipeline: {fileID: 0} 46 | m_TransparencySortMode: 0 47 | m_TransparencySortAxis: {x: 0, y: 0, z: 1} 48 | m_DefaultRenderingPath: 1 49 | m_DefaultMobileRenderingPath: 1 50 | m_TierSettings: [] 51 | m_LightmapStripping: 0 52 | m_FogStripping: 0 53 | m_InstancingStripping: 0 54 | m_LightmapKeepPlain: 1 55 | m_LightmapKeepDirCombined: 1 56 | m_LightmapKeepDynamicPlain: 1 57 | m_LightmapKeepDynamicDirCombined: 1 58 | m_LightmapKeepShadowMask: 1 59 | m_LightmapKeepSubtractive: 1 60 | m_FogKeepLinear: 1 61 | m_FogKeepExp: 1 62 | m_FogKeepExp2: 1 63 | m_AlbedoSwatchInfos: [] 64 | m_LightsUseLinearIntensity: 0 65 | m_LightsUseColorTemperature: 0 66 | m_LogWhenShaderIsCompiled: 0 67 | m_AllowEnlightenSupportForUpgradedProject: 1 68 | -------------------------------------------------------------------------------- /ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!13 &1 4 | InputManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Axes: 8 | - serializedVersion: 3 9 | m_Name: Horizontal 10 | descriptiveName: 11 | descriptiveNegativeName: 12 | negativeButton: left 13 | positiveButton: right 14 | altNegativeButton: a 15 | altPositiveButton: d 16 | gravity: 3 17 | dead: 0.001 18 | sensitivity: 3 19 | snap: 1 20 | invert: 0 21 | type: 0 22 | axis: 0 23 | joyNum: 0 24 | - serializedVersion: 3 25 | m_Name: Vertical 26 | descriptiveName: 27 | descriptiveNegativeName: 28 | negativeButton: down 29 | positiveButton: up 30 | altNegativeButton: s 31 | altPositiveButton: w 32 | gravity: 3 33 | dead: 0.001 34 | sensitivity: 3 35 | snap: 1 36 | invert: 0 37 | type: 0 38 | axis: 0 39 | joyNum: 0 40 | - serializedVersion: 3 41 | m_Name: Fire1 42 | descriptiveName: 43 | descriptiveNegativeName: 44 | negativeButton: 45 | positiveButton: left ctrl 46 | altNegativeButton: 47 | altPositiveButton: mouse 0 48 | gravity: 1000 49 | dead: 0.001 50 | sensitivity: 1000 51 | snap: 0 52 | invert: 0 53 | type: 0 54 | axis: 0 55 | joyNum: 0 56 | - serializedVersion: 3 57 | m_Name: Fire2 58 | descriptiveName: 59 | descriptiveNegativeName: 60 | negativeButton: 61 | positiveButton: left alt 62 | altNegativeButton: 63 | altPositiveButton: mouse 1 64 | gravity: 1000 65 | dead: 0.001 66 | sensitivity: 1000 67 | snap: 0 68 | invert: 0 69 | type: 0 70 | axis: 0 71 | joyNum: 0 72 | - serializedVersion: 3 73 | m_Name: Fire3 74 | descriptiveName: 75 | descriptiveNegativeName: 76 | negativeButton: 77 | positiveButton: left shift 78 | altNegativeButton: 79 | altPositiveButton: mouse 2 80 | gravity: 1000 81 | dead: 0.001 82 | sensitivity: 1000 83 | snap: 0 84 | invert: 0 85 | type: 0 86 | axis: 0 87 | joyNum: 0 88 | - serializedVersion: 3 89 | m_Name: Jump 90 | descriptiveName: 91 | descriptiveNegativeName: 92 | negativeButton: 93 | positiveButton: space 94 | altNegativeButton: 95 | altPositiveButton: 96 | gravity: 1000 97 | dead: 0.001 98 | sensitivity: 1000 99 | snap: 0 100 | invert: 0 101 | type: 0 102 | axis: 0 103 | joyNum: 0 104 | - serializedVersion: 3 105 | m_Name: Mouse X 106 | descriptiveName: 107 | descriptiveNegativeName: 108 | negativeButton: 109 | positiveButton: 110 | altNegativeButton: 111 | altPositiveButton: 112 | gravity: 0 113 | dead: 0 114 | sensitivity: 0.1 115 | snap: 0 116 | invert: 0 117 | type: 1 118 | axis: 0 119 | joyNum: 0 120 | - serializedVersion: 3 121 | m_Name: Mouse Y 122 | descriptiveName: 123 | descriptiveNegativeName: 124 | negativeButton: 125 | positiveButton: 126 | altNegativeButton: 127 | altPositiveButton: 128 | gravity: 0 129 | dead: 0 130 | sensitivity: 0.1 131 | snap: 0 132 | invert: 0 133 | type: 1 134 | axis: 1 135 | joyNum: 0 136 | - serializedVersion: 3 137 | m_Name: Mouse ScrollWheel 138 | descriptiveName: 139 | descriptiveNegativeName: 140 | negativeButton: 141 | positiveButton: 142 | altNegativeButton: 143 | altPositiveButton: 144 | gravity: 0 145 | dead: 0 146 | sensitivity: 0.1 147 | snap: 0 148 | invert: 0 149 | type: 1 150 | axis: 2 151 | joyNum: 0 152 | - serializedVersion: 3 153 | m_Name: Horizontal 154 | descriptiveName: 155 | descriptiveNegativeName: 156 | negativeButton: 157 | positiveButton: 158 | altNegativeButton: 159 | altPositiveButton: 160 | gravity: 0 161 | dead: 0.19 162 | sensitivity: 1 163 | snap: 0 164 | invert: 0 165 | type: 2 166 | axis: 0 167 | joyNum: 0 168 | - serializedVersion: 3 169 | m_Name: Vertical 170 | descriptiveName: 171 | descriptiveNegativeName: 172 | negativeButton: 173 | positiveButton: 174 | altNegativeButton: 175 | altPositiveButton: 176 | gravity: 0 177 | dead: 0.19 178 | sensitivity: 1 179 | snap: 0 180 | invert: 1 181 | type: 2 182 | axis: 1 183 | joyNum: 0 184 | - serializedVersion: 3 185 | m_Name: Fire1 186 | descriptiveName: 187 | descriptiveNegativeName: 188 | negativeButton: 189 | positiveButton: joystick button 0 190 | altNegativeButton: 191 | altPositiveButton: 192 | gravity: 1000 193 | dead: 0.001 194 | sensitivity: 1000 195 | snap: 0 196 | invert: 0 197 | type: 0 198 | axis: 0 199 | joyNum: 0 200 | - serializedVersion: 3 201 | m_Name: Fire2 202 | descriptiveName: 203 | descriptiveNegativeName: 204 | negativeButton: 205 | positiveButton: joystick button 1 206 | altNegativeButton: 207 | altPositiveButton: 208 | gravity: 1000 209 | dead: 0.001 210 | sensitivity: 1000 211 | snap: 0 212 | invert: 0 213 | type: 0 214 | axis: 0 215 | joyNum: 0 216 | - serializedVersion: 3 217 | m_Name: Fire3 218 | descriptiveName: 219 | descriptiveNegativeName: 220 | negativeButton: 221 | positiveButton: joystick button 2 222 | altNegativeButton: 223 | altPositiveButton: 224 | gravity: 1000 225 | dead: 0.001 226 | sensitivity: 1000 227 | snap: 0 228 | invert: 0 229 | type: 0 230 | axis: 0 231 | joyNum: 0 232 | - serializedVersion: 3 233 | m_Name: Jump 234 | descriptiveName: 235 | descriptiveNegativeName: 236 | negativeButton: 237 | positiveButton: joystick button 3 238 | altNegativeButton: 239 | altPositiveButton: 240 | gravity: 1000 241 | dead: 0.001 242 | sensitivity: 1000 243 | snap: 0 244 | invert: 0 245 | type: 0 246 | axis: 0 247 | joyNum: 0 248 | - serializedVersion: 3 249 | m_Name: Submit 250 | descriptiveName: 251 | descriptiveNegativeName: 252 | negativeButton: 253 | positiveButton: return 254 | altNegativeButton: 255 | altPositiveButton: joystick button 0 256 | gravity: 1000 257 | dead: 0.001 258 | sensitivity: 1000 259 | snap: 0 260 | invert: 0 261 | type: 0 262 | axis: 0 263 | joyNum: 0 264 | - serializedVersion: 3 265 | m_Name: Submit 266 | descriptiveName: 267 | descriptiveNegativeName: 268 | negativeButton: 269 | positiveButton: enter 270 | altNegativeButton: 271 | altPositiveButton: space 272 | gravity: 1000 273 | dead: 0.001 274 | sensitivity: 1000 275 | snap: 0 276 | invert: 0 277 | type: 0 278 | axis: 0 279 | joyNum: 0 280 | - serializedVersion: 3 281 | m_Name: Cancel 282 | descriptiveName: 283 | descriptiveNegativeName: 284 | negativeButton: 285 | positiveButton: escape 286 | altNegativeButton: 287 | altPositiveButton: joystick button 1 288 | gravity: 1000 289 | dead: 0.001 290 | sensitivity: 1000 291 | snap: 0 292 | invert: 0 293 | type: 0 294 | axis: 0 295 | joyNum: 0 296 | -------------------------------------------------------------------------------- /ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!126 &1 4 | NavMeshProjectSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | areas: 8 | - name: Walkable 9 | cost: 1 10 | - name: Not Walkable 11 | cost: 1 12 | - name: Jump 13 | cost: 2 14 | - name: 15 | cost: 1 16 | - name: 17 | cost: 1 18 | - name: 19 | cost: 1 20 | - name: 21 | cost: 1 22 | - name: 23 | cost: 1 24 | - name: 25 | cost: 1 26 | - name: 27 | cost: 1 28 | - name: 29 | cost: 1 30 | - name: 31 | cost: 1 32 | - name: 33 | cost: 1 34 | - name: 35 | cost: 1 36 | - name: 37 | cost: 1 38 | - name: 39 | cost: 1 40 | - name: 41 | cost: 1 42 | - name: 43 | cost: 1 44 | - name: 45 | cost: 1 46 | - name: 47 | cost: 1 48 | - name: 49 | cost: 1 50 | - name: 51 | cost: 1 52 | - name: 53 | cost: 1 54 | - name: 55 | cost: 1 56 | - name: 57 | cost: 1 58 | - name: 59 | cost: 1 60 | - name: 61 | cost: 1 62 | - name: 63 | cost: 1 64 | - name: 65 | cost: 1 66 | - name: 67 | cost: 1 68 | - name: 69 | cost: 1 70 | - name: 71 | cost: 1 72 | m_LastAgentTypeID: -887442657 73 | m_Settings: 74 | - serializedVersion: 2 75 | agentTypeID: 0 76 | agentRadius: 0.5 77 | agentHeight: 2 78 | agentSlope: 45 79 | agentClimb: 0.75 80 | ledgeDropHeight: 0 81 | maxJumpAcrossDistance: 0 82 | minRegionArea: 2 83 | manualCellSize: 0 84 | cellSize: 0.16666667 85 | manualTileSize: 0 86 | tileSize: 256 87 | accuratePlacement: 0 88 | debug: 89 | m_Flags: 0 90 | m_SettingNames: 91 | - Humanoid 92 | -------------------------------------------------------------------------------- /ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!149 &1 4 | NetworkManager: 5 | m_ObjectHideFlags: 0 6 | m_DebugLevel: 0 7 | m_Sendrate: 15 8 | m_AssetToPrefab: {} 9 | -------------------------------------------------------------------------------- /ProjectSettings/PackageManagerSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &1 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 61 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_GameObject: {fileID: 0} 10 | m_Enabled: 1 11 | m_EditorHideFlags: 0 12 | m_Script: {fileID: 0} 13 | m_Name: 14 | m_EditorClassIdentifier: UnityEditor:UnityEditor.PackageManager.UI:PackageManagerProjectSettings 15 | m_ScopedRegistriesSettingsExpanded: 1 16 | oneTimeWarningShown: 0 17 | m_Registries: 18 | - m_Id: main 19 | m_Name: 20 | m_Url: https://packages.unity.com 21 | m_Scopes: [] 22 | m_IsDefault: 1 23 | m_UserSelectedRegistryName: 24 | m_UserAddingNewScopedRegistry: 0 25 | m_RegistryInfoDraft: 26 | m_ErrorMessage: 27 | m_Original: 28 | m_Id: 29 | m_Name: 30 | m_Url: 31 | m_Scopes: [] 32 | m_IsDefault: 0 33 | m_Modified: 0 34 | m_Name: 35 | m_Url: 36 | m_Scopes: 37 | - 38 | m_SelectedScopeIndex: 0 39 | -------------------------------------------------------------------------------- /ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!19 &1 4 | Physics2DSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 4 7 | m_Gravity: {x: 0, y: -9.81} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_VelocityIterations: 8 10 | m_PositionIterations: 3 11 | m_VelocityThreshold: 1 12 | m_MaxLinearCorrection: 0.2 13 | m_MaxAngularCorrection: 8 14 | m_MaxTranslationSpeed: 100 15 | m_MaxRotationSpeed: 360 16 | m_BaumgarteScale: 0.2 17 | m_BaumgarteTimeOfImpactScale: 0.75 18 | m_TimeToSleep: 0.5 19 | m_LinearSleepTolerance: 0.01 20 | m_AngularSleepTolerance: 2 21 | m_DefaultContactOffset: 0.01 22 | m_AutoSimulation: 1 23 | m_QueriesHitTriggers: 1 24 | m_QueriesStartInColliders: 1 25 | m_ChangeStopsCallbacks: 0 26 | m_CallbacksOnDisable: 1 27 | m_ReuseCollisionCallbacks: 1 28 | m_AutoSyncTransforms: 0 29 | m_AlwaysShowColliders: 0 30 | m_ShowColliderSleep: 1 31 | m_ShowColliderContacts: 0 32 | m_ShowColliderAABB: 0 33 | m_ContactArrowScale: 0.2 34 | m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} 35 | m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} 36 | m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} 37 | m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} 38 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 39 | -------------------------------------------------------------------------------- /ProjectSettings/PresetManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1386491679 &1 4 | PresetManager: 5 | m_ObjectHideFlags: 0 6 | m_DefaultList: 7 | - type: 8 | m_NativeTypeID: 108 9 | m_ManagedTypePPtr: {fileID: 0} 10 | m_ManagedTypeFallback: 11 | defaultPresets: 12 | - m_Preset: {fileID: 2655988077585873504, guid: c1cf8506f04ef2c4a88b64b6c4202eea, 13 | type: 2} 14 | - type: 15 | m_NativeTypeID: 1020 16 | m_ManagedTypePPtr: {fileID: 0} 17 | m_ManagedTypeFallback: 18 | defaultPresets: 19 | - m_Preset: {fileID: 2655988077585873504, guid: 0cd792cc87e492d43b4e95b205fc5cc6, 20 | type: 2} 21 | - type: 22 | m_NativeTypeID: 1006 23 | m_ManagedTypePPtr: {fileID: 0} 24 | m_ManagedTypeFallback: 25 | defaultPresets: 26 | - m_Preset: {fileID: 2655988077585873504, guid: 7a99f8aa944efe94cb9bd74562b7d5f9, 27 | type: 2} 28 | -------------------------------------------------------------------------------- /ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!129 &1 4 | PlayerSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 20 7 | productGUID: 64f9c552a8a194b68ae4522ffd083209 8 | AndroidProfiler: 0 9 | AndroidFilterTouchesWhenObscured: 0 10 | AndroidEnableSustainedPerformanceMode: 0 11 | defaultScreenOrientation: 4 12 | targetDevice: 2 13 | useOnDemandResources: 0 14 | accelerometerFrequency: 60 15 | companyName: BuffStudio 16 | productName: TestAppTracking 17 | defaultCursor: {fileID: 0} 18 | cursorHotspot: {x: 0, y: 0} 19 | m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1} 20 | m_ShowUnitySplashScreen: 1 21 | m_ShowUnitySplashLogo: 1 22 | m_SplashScreenOverlayOpacity: 1 23 | m_SplashScreenAnimation: 1 24 | m_SplashScreenLogoStyle: 1 25 | m_SplashScreenDrawMode: 0 26 | m_SplashScreenBackgroundAnimationZoom: 1 27 | m_SplashScreenLogoAnimationZoom: 1 28 | m_SplashScreenBackgroundLandscapeAspect: 1 29 | m_SplashScreenBackgroundPortraitAspect: 1 30 | m_SplashScreenBackgroundLandscapeUvs: 31 | serializedVersion: 2 32 | x: 0 33 | y: 0 34 | width: 1 35 | height: 1 36 | m_SplashScreenBackgroundPortraitUvs: 37 | serializedVersion: 2 38 | x: 0 39 | y: 0 40 | width: 1 41 | height: 1 42 | m_SplashScreenLogos: [] 43 | m_VirtualRealitySplashScreen: {fileID: 0} 44 | m_HolographicTrackingLossScreen: {fileID: 0} 45 | defaultScreenWidth: 1024 46 | defaultScreenHeight: 768 47 | defaultScreenWidthWeb: 960 48 | defaultScreenHeightWeb: 600 49 | m_StereoRenderingPath: 0 50 | m_ActiveColorSpace: 0 51 | m_MTRendering: 1 52 | m_StackTraceTypes: 010000000100000001000000010000000100000001000000 53 | iosShowActivityIndicatorOnLoading: -1 54 | androidShowActivityIndicatorOnLoading: -1 55 | iosUseCustomAppBackgroundBehavior: 0 56 | iosAllowHTTPDownload: 1 57 | allowedAutorotateToPortrait: 1 58 | allowedAutorotateToPortraitUpsideDown: 1 59 | allowedAutorotateToLandscapeRight: 1 60 | allowedAutorotateToLandscapeLeft: 1 61 | useOSAutorotation: 1 62 | use32BitDisplayBuffer: 1 63 | preserveFramebufferAlpha: 0 64 | disableDepthAndStencilBuffers: 0 65 | androidStartInFullscreen: 1 66 | androidRenderOutsideSafeArea: 0 67 | androidUseSwappy: 0 68 | androidBlitType: 0 69 | defaultIsNativeResolution: 1 70 | macRetinaSupport: 1 71 | runInBackground: 1 72 | captureSingleScreen: 0 73 | muteOtherAudioSources: 0 74 | Prepare IOS For Recording: 0 75 | Force IOS Speakers When Recording: 0 76 | deferSystemGesturesMode: 0 77 | hideHomeButton: 0 78 | submitAnalytics: 1 79 | usePlayerLog: 1 80 | bakeCollisionMeshes: 0 81 | forceSingleInstance: 0 82 | useFlipModelSwapchain: 1 83 | resizableWindow: 0 84 | useMacAppStoreValidation: 0 85 | macAppStoreCategory: public.app-category.games 86 | gpuSkinning: 1 87 | xboxPIXTextureCapture: 0 88 | xboxEnableAvatar: 0 89 | xboxEnableKinect: 0 90 | xboxEnableKinectAutoTracking: 0 91 | xboxEnableFitness: 0 92 | visibleInBackground: 1 93 | allowFullscreenSwitch: 1 94 | fullscreenMode: 1 95 | xboxSpeechDB: 0 96 | xboxEnableHeadOrientation: 0 97 | xboxEnableGuest: 0 98 | xboxEnablePIXSampling: 0 99 | metalFramebufferOnly: 0 100 | xboxOneResolution: 0 101 | xboxOneSResolution: 0 102 | xboxOneXResolution: 3 103 | xboxOneMonoLoggingLevel: 0 104 | xboxOneLoggingLevel: 1 105 | xboxOneDisableEsram: 0 106 | xboxOneEnableTypeOptimization: 0 107 | xboxOnePresentImmediateThreshold: 0 108 | switchQueueCommandMemory: 0 109 | switchQueueControlMemory: 16384 110 | switchQueueComputeMemory: 262144 111 | switchNVNShaderPoolsGranularity: 33554432 112 | switchNVNDefaultPoolsGranularity: 16777216 113 | switchNVNOtherPoolsGranularity: 16777216 114 | switchNVNMaxPublicTextureIDCount: 0 115 | switchNVNMaxPublicSamplerIDCount: 0 116 | stadiaPresentMode: 0 117 | stadiaTargetFramerate: 0 118 | vulkanNumSwapchainBuffers: 3 119 | vulkanEnableSetSRGBWrite: 0 120 | vulkanEnableLateAcquireNextImage: 0 121 | m_SupportedAspectRatios: 122 | 4:3: 1 123 | 5:4: 1 124 | 16:10: 1 125 | 16:9: 1 126 | Others: 1 127 | bundleVersion: 1.0.0 128 | preloadedAssets: [] 129 | metroInputSource: 0 130 | wsaTransparentSwapchain: 0 131 | m_HolographicPauseOnTrackingLoss: 1 132 | xboxOneDisableKinectGpuReservation: 1 133 | xboxOneEnable7thCore: 1 134 | vrSettings: 135 | cardboard: 136 | depthFormat: 0 137 | enableTransitionView: 0 138 | daydream: 139 | depthFormat: 0 140 | useSustainedPerformanceMode: 0 141 | enableVideoLayer: 0 142 | useProtectedVideoMemory: 0 143 | minimumSupportedHeadTracking: 0 144 | maximumSupportedHeadTracking: 1 145 | hololens: 146 | depthFormat: 1 147 | depthBufferSharingEnabled: 1 148 | lumin: 149 | depthFormat: 0 150 | frameTiming: 2 151 | enableGLCache: 0 152 | glCacheMaxBlobSize: 524288 153 | glCacheMaxFileSize: 8388608 154 | oculus: 155 | sharedDepthBuffer: 1 156 | dashSupport: 1 157 | lowOverheadMode: 0 158 | protectedContext: 0 159 | v2Signing: 0 160 | enable360StereoCapture: 0 161 | isWsaHolographicRemotingEnabled: 0 162 | enableFrameTimingStats: 0 163 | useHDRDisplay: 0 164 | D3DHDRBitDepth: 0 165 | m_ColorGamuts: 00000000 166 | targetPixelDensity: 30 167 | resolutionScalingMode: 0 168 | androidSupportedAspectRatio: 1 169 | androidMaxAspectRatio: 2.1 170 | applicationIdentifier: 171 | iPhone: com.buffstudio.test.apptracking 172 | buildNumber: {} 173 | AndroidBundleVersionCode: 1 174 | AndroidMinSdkVersion: 19 175 | AndroidTargetSdkVersion: 0 176 | AndroidPreferredInstallLocation: 1 177 | aotOptions: 178 | stripEngineCode: 1 179 | iPhoneStrippingLevel: 0 180 | iPhoneScriptCallOptimization: 0 181 | ForceInternetPermission: 0 182 | ForceSDCardPermission: 0 183 | CreateWallpaper: 0 184 | APKExpansionFiles: 0 185 | keepLoadedShadersAlive: 0 186 | StripUnusedMeshComponents: 1 187 | VertexChannelCompressionMask: 4054 188 | iPhoneSdkVersion: 988 189 | iOSTargetOSVersionString: 10.0 190 | tvOSSdkVersion: 0 191 | tvOSRequireExtendedGameController: 0 192 | tvOSTargetOSVersionString: 10.0 193 | uIPrerenderedIcon: 0 194 | uIRequiresPersistentWiFi: 0 195 | uIRequiresFullScreen: 1 196 | uIStatusBarHidden: 1 197 | uIExitOnSuspend: 0 198 | uIStatusBarStyle: 0 199 | appleTVSplashScreen: {fileID: 0} 200 | appleTVSplashScreen2x: {fileID: 0} 201 | tvOSSmallIconLayers: [] 202 | tvOSSmallIconLayers2x: [] 203 | tvOSLargeIconLayers: [] 204 | tvOSLargeIconLayers2x: [] 205 | tvOSTopShelfImageLayers: [] 206 | tvOSTopShelfImageLayers2x: [] 207 | tvOSTopShelfImageWideLayers: [] 208 | tvOSTopShelfImageWideLayers2x: [] 209 | iOSLaunchScreenType: 0 210 | iOSLaunchScreenPortrait: {fileID: 0} 211 | iOSLaunchScreenLandscape: {fileID: 0} 212 | iOSLaunchScreenBackgroundColor: 213 | serializedVersion: 2 214 | rgba: 0 215 | iOSLaunchScreenFillPct: 100 216 | iOSLaunchScreenSize: 100 217 | iOSLaunchScreenCustomXibPath: 218 | iOSLaunchScreeniPadType: 0 219 | iOSLaunchScreeniPadImage: {fileID: 0} 220 | iOSLaunchScreeniPadBackgroundColor: 221 | serializedVersion: 2 222 | rgba: 0 223 | iOSLaunchScreeniPadFillPct: 100 224 | iOSLaunchScreeniPadSize: 100 225 | iOSLaunchScreeniPadCustomXibPath: 226 | iOSUseLaunchScreenStoryboard: 0 227 | iOSLaunchScreenCustomStoryboardPath: 228 | iOSDeviceRequirements: [] 229 | iOSURLSchemes: [] 230 | iOSBackgroundModes: 0 231 | iOSMetalForceHardShadows: 0 232 | metalEditorSupport: 1 233 | metalAPIValidation: 1 234 | iOSRenderExtraFrameOnPause: 0 235 | iosCopyPluginsCodeInsteadOfSymlink: 0 236 | appleDeveloperTeamID: 237 | iOSManualSigningProvisioningProfileID: 238 | tvOSManualSigningProvisioningProfileID: 239 | iOSManualSigningProvisioningProfileType: 0 240 | tvOSManualSigningProvisioningProfileType: 0 241 | appleEnableAutomaticSigning: 0 242 | iOSRequireARKit: 0 243 | iOSAutomaticallyDetectAndAddCapabilities: 1 244 | appleEnableProMotion: 0 245 | clonedFromGUID: c0afd0d1d80e3634a9dac47e8a0426ea 246 | templatePackageId: com.unity.template.3d@1.3.0 247 | templateDefaultScene: Assets/Scenes/SampleScene.unity 248 | AndroidTargetArchitectures: 5 249 | AndroidSplashScreenScale: 0 250 | androidSplashScreen: {fileID: 0} 251 | AndroidKeystoreName: 252 | AndroidKeyaliasName: 253 | AndroidBuildApkPerCpuArchitecture: 0 254 | AndroidTVCompatibility: 1 255 | AndroidIsGame: 1 256 | AndroidEnableTango: 0 257 | androidEnableBanner: 1 258 | androidUseLowAccuracyLocation: 0 259 | androidUseCustomKeystore: 0 260 | m_AndroidBanners: 261 | - width: 320 262 | height: 180 263 | banner: {fileID: 0} 264 | androidGamepadSupportLevel: 0 265 | AndroidValidateAppBundleSize: 1 266 | AndroidAppBundleSizeToValidate: 150 267 | m_BuildTargetIcons: [] 268 | m_BuildTargetPlatformIcons: 269 | - m_BuildTarget: iPhone 270 | m_Icons: 271 | - m_Textures: [] 272 | m_Width: 180 273 | m_Height: 180 274 | m_Kind: 0 275 | m_SubKind: iPhone 276 | - m_Textures: [] 277 | m_Width: 120 278 | m_Height: 120 279 | m_Kind: 0 280 | m_SubKind: iPhone 281 | - m_Textures: [] 282 | m_Width: 167 283 | m_Height: 167 284 | m_Kind: 0 285 | m_SubKind: iPad 286 | - m_Textures: [] 287 | m_Width: 152 288 | m_Height: 152 289 | m_Kind: 0 290 | m_SubKind: iPad 291 | - m_Textures: [] 292 | m_Width: 76 293 | m_Height: 76 294 | m_Kind: 0 295 | m_SubKind: iPad 296 | - m_Textures: [] 297 | m_Width: 120 298 | m_Height: 120 299 | m_Kind: 3 300 | m_SubKind: iPhone 301 | - m_Textures: [] 302 | m_Width: 80 303 | m_Height: 80 304 | m_Kind: 3 305 | m_SubKind: iPhone 306 | - m_Textures: [] 307 | m_Width: 80 308 | m_Height: 80 309 | m_Kind: 3 310 | m_SubKind: iPad 311 | - m_Textures: [] 312 | m_Width: 40 313 | m_Height: 40 314 | m_Kind: 3 315 | m_SubKind: iPad 316 | - m_Textures: [] 317 | m_Width: 87 318 | m_Height: 87 319 | m_Kind: 1 320 | m_SubKind: iPhone 321 | - m_Textures: [] 322 | m_Width: 58 323 | m_Height: 58 324 | m_Kind: 1 325 | m_SubKind: iPhone 326 | - m_Textures: [] 327 | m_Width: 29 328 | m_Height: 29 329 | m_Kind: 1 330 | m_SubKind: iPhone 331 | - m_Textures: [] 332 | m_Width: 58 333 | m_Height: 58 334 | m_Kind: 1 335 | m_SubKind: iPad 336 | - m_Textures: [] 337 | m_Width: 29 338 | m_Height: 29 339 | m_Kind: 1 340 | m_SubKind: iPad 341 | - m_Textures: [] 342 | m_Width: 60 343 | m_Height: 60 344 | m_Kind: 2 345 | m_SubKind: iPhone 346 | - m_Textures: [] 347 | m_Width: 40 348 | m_Height: 40 349 | m_Kind: 2 350 | m_SubKind: iPhone 351 | - m_Textures: [] 352 | m_Width: 40 353 | m_Height: 40 354 | m_Kind: 2 355 | m_SubKind: iPad 356 | - m_Textures: [] 357 | m_Width: 20 358 | m_Height: 20 359 | m_Kind: 2 360 | m_SubKind: iPad 361 | - m_Textures: [] 362 | m_Width: 1024 363 | m_Height: 1024 364 | m_Kind: 4 365 | m_SubKind: App Store 366 | - m_BuildTarget: Android 367 | m_Icons: 368 | - m_Textures: [] 369 | m_Width: 432 370 | m_Height: 432 371 | m_Kind: 2 372 | m_SubKind: 373 | - m_Textures: [] 374 | m_Width: 324 375 | m_Height: 324 376 | m_Kind: 2 377 | m_SubKind: 378 | - m_Textures: [] 379 | m_Width: 216 380 | m_Height: 216 381 | m_Kind: 2 382 | m_SubKind: 383 | - m_Textures: [] 384 | m_Width: 162 385 | m_Height: 162 386 | m_Kind: 2 387 | m_SubKind: 388 | - m_Textures: [] 389 | m_Width: 108 390 | m_Height: 108 391 | m_Kind: 2 392 | m_SubKind: 393 | - m_Textures: [] 394 | m_Width: 81 395 | m_Height: 81 396 | m_Kind: 2 397 | m_SubKind: 398 | - m_Textures: [] 399 | m_Width: 192 400 | m_Height: 192 401 | m_Kind: 1 402 | m_SubKind: 403 | - m_Textures: [] 404 | m_Width: 144 405 | m_Height: 144 406 | m_Kind: 1 407 | m_SubKind: 408 | - m_Textures: [] 409 | m_Width: 96 410 | m_Height: 96 411 | m_Kind: 1 412 | m_SubKind: 413 | - m_Textures: [] 414 | m_Width: 72 415 | m_Height: 72 416 | m_Kind: 1 417 | m_SubKind: 418 | - m_Textures: [] 419 | m_Width: 48 420 | m_Height: 48 421 | m_Kind: 1 422 | m_SubKind: 423 | - m_Textures: [] 424 | m_Width: 36 425 | m_Height: 36 426 | m_Kind: 1 427 | m_SubKind: 428 | - m_Textures: [] 429 | m_Width: 192 430 | m_Height: 192 431 | m_Kind: 0 432 | m_SubKind: 433 | - m_Textures: [] 434 | m_Width: 144 435 | m_Height: 144 436 | m_Kind: 0 437 | m_SubKind: 438 | - m_Textures: [] 439 | m_Width: 96 440 | m_Height: 96 441 | m_Kind: 0 442 | m_SubKind: 443 | - m_Textures: [] 444 | m_Width: 72 445 | m_Height: 72 446 | m_Kind: 0 447 | m_SubKind: 448 | - m_Textures: [] 449 | m_Width: 48 450 | m_Height: 48 451 | m_Kind: 0 452 | m_SubKind: 453 | - m_Textures: [] 454 | m_Width: 36 455 | m_Height: 36 456 | m_Kind: 0 457 | m_SubKind: 458 | m_BuildTargetBatching: 459 | - m_BuildTarget: Standalone 460 | m_StaticBatching: 1 461 | m_DynamicBatching: 0 462 | - m_BuildTarget: tvOS 463 | m_StaticBatching: 1 464 | m_DynamicBatching: 0 465 | - m_BuildTarget: Android 466 | m_StaticBatching: 1 467 | m_DynamicBatching: 0 468 | - m_BuildTarget: iPhone 469 | m_StaticBatching: 1 470 | m_DynamicBatching: 0 471 | - m_BuildTarget: WebGL 472 | m_StaticBatching: 0 473 | m_DynamicBatching: 0 474 | m_BuildTargetGraphicsJobs: 475 | - m_BuildTarget: MacStandaloneSupport 476 | m_GraphicsJobs: 0 477 | - m_BuildTarget: Switch 478 | m_GraphicsJobs: 0 479 | - m_BuildTarget: MetroSupport 480 | m_GraphicsJobs: 0 481 | - m_BuildTarget: AppleTVSupport 482 | m_GraphicsJobs: 0 483 | - m_BuildTarget: BJMSupport 484 | m_GraphicsJobs: 0 485 | - m_BuildTarget: LinuxStandaloneSupport 486 | m_GraphicsJobs: 0 487 | - m_BuildTarget: PS4Player 488 | m_GraphicsJobs: 0 489 | - m_BuildTarget: iOSSupport 490 | m_GraphicsJobs: 0 491 | - m_BuildTarget: WindowsStandaloneSupport 492 | m_GraphicsJobs: 0 493 | - m_BuildTarget: XboxOnePlayer 494 | m_GraphicsJobs: 0 495 | - m_BuildTarget: LuminSupport 496 | m_GraphicsJobs: 0 497 | - m_BuildTarget: CloudRendering 498 | m_GraphicsJobs: 0 499 | - m_BuildTarget: AndroidPlayer 500 | m_GraphicsJobs: 0 501 | - m_BuildTarget: WebGLSupport 502 | m_GraphicsJobs: 0 503 | m_BuildTargetGraphicsJobMode: 504 | - m_BuildTarget: PS4Player 505 | m_GraphicsJobMode: 0 506 | - m_BuildTarget: XboxOnePlayer 507 | m_GraphicsJobMode: 0 508 | m_BuildTargetGraphicsAPIs: 509 | - m_BuildTarget: AndroidPlayer 510 | m_APIs: 0b00000008000000 511 | m_Automatic: 1 512 | - m_BuildTarget: iOSSupport 513 | m_APIs: 10000000 514 | m_Automatic: 1 515 | - m_BuildTarget: AppleTVSupport 516 | m_APIs: 10000000 517 | m_Automatic: 0 518 | - m_BuildTarget: WebGLSupport 519 | m_APIs: 0b000000 520 | m_Automatic: 1 521 | m_BuildTargetVRSettings: 522 | - m_BuildTarget: Standalone 523 | m_Enabled: 0 524 | m_Devices: 525 | - Oculus 526 | - OpenVR 527 | openGLRequireES31: 0 528 | openGLRequireES31AEP: 0 529 | openGLRequireES32: 0 530 | m_TemplateCustomTags: {} 531 | mobileMTRendering: 532 | Android: 1 533 | iPhone: 1 534 | tvOS: 1 535 | m_BuildTargetGroupLightmapEncodingQuality: [] 536 | m_BuildTargetGroupLightmapSettings: [] 537 | playModeTestRunnerEnabled: 0 538 | runPlayModeTestAsEditModeTest: 0 539 | actionOnDotNetUnhandledException: 1 540 | enableInternalProfiler: 0 541 | logObjCUncaughtExceptions: 1 542 | enableCrashReportAPI: 0 543 | cameraUsageDescription: 544 | locationUsageDescription: 545 | microphoneUsageDescription: 546 | switchNetLibKey: 547 | switchSocketMemoryPoolSize: 6144 548 | switchSocketAllocatorPoolSize: 128 549 | switchSocketConcurrencyLimit: 14 550 | switchScreenResolutionBehavior: 2 551 | switchUseCPUProfiler: 0 552 | switchApplicationID: 0x01004b9000490000 553 | switchNSODependencies: 554 | switchTitleNames_0: 555 | switchTitleNames_1: 556 | switchTitleNames_2: 557 | switchTitleNames_3: 558 | switchTitleNames_4: 559 | switchTitleNames_5: 560 | switchTitleNames_6: 561 | switchTitleNames_7: 562 | switchTitleNames_8: 563 | switchTitleNames_9: 564 | switchTitleNames_10: 565 | switchTitleNames_11: 566 | switchTitleNames_12: 567 | switchTitleNames_13: 568 | switchTitleNames_14: 569 | switchPublisherNames_0: 570 | switchPublisherNames_1: 571 | switchPublisherNames_2: 572 | switchPublisherNames_3: 573 | switchPublisherNames_4: 574 | switchPublisherNames_5: 575 | switchPublisherNames_6: 576 | switchPublisherNames_7: 577 | switchPublisherNames_8: 578 | switchPublisherNames_9: 579 | switchPublisherNames_10: 580 | switchPublisherNames_11: 581 | switchPublisherNames_12: 582 | switchPublisherNames_13: 583 | switchPublisherNames_14: 584 | switchIcons_0: {fileID: 0} 585 | switchIcons_1: {fileID: 0} 586 | switchIcons_2: {fileID: 0} 587 | switchIcons_3: {fileID: 0} 588 | switchIcons_4: {fileID: 0} 589 | switchIcons_5: {fileID: 0} 590 | switchIcons_6: {fileID: 0} 591 | switchIcons_7: {fileID: 0} 592 | switchIcons_8: {fileID: 0} 593 | switchIcons_9: {fileID: 0} 594 | switchIcons_10: {fileID: 0} 595 | switchIcons_11: {fileID: 0} 596 | switchIcons_12: {fileID: 0} 597 | switchIcons_13: {fileID: 0} 598 | switchIcons_14: {fileID: 0} 599 | switchSmallIcons_0: {fileID: 0} 600 | switchSmallIcons_1: {fileID: 0} 601 | switchSmallIcons_2: {fileID: 0} 602 | switchSmallIcons_3: {fileID: 0} 603 | switchSmallIcons_4: {fileID: 0} 604 | switchSmallIcons_5: {fileID: 0} 605 | switchSmallIcons_6: {fileID: 0} 606 | switchSmallIcons_7: {fileID: 0} 607 | switchSmallIcons_8: {fileID: 0} 608 | switchSmallIcons_9: {fileID: 0} 609 | switchSmallIcons_10: {fileID: 0} 610 | switchSmallIcons_11: {fileID: 0} 611 | switchSmallIcons_12: {fileID: 0} 612 | switchSmallIcons_13: {fileID: 0} 613 | switchSmallIcons_14: {fileID: 0} 614 | switchManualHTML: 615 | switchAccessibleURLs: 616 | switchLegalInformation: 617 | switchMainThreadStackSize: 1048576 618 | switchPresenceGroupId: 619 | switchLogoHandling: 0 620 | switchReleaseVersion: 0 621 | switchDisplayVersion: 1.0.0 622 | switchStartupUserAccount: 0 623 | switchTouchScreenUsage: 0 624 | switchSupportedLanguagesMask: 0 625 | switchLogoType: 0 626 | switchApplicationErrorCodeCategory: 627 | switchUserAccountSaveDataSize: 0 628 | switchUserAccountSaveDataJournalSize: 0 629 | switchApplicationAttribute: 0 630 | switchCardSpecSize: -1 631 | switchCardSpecClock: -1 632 | switchRatingsMask: 0 633 | switchRatingsInt_0: 0 634 | switchRatingsInt_1: 0 635 | switchRatingsInt_2: 0 636 | switchRatingsInt_3: 0 637 | switchRatingsInt_4: 0 638 | switchRatingsInt_5: 0 639 | switchRatingsInt_6: 0 640 | switchRatingsInt_7: 0 641 | switchRatingsInt_8: 0 642 | switchRatingsInt_9: 0 643 | switchRatingsInt_10: 0 644 | switchRatingsInt_11: 0 645 | switchRatingsInt_12: 0 646 | switchLocalCommunicationIds_0: 647 | switchLocalCommunicationIds_1: 648 | switchLocalCommunicationIds_2: 649 | switchLocalCommunicationIds_3: 650 | switchLocalCommunicationIds_4: 651 | switchLocalCommunicationIds_5: 652 | switchLocalCommunicationIds_6: 653 | switchLocalCommunicationIds_7: 654 | switchParentalControl: 0 655 | switchAllowsScreenshot: 1 656 | switchAllowsVideoCapturing: 1 657 | switchAllowsRuntimeAddOnContentInstall: 0 658 | switchDataLossConfirmation: 0 659 | switchUserAccountLockEnabled: 0 660 | switchSystemResourceMemory: 16777216 661 | switchSupportedNpadStyles: 3 662 | switchNativeFsCacheSize: 32 663 | switchIsHoldTypeHorizontal: 0 664 | switchSupportedNpadCount: 8 665 | switchSocketConfigEnabled: 0 666 | switchTcpInitialSendBufferSize: 32 667 | switchTcpInitialReceiveBufferSize: 64 668 | switchTcpAutoSendBufferSizeMax: 256 669 | switchTcpAutoReceiveBufferSizeMax: 256 670 | switchUdpSendBufferSize: 9 671 | switchUdpReceiveBufferSize: 42 672 | switchSocketBufferEfficiency: 4 673 | switchSocketInitializeEnabled: 1 674 | switchNetworkInterfaceManagerInitializeEnabled: 1 675 | switchPlayerConnectionEnabled: 1 676 | ps4NPAgeRating: 12 677 | ps4NPTitleSecret: 678 | ps4NPTrophyPackPath: 679 | ps4ParentalLevel: 11 680 | ps4ContentID: ED1633-NPXX51362_00-0000000000000000 681 | ps4Category: 0 682 | ps4MasterVersion: 01.00 683 | ps4AppVersion: 01.00 684 | ps4AppType: 0 685 | ps4ParamSfxPath: 686 | ps4VideoOutPixelFormat: 0 687 | ps4VideoOutInitialWidth: 1920 688 | ps4VideoOutBaseModeInitialWidth: 1920 689 | ps4VideoOutReprojectionRate: 60 690 | ps4PronunciationXMLPath: 691 | ps4PronunciationSIGPath: 692 | ps4BackgroundImagePath: 693 | ps4StartupImagePath: 694 | ps4StartupImagesFolder: 695 | ps4IconImagesFolder: 696 | ps4SaveDataImagePath: 697 | ps4SdkOverride: 698 | ps4BGMPath: 699 | ps4ShareFilePath: 700 | ps4ShareOverlayImagePath: 701 | ps4PrivacyGuardImagePath: 702 | ps4ExtraSceSysFile: 703 | ps4NPtitleDatPath: 704 | ps4RemotePlayKeyAssignment: -1 705 | ps4RemotePlayKeyMappingDir: 706 | ps4PlayTogetherPlayerCount: 0 707 | ps4EnterButtonAssignment: 1 708 | ps4ApplicationParam1: 0 709 | ps4ApplicationParam2: 0 710 | ps4ApplicationParam3: 0 711 | ps4ApplicationParam4: 0 712 | ps4DownloadDataSize: 0 713 | ps4GarlicHeapSize: 2048 714 | ps4ProGarlicHeapSize: 2560 715 | playerPrefsMaxSize: 32768 716 | ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ 717 | ps4pnSessions: 1 718 | ps4pnPresence: 1 719 | ps4pnFriends: 1 720 | ps4pnGameCustomData: 1 721 | playerPrefsSupport: 0 722 | enableApplicationExit: 0 723 | resetTempFolder: 1 724 | restrictedAudioUsageRights: 0 725 | ps4UseResolutionFallback: 0 726 | ps4ReprojectionSupport: 0 727 | ps4UseAudio3dBackend: 0 728 | ps4UseLowGarlicFragmentationMode: 1 729 | ps4SocialScreenEnabled: 0 730 | ps4ScriptOptimizationLevel: 0 731 | ps4Audio3dVirtualSpeakerCount: 14 732 | ps4attribCpuUsage: 0 733 | ps4PatchPkgPath: 734 | ps4PatchLatestPkgPath: 735 | ps4PatchChangeinfoPath: 736 | ps4PatchDayOne: 0 737 | ps4attribUserManagement: 0 738 | ps4attribMoveSupport: 0 739 | ps4attrib3DSupport: 0 740 | ps4attribShareSupport: 0 741 | ps4attribExclusiveVR: 0 742 | ps4disableAutoHideSplash: 0 743 | ps4videoRecordingFeaturesUsed: 0 744 | ps4contentSearchFeaturesUsed: 0 745 | ps4CompatibilityPS5: 0 746 | ps4GPU800MHz: 1 747 | ps4attribEyeToEyeDistanceSettingVR: 0 748 | ps4IncludedModules: [] 749 | ps4attribVROutputEnabled: 0 750 | monoEnv: 751 | splashScreenBackgroundSourceLandscape: {fileID: 0} 752 | splashScreenBackgroundSourcePortrait: {fileID: 0} 753 | blurSplashScreenBackground: 1 754 | spritePackerPolicy: 755 | webGLMemorySize: 256 756 | webGLExceptionSupport: 1 757 | webGLNameFilesAsHashes: 0 758 | webGLDataCaching: 1 759 | webGLDebugSymbols: 0 760 | webGLEmscriptenArgs: 761 | webGLModulesDirectory: 762 | webGLTemplate: APPLICATION:Default 763 | webGLAnalyzeBuildSize: 0 764 | webGLUseEmbeddedResources: 0 765 | webGLCompressionFormat: 1 766 | webGLLinkerTarget: 1 767 | webGLThreadsSupport: 0 768 | webGLWasmStreaming: 0 769 | scriptingDefineSymbols: {} 770 | platformArchitecture: {} 771 | scriptingBackend: {} 772 | il2cppCompilerConfiguration: {} 773 | managedStrippingLevel: {} 774 | incrementalIl2cppBuild: {} 775 | allowUnsafeCode: 0 776 | additionalIl2CppArgs: 777 | scriptingRuntimeVersion: 1 778 | gcIncremental: 0 779 | gcWBarrierValidation: 0 780 | apiCompatibilityLevelPerPlatform: {} 781 | m_RenderingPath: 1 782 | m_MobileRenderingPath: 1 783 | metroPackageName: Template_3D 784 | metroPackageVersion: 785 | metroCertificatePath: 786 | metroCertificatePassword: 787 | metroCertificateSubject: 788 | metroCertificateIssuer: 789 | metroCertificateNotAfter: 0000000000000000 790 | metroApplicationDescription: Template_3D 791 | wsaImages: {} 792 | metroTileShortName: 793 | metroTileShowName: 0 794 | metroMediumTileShowName: 0 795 | metroLargeTileShowName: 0 796 | metroWideTileShowName: 0 797 | metroSupportStreamingInstall: 0 798 | metroLastRequiredScene: 0 799 | metroDefaultTileSize: 1 800 | metroTileForegroundText: 2 801 | metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} 802 | metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, 803 | a: 1} 804 | metroSplashScreenUseBackgroundColor: 0 805 | platformCapabilities: {} 806 | metroTargetDeviceFamilies: {} 807 | metroFTAName: 808 | metroFTAFileTypes: [] 809 | metroProtocolName: 810 | XboxOneProductId: 811 | XboxOneUpdateKey: 812 | XboxOneSandboxId: 813 | XboxOneContentId: 814 | XboxOneTitleId: 815 | XboxOneSCId: 816 | XboxOneGameOsOverridePath: 817 | XboxOnePackagingOverridePath: 818 | XboxOneAppManifestOverridePath: 819 | XboxOneVersion: 1.0.0.0 820 | XboxOnePackageEncryption: 0 821 | XboxOnePackageUpdateGranularity: 2 822 | XboxOneDescription: 823 | XboxOneLanguage: 824 | - enus 825 | XboxOneCapability: [] 826 | XboxOneGameRating: {} 827 | XboxOneIsContentPackage: 0 828 | XboxOneEnableGPUVariability: 1 829 | XboxOneSockets: {} 830 | XboxOneSplashScreen: {fileID: 0} 831 | XboxOneAllowedProductIds: [] 832 | XboxOnePersistentLocalStorageSize: 0 833 | XboxOneXTitleMemory: 8 834 | XboxOneOverrideIdentityName: 835 | XboxOneOverrideIdentityPublisher: 836 | vrEditorSettings: 837 | daydream: 838 | daydreamIconForeground: {fileID: 0} 839 | daydreamIconBackground: {fileID: 0} 840 | cloudServicesEnabled: 841 | UNet: 1 842 | luminIcon: 843 | m_Name: 844 | m_ModelFolderPath: 845 | m_PortalFolderPath: 846 | luminCert: 847 | m_CertPath: 848 | m_SignPackage: 1 849 | luminIsChannelApp: 0 850 | luminVersion: 851 | m_VersionCode: 1 852 | m_VersionName: 853 | apiCompatibilityLevel: 6 854 | cloudProjectId: 855 | framebufferDepthMemorylessMode: 0 856 | projectName: 857 | organizationId: 858 | cloudEnabled: 0 859 | enableNativePlatformBackendsForNewInputSystem: 0 860 | disableOldInputManagerSupport: 0 861 | legacyClampBlendShapeWeights: 0 862 | -------------------------------------------------------------------------------- /ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 2019.4.13f1 2 | m_EditorVersionWithRevision: 2019.4.13f1 (518737b1de84) 3 | -------------------------------------------------------------------------------- /ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!47 &1 4 | QualitySettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 5 7 | m_CurrentQuality: 4 8 | m_QualitySettings: 9 | - serializedVersion: 2 10 | name: Very Low 11 | pixelLightCount: 0 12 | shadows: 0 13 | shadowResolution: 0 14 | shadowProjection: 1 15 | shadowCascades: 1 16 | shadowDistance: 15 17 | shadowNearPlaneOffset: 3 18 | shadowCascade2Split: 0.33333334 19 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 20 | shadowmaskMode: 0 21 | blendWeights: 1 22 | textureQuality: 1 23 | anisotropicTextures: 0 24 | antiAliasing: 0 25 | softParticles: 0 26 | softVegetation: 0 27 | realtimeReflectionProbes: 0 28 | billboardsFaceCameraPosition: 0 29 | vSyncCount: 0 30 | lodBias: 0.3 31 | maximumLODLevel: 0 32 | particleRaycastBudget: 4 33 | asyncUploadTimeSlice: 2 34 | asyncUploadBufferSize: 16 35 | resolutionScalingFixedDPIFactor: 1 36 | excludedTargetPlatforms: [] 37 | - serializedVersion: 2 38 | name: Low 39 | pixelLightCount: 0 40 | shadows: 0 41 | shadowResolution: 0 42 | shadowProjection: 1 43 | shadowCascades: 1 44 | shadowDistance: 20 45 | shadowNearPlaneOffset: 3 46 | shadowCascade2Split: 0.33333334 47 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 48 | shadowmaskMode: 0 49 | blendWeights: 2 50 | textureQuality: 0 51 | anisotropicTextures: 0 52 | antiAliasing: 0 53 | softParticles: 0 54 | softVegetation: 0 55 | realtimeReflectionProbes: 0 56 | billboardsFaceCameraPosition: 0 57 | vSyncCount: 0 58 | lodBias: 0.4 59 | maximumLODLevel: 0 60 | particleRaycastBudget: 16 61 | asyncUploadTimeSlice: 2 62 | asyncUploadBufferSize: 16 63 | resolutionScalingFixedDPIFactor: 1 64 | excludedTargetPlatforms: [] 65 | - serializedVersion: 2 66 | name: Medium 67 | pixelLightCount: 1 68 | shadows: 1 69 | shadowResolution: 0 70 | shadowProjection: 1 71 | shadowCascades: 1 72 | shadowDistance: 20 73 | shadowNearPlaneOffset: 3 74 | shadowCascade2Split: 0.33333334 75 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 76 | shadowmaskMode: 0 77 | blendWeights: 2 78 | textureQuality: 0 79 | anisotropicTextures: 1 80 | antiAliasing: 0 81 | softParticles: 0 82 | softVegetation: 0 83 | realtimeReflectionProbes: 0 84 | billboardsFaceCameraPosition: 0 85 | vSyncCount: 1 86 | lodBias: 0.7 87 | maximumLODLevel: 0 88 | particleRaycastBudget: 64 89 | asyncUploadTimeSlice: 2 90 | asyncUploadBufferSize: 16 91 | resolutionScalingFixedDPIFactor: 1 92 | excludedTargetPlatforms: [] 93 | - serializedVersion: 2 94 | name: High 95 | pixelLightCount: 2 96 | shadows: 2 97 | shadowResolution: 1 98 | shadowProjection: 1 99 | shadowCascades: 2 100 | shadowDistance: 40 101 | shadowNearPlaneOffset: 3 102 | shadowCascade2Split: 0.33333334 103 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 104 | shadowmaskMode: 1 105 | blendWeights: 2 106 | textureQuality: 0 107 | anisotropicTextures: 1 108 | antiAliasing: 2 109 | softParticles: 0 110 | softVegetation: 1 111 | realtimeReflectionProbes: 1 112 | billboardsFaceCameraPosition: 1 113 | vSyncCount: 1 114 | lodBias: 1 115 | maximumLODLevel: 0 116 | particleRaycastBudget: 256 117 | asyncUploadTimeSlice: 2 118 | asyncUploadBufferSize: 16 119 | resolutionScalingFixedDPIFactor: 1 120 | excludedTargetPlatforms: [] 121 | - serializedVersion: 2 122 | name: Very High 123 | pixelLightCount: 3 124 | shadows: 2 125 | shadowResolution: 2 126 | shadowProjection: 1 127 | shadowCascades: 2 128 | shadowDistance: 40 129 | shadowNearPlaneOffset: 3 130 | shadowCascade2Split: 0.33333334 131 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 132 | shadowmaskMode: 1 133 | blendWeights: 4 134 | textureQuality: 0 135 | anisotropicTextures: 1 136 | antiAliasing: 4 137 | softParticles: 1 138 | softVegetation: 1 139 | realtimeReflectionProbes: 1 140 | billboardsFaceCameraPosition: 1 141 | vSyncCount: 1 142 | lodBias: 1.5 143 | maximumLODLevel: 0 144 | particleRaycastBudget: 1024 145 | asyncUploadTimeSlice: 2 146 | asyncUploadBufferSize: 16 147 | resolutionScalingFixedDPIFactor: 1 148 | excludedTargetPlatforms: [] 149 | - serializedVersion: 2 150 | name: Ultra 151 | pixelLightCount: 4 152 | shadows: 2 153 | shadowResolution: 2 154 | shadowProjection: 1 155 | shadowCascades: 4 156 | shadowDistance: 150 157 | shadowNearPlaneOffset: 3 158 | shadowCascade2Split: 0.33333334 159 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 160 | shadowmaskMode: 1 161 | blendWeights: 4 162 | textureQuality: 0 163 | anisotropicTextures: 1 164 | antiAliasing: 4 165 | softParticles: 1 166 | softVegetation: 1 167 | realtimeReflectionProbes: 1 168 | billboardsFaceCameraPosition: 1 169 | vSyncCount: 1 170 | lodBias: 2 171 | maximumLODLevel: 0 172 | particleRaycastBudget: 4096 173 | asyncUploadTimeSlice: 2 174 | asyncUploadBufferSize: 16 175 | resolutionScalingFixedDPIFactor: 1 176 | excludedTargetPlatforms: [] 177 | m_PerPlatformDefaultQuality: 178 | Android: 2 179 | Nintendo 3DS: 5 180 | Nintendo Switch: 5 181 | PS4: 5 182 | PSP2: 2 183 | Standalone: 5 184 | Tizen: 2 185 | WebGL: 3 186 | WiiU: 5 187 | Windows Store Apps: 5 188 | XboxOne: 5 189 | iPhone: 2 190 | tvOS: 2 191 | -------------------------------------------------------------------------------- /ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!78 &1 4 | TagManager: 5 | serializedVersion: 2 6 | tags: [] 7 | layers: 8 | - Default 9 | - TransparentFX 10 | - Ignore Raycast 11 | - 12 | - Water 13 | - UI 14 | - 15 | - 16 | - PostProcessing 17 | - 18 | - 19 | - 20 | - 21 | - 22 | - 23 | - 24 | - 25 | - 26 | - 27 | - 28 | - 29 | - 30 | - 31 | - 32 | - 33 | - 34 | - 35 | - 36 | - 37 | - 38 | - 39 | - 40 | m_SortingLayers: 41 | - name: Default 42 | uniqueID: 0 43 | locked: 0 44 | -------------------------------------------------------------------------------- /ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!5 &1 4 | TimeManager: 5 | m_ObjectHideFlags: 0 6 | Fixed Timestep: 0.02 7 | Maximum Allowed Timestep: 0.1 8 | m_TimeScale: 1 9 | Maximum Particle Timestep: 0.03 10 | -------------------------------------------------------------------------------- /ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!310 &1 4 | UnityConnectSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 1 7 | m_Enabled: 0 8 | m_TestMode: 0 9 | m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events 10 | m_EventUrl: https://cdp.cloud.unity3d.com/v1/events 11 | m_ConfigUrl: https://config.uca.cloud.unity3d.com 12 | m_TestInitMode: 0 13 | CrashReportingSettings: 14 | m_EventUrl: https://perf-events.cloud.unity3d.com 15 | m_Enabled: 0 16 | m_LogBufferSize: 10 17 | m_CaptureEditorExceptions: 1 18 | UnityPurchasingSettings: 19 | m_Enabled: 0 20 | m_TestMode: 0 21 | UnityAnalyticsSettings: 22 | m_Enabled: 0 23 | m_TestMode: 0 24 | m_InitializeOnStartup: 1 25 | UnityAdsSettings: 26 | m_Enabled: 0 27 | m_InitializeOnStartup: 1 28 | m_TestMode: 0 29 | m_IosGameId: 30 | m_AndroidGameId: 31 | m_GameIds: {} 32 | m_GameId: 33 | PerformanceReportingSettings: 34 | m_Enabled: 0 35 | -------------------------------------------------------------------------------- /ProjectSettings/VFXManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!937362698 &1 4 | VFXManager: 5 | m_ObjectHideFlags: 0 6 | m_IndirectShader: {fileID: 0} 7 | m_CopyBufferShader: {fileID: 0} 8 | m_SortShader: {fileID: 0} 9 | m_RenderPipeSettingsPath: 10 | m_FixedTimeStep: 0.016666668 11 | m_MaxDeltaTime: 0.05 12 | -------------------------------------------------------------------------------- /ProjectSettings/XRSettings.asset: -------------------------------------------------------------------------------- 1 | { 2 | "m_SettingKeys": [ 3 | "VR Device Disabled", 4 | "VR Device User Alert" 5 | ], 6 | "m_SettingValues": [ 7 | "False", 8 | "False" 9 | ] 10 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UnityBridgeAppTracking 2 | iOS 14 App Tracking Transparency Bridge For Unity 3 | |iOS|Description| 4 | |--------------|--| 5 | | 14.4 or less | Do not this UnityBridgeAppTracking, because iOS Advertising Identifier is OK. | 6 | | 14.5 or more | iOS Advertising Identifier is all zero in default. Do this UnityBridgeAppTracking, If User allow App Tracking Authorization, iOS Advertising Identifier is OK. But if User deny, iOS Advertising Identifier is all zero. User can switch on in Setting - Your App - App Tracking Authorization. | 7 | 8 | (from https://developer.apple.com/documentation/adsupport/asidentifiermanager/1614151-advertisingidentifier?language=objc) 9 | 10 | ## Build Environment 11 | 12 | Unity 2018.x / Unity 2019.x 13 | 14 | Xcode 12.3 15 | 16 | ## How to Use 17 | 1. Modify your NSUserTrackingUsageDescription in NSUserTrackingUsageDescription.txt and Add SKAdNetworks to SKAdNetworkItems.plist 18 | ``` 19 | Assets/10.Tools/AppTrackingTransparency/Editor/NSUserTrackingUsageDescription.txt 20 | Assets/10.Tools/AppTrackingTransparency/Editor/SKAdNetworkItems.plist 21 | ``` 22 | So, Unity PostprocessBuildScript insert NSUserTrackingUsageDescription and SKAdNetworkItems to Info.plist. 23 | 24 | 2. Modify Multi Language NSUserTrackingUsageDescription And App Name. 25 | Examples to Base, Korean, Chinese(Simple), Chinese(Traditional), English, Japanese 26 | ``` 27 | Assets/10.Tools/NativeLocale/iOS/Base.lproj/InfoPlist.strings 28 | Assets/10.Tools/NativeLocale/iOS/ko.lproj/InfoPlist.strings 29 | Assets/10.Tools/NativeLocale/iOS/zh-Hans.lproj/InfoPlist.strings 30 | Assets/10.Tools/NativeLocale/iOS/zh-Hant.lproj/InfoPlist.strings 31 | Assets/10.Tools/NativeLocale/iOS/en.lproj/InfoPlist.strings 32 | Assets/10.Tools/NativeLocale/iOS/ja.lproj/InfoPlist.strings 33 | ``` 34 | option) 35 | If you do not want to use Multi Language App Name, remove CFBundleDisplayName, CFBundleName in InfoPlist.strings 36 | 37 | 3. Attach AppTrackingAuthorization.prefab in your Scene. 38 | ``` 39 | Assets/03.Prefebs/AppTrackingAuthorization.prefab 40 | ``` 41 | 4. Modify AppTrackingAuthorization.cs in your flow. 42 | ``` 43 | Assets/02.Scripts/AppTrackingTransparency/AppTrackingAuthorization.cs 44 | ``` 45 | - Request App Tracking Authorization 46 | ``` 47 | AppTrackingTransparency.RequestAppTrackingAuthorization(); 48 | ``` 49 | - Request Call back 50 | ``` 51 | public void OnCallBackAuthorizationForNoneIOS(AppTrackingTransparency.AuthorizationStatus myStatus) 52 | ``` 53 | - Check current App Tracking Authorization Status 54 | ``` 55 | AppTrackingTransparency.status 56 | ``` 57 | 5. Build Unity Xcode Project and Build Xcode and Test! 58 | 59 | ## Sample App Screen Shot 60 | | 1. notDetermined Status | 2. Request App Tracking Authorization | 3. Allow | 4. Deny | 61 | | ------------ | ---------- | ------ |------ | 62 | | ![notDetermined Status](https://github.com/BuffStudio-PublicDev/UnityBridgeAppTracking/blob/main/SampleScreenShot/Image01.png) |![Request App Tracking Authorization](https://github.com/BuffStudio-PublicDev/UnityBridgeAppTracking/blob/main/SampleScreenShot/Image02.png)| ![Allow](https://github.com/BuffStudio-PublicDev/UnityBridgeAppTracking/blob/main/SampleScreenShot/Image03.png) |![Deny](https://github.com/BuffStudio-PublicDev/UnityBridgeAppTracking/blob/main/SampleScreenShot/Image04.png)| 63 | 64 | | 1. App Setting App Tracking Authorization Off | 2. Switch on in App Tracking Authorization | 3. App Setting App Tracking Authorization On | 65 | | ------------ | ---------- | ------ | 66 | | ![](https://github.com/BuffStudio-PublicDev/UnityBridgeAppTracking/blob/main/SampleScreenShot/Image05.png) | ![](https://github.com/BuffStudio-PublicDev/UnityBridgeAppTracking/blob/main/SampleScreenShot/Image06.png) | ![](https://github.com/BuffStudio-PublicDev/UnityBridgeAppTracking/blob/main/SampleScreenShot/Image07.png) | 67 | 68 | ## This UnityBridgeAppTracking use UnityAppNameLocalizationForIOS 69 | 70 | https://github.com/zeyangl/UnityAppNameLocalizationForIOS 71 | 72 | ## IOS 14 App Tracking Transparency Documents 73 | 74 | https://developer.apple.com/documentation/apptrackingtransparency 75 | 76 | https://developer.apple.com/documentation/adsupport/asidentifiermanager/1614151-advertisingidentifier?language=objc 77 | -------------------------------------------------------------------------------- /SampleScreenShot/Image01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffStudio-PublicDev/UnityBridgeAppTracking/d3c3c34a653ed5a55e795fba1b0c53c240064aef/SampleScreenShot/Image01.png -------------------------------------------------------------------------------- /SampleScreenShot/Image02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffStudio-PublicDev/UnityBridgeAppTracking/d3c3c34a653ed5a55e795fba1b0c53c240064aef/SampleScreenShot/Image02.png -------------------------------------------------------------------------------- /SampleScreenShot/Image03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffStudio-PublicDev/UnityBridgeAppTracking/d3c3c34a653ed5a55e795fba1b0c53c240064aef/SampleScreenShot/Image03.png -------------------------------------------------------------------------------- /SampleScreenShot/Image04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffStudio-PublicDev/UnityBridgeAppTracking/d3c3c34a653ed5a55e795fba1b0c53c240064aef/SampleScreenShot/Image04.png -------------------------------------------------------------------------------- /SampleScreenShot/Image05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffStudio-PublicDev/UnityBridgeAppTracking/d3c3c34a653ed5a55e795fba1b0c53c240064aef/SampleScreenShot/Image05.png -------------------------------------------------------------------------------- /SampleScreenShot/Image06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffStudio-PublicDev/UnityBridgeAppTracking/d3c3c34a653ed5a55e795fba1b0c53c240064aef/SampleScreenShot/Image06.png -------------------------------------------------------------------------------- /SampleScreenShot/Image07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuffStudio-PublicDev/UnityBridgeAppTracking/d3c3c34a653ed5a55e795fba1b0c53c240064aef/SampleScreenShot/Image07.png --------------------------------------------------------------------------------