Skip to content

Commit b1a7efa

Browse files
authored
Merge pull request #6 from handsomecode/enh/config_file
Update configuration file and refresh mechanism
2 parents 41d9b85 + d28f551 commit b1a7efa

File tree

16 files changed

+533
-734
lines changed

16 files changed

+533
-734
lines changed

README.md

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -35,46 +35,30 @@ make
3535
```
3636

3737
## Usage
38-
### To generate a new project
39-
Currently, Unity needs to be closed for this process to begin.
38+
### To generate new iOS and Unity projects
39+
_Currently, Unity needs to be closed for this process to begin._
4040

4141
1. Create a top-level folder and navigate to it. This folder will contain all information about the Xcode and Unity projects. (_Note: By default, the name of this folder will be the name of the Xcode and Unity projects._)
4242
```
4343
mkdir ExampleProject
4444
cd ExampleProject
4545
```
4646

47-
2. Run the following to generate the `ubconfig.json` file where you can specify project names and paths
47+
2. Run the following to generate the `ubconfig.json` file where you can specify project information
4848
```
49-
UnityBuildKit init
49+
UnityBuildKit config
5050
```
5151

5252
3. After filling out the config file information, run
5353
```
5454
$ UnityBuildKit generate
5555
```
5656

57-
4. Once generation is complete, open the Xcode project. Using the Build Scheme drop down menu, select Edit Scheme to edit your project's scheme (the scheme should be the same name as your project). Select the Run action then the Options tab. In the middle of the window, you will see `Metal API Validation` with a set of options in a drop down menu. Change the current option to `Disabled`, as seen below:
58-
![](Assets/metal_validation_scheme.png)
59-
_(Note: if you do not see the option for Metal API Validation, verify your run destination is a physical device of set to Generic iOS Device)_
60-
6157
#### Notes
62-
- The generation script sets up the Unity project to build for the Device SDK. These means that, if building for a simulator, there is a high probability that you will encounter build and linker errors in Xcode. Change the run destination to a physical device and the errors should go away.
63-
64-
- If building for a physical device, do not forget to set up your code signing.
65-
66-
### To refresh the Xcode project
67-
After making updates to your Unity project, you'll need to refresh the files linked with the Xcode project. Currently, Unity needs to be closed for this process to begin.
58+
- The generation script sets up the Unity project to build for the Device SDK. These means that, if building for a simulator, there is a high probability that you will encounter build and linker errors in Xcode. Change the run destination to a physical device and the errors should go away. You can change this in Unity using the Build Settings once generation is completed.
6859

69-
1. Navigate to the top-level folder
70-
```
71-
cd ExampleProject
72-
```
73-
74-
2. Run
75-
```
76-
UnityBuildKit refresh
77-
```
60+
### Refreshing the projects
61+
The iOS project is automatically updated and refreshed every time the Unity project is built. You shouldn't need to do anything! 😀
7862

7963
## Known Unity Version Compatibility
8064
- 2107.1.f1
@@ -86,7 +70,7 @@ This tool is built using:
8670

8771
and the wonderful dependencies they bring with them.
8872

89-
Inspiration for building `UnityBuildKit` came after running into several problems while trying to [manually do this process](https://the-nerd.be/2015/11/13/integrate-unity-5-in-a-native-ios-app-with-xcode-7/) and reading over a [github issue](https://github.com/blitzagency/ios-unity5/issues/52) trying to resolve those problems.
73+
Inspiration for building `UnityBuildKit` came after running into several problems while trying to [manually do this process](https://the-nerd.be/2015/11/13/integrate-unity-5-in-a-native-ios-app-with-xcode-7/) and reading over a [github issue](https://github.com/blitzagency/ios-unity5/issues/52) trying to resolve those problems (big thanks to [jiulongw](https://github.com/jiulongw/swift-unity)).
9074

9175
## License
9276

Sources/UBKit/Files/Config/config.swift renamed to Sources/UBKit/Files/Config/configFile.swift

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// config.swift
2+
// configFile.swift
33
//
44
// Copyright (c) 2017 Handsome
55
//
@@ -28,11 +28,20 @@ extension File {
2828
class func configFile() -> Data? {
2929
let file = """
3030
{
31-
"project_name": "",
32-
"bundle_id": "<com.example.project_name>",
33-
"unity_path": "<path_to_Unity>",
34-
"unity_version": "",
35-
"unity_scene_name": ""
31+
"ios": {
32+
"projectName": "ExampleProject",
33+
"bundleId": "com.example.ExampleProject",
34+
"projectPath": "" // Defaults to iOS/
35+
},
36+
"unity": {
37+
"projectName": "ExampleProject",
38+
"applicationPath": "", // e.g /Applications/Unity/Unity.app/Contents/MacOS/Unity
39+
"version": "", // e.g. 2017.1.f1
40+
"projectPath": "", // Defaults to Unity/
41+
"sceneNames": [
42+
"ExampleScene"
43+
]
44+
}
3645
}
3746
""".data(using: .utf8)
3847
return file

Sources/UBKit/Files/Unity/UnityEditorScript.swift renamed to Sources/UBKit/Files/Unity/UnityEditorBuildScript.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// UnityEditorScript.swift
2+
// UnityEditorBuildScript.swift
33
//
44
// Copyright (c) 2017 Handsome
55
//
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
//
2+
// UnityProjectScript.swift
3+
// UnityBuildKitPackageDescription
4+
//
5+
// Copyright (c) 2017 Handsome
6+
//
7+
// Permission is hereby granted, free of charge, to any person obtaining a copy
8+
// of this software and associated documentation files (the "Software"), to deal
9+
// in the Software without restriction, including without limitation the rights
10+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
// copies of the Software, and to permit persons to whom the Software is
12+
// furnished to do so, subject to the following conditions:
13+
//
14+
// The above copyright notice and this permission notice shall be included in all
15+
// copies or substantial portions of the Software.
16+
//
17+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
// SOFTWARE.
24+
25+
import Foundation
26+
27+
extension File {
28+
29+
class func unityProjectScriptFile(projectName: String, iOSProjectPath: String) -> Data? {
30+
let file = """
31+
using System.Linq;
32+
using System.Collections.Generic;
33+
using System.IO;
34+
using System.Text;
35+
using UnityEngine;
36+
using UnityEditor;
37+
using UnityEditor.Callbacks;
38+
using UnityEditor.iOS.Xcode;
39+
40+
public class XcodeRefresher {
41+
42+
private const string iOSProjectRoot = \"\(iOSProjectPath)\";
43+
private const string iOSProjectName = \"\(projectName)\";
44+
private const string ClassesProjectPath = "Vendor/UBK/Classes";
45+
private const string LibrariesProjectPath = "Vendor/UBK/Libraries";
46+
private const string PbxFilePath = iOSProjectName + ".xcodeproj/project.pbxproj";
47+
48+
public static void Refresh() {
49+
var pathToBuiltProject = GetArg ("-buildPath");
50+
UpdateUnityProjectFiles (pathToBuiltProject);
51+
}
52+
53+
#if UNITY_IOS
54+
[PostProcessBuild]
55+
public static void OnPostBuild(BuildTarget target, string pathToBuiltProject) {
56+
UpdateUnityProjectFiles(pathToBuiltProject);
57+
}
58+
#endif
59+
60+
private static void UpdateUnityProjectFiles(string pathToBuiltProject) {
61+
var pbx = new PBXProject();
62+
var pbxPath = Path.Combine(iOSProjectRoot, PbxFilePath);
63+
pbx.ReadFromFile(pbxPath);
64+
65+
ProcessUnityDirectory(
66+
pbx,
67+
Path.Combine(pathToBuiltProject, "Classes"),
68+
Path.Combine(iOSProjectRoot, ClassesProjectPath),
69+
ClassesProjectPath);
70+
71+
ProcessUnityDirectory(
72+
pbx,
73+
Path.Combine(pathToBuiltProject, "Libraries"),
74+
Path.Combine(iOSProjectRoot, LibrariesProjectPath),
75+
LibrariesProjectPath);
76+
77+
pbx.WriteToFile(pbxPath);
78+
}
79+
80+
/// <summary>
81+
/// Update pbx project file by adding src files and removing extra files that
82+
/// exists in dest but not in src any more.
83+
///
84+
/// This method only updates the pbx project file. It does not copy or delete
85+
/// files in Swift Xcode project. The Swift Xcode project will do copy and delete
86+
/// during build, and it should copy files if contents are different, regardless
87+
/// of the file time.
88+
/// </summary>
89+
/// <param name="pbx">The pbx project.</param>
90+
/// <param name="src">The directory where Unity project is built.</param>
91+
/// <param name="dest">The directory of the Swift Xcode project where the
92+
/// Unity project is embedded into.</param>
93+
/// <param name="projectPathPrefix">The prefix of project path in Swift Xcode
94+
/// project for Unity code files. E.g. "DempApp/Unity/Classes" for all files
95+
/// under Classes folder from Unity iOS build output.</param>
96+
private static void ProcessUnityDirectory(PBXProject pbx, string src, string dest, string projectPathPrefix) {
97+
var targetGuid = pbx.TargetGuidByName(iOSProjectName);
98+
99+
string[] newFiles, extraFiles;
100+
CompareDirectories(src, dest, out newFiles, out extraFiles);
101+
102+
foreach (var f in newFiles) {
103+
var projPath = Path.Combine(projectPathPrefix, f);
104+
if (!pbx.ContainsFileByProjectPath(projPath)) {
105+
var guid = pbx.AddFile(Path.Combine(src, f), projPath, PBXSourceTree.Absolute);
106+
pbx.AddFileToBuild(targetGuid, guid);
107+
108+
Debug.LogFormat("Added file to pbx: '{0}'", projPath);
109+
}
110+
}
111+
112+
foreach (var f in extraFiles) {
113+
var projPath = Path.Combine(projectPathPrefix, f);
114+
if (pbx.ContainsFileByProjectPath(projPath)) {
115+
var guid = pbx.FindFileGuidByProjectPath(projPath);
116+
pbx.RemoveFile(guid);
117+
118+
Debug.LogFormat("Removed file from pbx: '{0}'", projPath);
119+
}
120+
}
121+
}
122+
123+
/// <summary>
124+
/// Compares the directories. Returns files that exists in src and
125+
/// extra files that exists in dest but not in src any more.
126+
/// </summary>
127+
private static void CompareDirectories(string src, string dest, out string[] srcFiles, out string[] extraFiles) {
128+
srcFiles = GetFilesRelativePath(src);
129+
130+
var destFiles = GetFilesRelativePath(dest);
131+
var extraFilesSet = new HashSet<string>(destFiles);
132+
133+
extraFilesSet.ExceptWith(srcFiles);
134+
extraFiles = extraFilesSet.ToArray();
135+
}
136+
137+
private static string[] GetFilesRelativePath(string directory) {
138+
var results = new List<string>();
139+
140+
if (Directory.Exists(directory)) {
141+
foreach (var path in Directory.GetFiles(directory, "*", SearchOption.AllDirectories)) {
142+
var relative = path.Substring(directory.Length).TrimStart('/');
143+
results.Add(relative);
144+
}
145+
}
146+
147+
return results.ToArray();
148+
}
149+
150+
private static string GetArg(string name) {
151+
var args = System.Environment.GetCommandLineArgs();
152+
for (int i = 0; i < args.Length; i++) {
153+
if (args [i] == name && args.Length > i + 1) {
154+
return args [i + 1];
155+
}
156+
}
157+
return null;
158+
}
159+
}
160+
""".data(using: .utf8)
161+
return file
162+
}
163+
}

Sources/UBKit/Files/Xcode/SpecFile.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ extension File {
4343
sources:
4444
- \(projectName)
4545
- Vendor
46+
postbuildScripts:
47+
- script: rm -rf "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Data"\\ncp -Rf "$UNITY_IOS_EXPORT_PATH/Data" "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Data"
48+
name: UnityBuildKit Postbuild
4649
settings:
4750
PRODUCT_BUNDLE_IDENTIFIER: \(bundleIdentifier)
4851
IOS_DEPLOYMENT_TARGET: 11.0
@@ -58,7 +61,7 @@ extension File {
5861
OTHER_CFLAGS: $(inherited) -DINIT_SCRIPTING_BACKEND=1 -fno-strict-overflow -DRUNTIME_IL2CPP=1
5962
CLANG_CXX_LANGUAGE_STANDARD: c++11
6063
CLANG_CXX_LIBRARY: libc++
61-
SWIFT_OBJC_BRIDGING_HEADER: UnityBridge.h
64+
SWIFT_OBJC_BRIDGING_HEADER: UnityBuildKit/UnityBridge/UnityBridge.h
6265
CLANG_ENABLE_MODULES: NO
6366
CLANG_WARN_BOOL_CONVERSION: NO
6467
CLANG_WARN_CONSTANT_CONVERSION: NO

0 commit comments

Comments
 (0)