Skip to content

Commit 815521f

Browse files
committedAug 13, 2017
Add CMake script
Move game source to CppSource Update README Add LICENSE
1 parent b69ae7c commit 815521f

12 files changed

+170
-54
lines changed
 

‎.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Typical location for CMake build files and Visual Studio 2017 generated directories
2+
/cmake
3+
/NativeScript.dir
4+
/x64

‎LICENSE.txt

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Copyright 2017 Jackson Dunstan
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4+
5+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6+
7+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

‎README.md

+108-3
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,119 @@
22

33
A library to allow writing Unity scripts in native code: C, C++, assembly.
44

5+
# Reasons to Prefer C++ Over C# #
6+
7+
By using C++ directly, you gain complete control over the code the CPU will execute. It's much easier to generate optimal code with a C++ compiler than with a C# compiler, IL2CPP, and finally a C++ compiler. You can even code with compiler intrinsics or assembly to directly write machine code and take advantage of CPU features like [SIMD](http://jacksondunstan.com/articles/3890) and hardware AES encryption for massive performance gains.
8+
9+
C++ is also a much larger language than C# and some developers will prefer having more tools at their disposal. Here are a few differences:
10+
11+
* Its template system is much more powerful than C# generics
12+
* There are macros for extreme flexibility by generating code
13+
* Function pointers instead of just delegates
14+
* No-overhead [algorithms](http://en.cppreference.com/w/cpp/algorithm) instead of LINQ
15+
* Bit fields for easy memory savings
16+
* Pointers and never-null references instead of just managed referneces
17+
* Much more. C++ is huge.
18+
19+
There are also some problems with C# code running under Unity that you'll automatically avoid. For one, Unity's garbage collector is very slow. It runs on the main thread, which blocks rendering and input handling. It collects all objects at once, which causes frame hitches. And it fragments memory, so eventually you may run out and crash.
20+
21+
A significant amount of effort is required to work around the GC and the resulting code is difficult to maintain and slow. This includes techniques like [object pools](http://jacksondunstan.com/articles/3829), which essentially make memory management manual. You've also got to avoid boxing value types to managed types, `foreach` loops in some situations, and various other [gotchas](http://jacksondunstan.com/articles/3850).
22+
23+
C++ has no required garbage collector and features optional automatic memory management via "smart pointer" types like [shared_ptr](http://en.cppreference.com/w/cpp/memory/shared_ptr). It offers an excellent alternative to Unity's primitive garbage collector.
24+
25+
While IL2CPP transforms C# into C++ already, it generates a lot of overhead. There are many [surprises](http://jacksondunstan.com/articles/3916) if you read through the generated C++. For example, there's overhead for any function using a static variable and an extra two pointers are stored at the beginning of every class. The same goes for all sorts of features such as `sizeof()`, mandatory null checks, and so forth. Instead, you could write C++ directly and not need to work around IL2CPP.
26+
27+
This project aims to give you a viable alternative to C#. Scripting in C++ isn't right for every project, but now it's an option.
28+
29+
# Project Structure
30+
31+
When scripting in C++, C# is used only as a "binding" layer so Unity can call C++ functions and C++ functions can call the Unity API. A code generator is used to generate most of these bindings according to the needs of your project.
32+
33+
All of your code, plus a few bindings, will exist in a single "native" C++ plugin. When you change your C++ code, you'll build this plugin and then play the game in the editor or in a deployed build (e.g. to an Android device). There won't be any C# code for Unity to compile unless you run the code generator, which is infrequent.
34+
35+
The standard C# workflow looks like this:
36+
37+
1. Edit C# code in a C# IDE like MonoDevelop
38+
2. Switch to the Unity editor window
39+
3. Wait for the compile to finish (slow, "real" games take 5+ seconds)
40+
4. Run the game
41+
42+
With C++, the workflow looks like this:
43+
44+
1. Edit C++ code in a C++ IDE like Xcode or Visual Studio
45+
2. Build the C++ plugin (extremely fast, often under 1 second)
46+
3. Switch to the Unity editor window. Nothing to compile.
47+
4. Run the game
48+
49+
One of the project's goals is to make it just as easy to work with C++ as it is to work with C#, if not easier.
50+
51+
# Getting Started
52+
53+
1. Download or clone this repo
54+
2. Copy everything in `Unity/Assets` directory to your Unity project's `Assets` directory
55+
3. Edit `NativeScriptTypes.json` and specify what parts of the Unity API you want access to from C++. Some examples are provided, but feel free to delete them if you're not using those features.
56+
4. Edit `CppSource/Game.cpp` to create your game. Some example code is provided, but feel free to delete it. You can add more C++ source (`.cpp`) and header (`.h`) files here as your game grows.
57+
58+
# Building the C++ Plugin
59+
60+
## iOS
61+
62+
There's nothing to do for iOS!
63+
64+
## macOS (Editor and Standalone)
65+
66+
1. Install [CMake](https://cmake.org/) version 3.6 or greater
67+
2. Create a directory for build files. Anywhere is fine.
68+
3. Open the Terminal app in `/Applications/Utilities`
69+
4. Execute `cd /path/to/your/build/directory`
70+
5. Execute `cmake -G "MyGenerator" /path/to/your/project/Assets`. Replace `MyGenerator` with the generator of your choice. To see the options, execute `cmake --help` and look at the list at the bottom. Common choices include "Unix Makefiles" to build from command line or "Xcode" to use Apple's IDE.
71+
6. The build scripts or IDE project files are now generated in your build directory
72+
7. Build as appropriate for your generator. For example, execute `make` if you chose `Unix Makefiles` as your generator or open `NativeScript.xcodeproj` and click `Product > Build` if you chose Xcode.
73+
74+
## Windows (Editor and Standalone)
75+
76+
1. Install [CMake](https://cmake.org/) version 3.6 or greater
77+
2. Create a directory for build files. Anywhere is fine.
78+
3. Open a Command Prompt by clicking the Start button, typing "Command Prompt", then clicking the app
79+
4. Execute `cd /path/to/your/build/directory`
80+
5. Execute `cmake -G "Visual Studio VERSION YEAR Win64" /path/to/your/project/Assets`. Replace `VERSION` and `YEAR` with the version of Visual Studio you want to use. To see the options, execute `cmake --help` and look at the list at the bottom. For example, use `"`Visual Studio 15 2017 Win64` for Visual Studio 2017. Any version, including Community, works just fine.
81+
6. The project files are now generated in your build directory
82+
7. Open `NativeScript.sln` and click `Build > Build Solution`.
83+
84+
## Linux (Editor and Standalone)
85+
86+
1. Install [CMake](https://cmake.org/) version 3.6 or greater
87+
2. Create a directory for build files. Anywhere is fine.
88+
3. Open a terminal as appropriate for your Linux distribution
89+
4. Execute `cd /path/to/your/build/directory`
90+
5. Execute `cmake -G "MyGenerator" /path/to/your/project/Assets`. Replace `MyGenerator` with the generator of your choice. To see the options, execute `cmake --help` and look at the list at the bottom. The most common choice is "Unix Makefiles" to build from command line, but there are IDE options too.
91+
6. The build scripts or IDE project files are now generated in your build directory
92+
7. Build as appropriate for your generator. For example, execute `make` if you chose `Unix Makefiles` as your generator.
93+
94+
## Android
95+
96+
1. Install [CMake](https://cmake.org/) version 3.6 or greater
97+
2. Create a directory for build files. Anywhere is fine.
98+
3. Open a terminal (macOS, Linux) or Command Prompt (Windows)
99+
4. Execute `cd /path/to/your/build/directory`
100+
5. Execute `cmake -G MyGenerator -DANDROID_NDK=/path/to/android/ndk /path/to/your/project/Assets`. Replace `MyGenerator` with the generator of your choice. To see the options, execute `cmake --help` and look at the list at the bottom. To make a build for any platform other than Android, omit the `-DANDROID_NDK=/path/to/android/ndk` part.
101+
6. The build scripts or IDE project files are now generated in your build directory
102+
7. Build as appropriate for your generator. For example, execute `make` if you chose `Unix Makefiles` as your generator.
103+
104+
# Updating To A New Version
105+
106+
To update to a new version of this project, overwrite your Unity project's `Assets/NativeScript` directory with this project's `Unity/Assets/NativeScript` directory.
107+
5108
# Reference
6109

7-
[Articles by the author](http://jacksondunstan.com/articles/3938)
110+
[Articles](http://jacksondunstan.com/articles/3938) by the author describing the development of this project.
8111

9112
# Author
10113

11-
[Jackson Dunstan](http://JacksonDunstan.com)
114+
[Jackson Dunstan](http://jacksondunstan.com)
12115

13116
# License
14117

15-
[MIT](https://opensource.org/licenses/MIT)
118+
All code is licensed [MIT](https://opensource.org/licenses/MIT), which means it can usually be easily used in commercial and non-commercial applications.
119+
120+
All writing is licensed [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which means it can be used as long as attribution is given.

‎Unity/.gitignore

+5-1
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,8 @@ sysinfo.txt
3535

3636
# Builds
3737
*.apk
38-
*.unitypackage
38+
*.unitypackage
39+
40+
# NativeScript plugins
41+
/Assets/Plugins
42+
/Assets/Plugins.meta

‎Unity/Assets/CMakeLists.txt

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
cmake_minimum_required( VERSION 3.6.0 FATAL_ERROR )
2+
set( CMAKE_INCLUDE_CURRENT_DIR ON )
3+
if ( ANDROID_NDK )
4+
set( ANDROID_ABI armeabi-v7a )
5+
set( CMAKE_TOOLCHAIN_FILE ${ANDROID_NDK}/build/cmake/android.toolchain.cmake )
6+
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/Plugins/Android )
7+
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/Plugins/Android )
8+
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/Plugins/Android )
9+
else()
10+
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/Plugins )
11+
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/Plugins )
12+
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/Plugins )
13+
endif( )
14+
include_directories( ${CMAKE_SOURCE_DIR}/NativeScript ${CMAKE_SOURCE_DIR}/CppSource )
15+
project( NativeScript CXX )
16+
file(GLOB GAMESOURCEFILES ${CMAKE_SOURCE_DIR}/CppSource/*.cpp)
17+
set( SOURCES
18+
${GAMESOURCEFILES}
19+
NativeScript/Bindings.h
20+
NativeScript/Bindings.cpp )
21+
add_library( ${PROJECT_NAME} MODULE ${SOURCES} )
22+
set_target_properties( ${PROJECT_NAME} PROPERTIES BUNDLE TRUE )
23+
24+
# Enable C++11
25+
target_compile_features( ${PROJECT_NAME} PRIVATE cxx_range_for )

‎Unity/Assets/CMakeLists.txt.meta

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Unity/Assets/CppSource.meta

+9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
File renamed without changes.
File renamed without changes.

‎Unity/Assets/NativeScript.bundle.meta

-46
This file was deleted.

‎Unity/Assets/NativeScriptConstants.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ public static class NativeScriptConstants
1919
/// Path to load the plugin from when running inside the editor
2020
/// </summary>
2121
#if UNITY_EDITOR_OSX
22-
public const string PluginPath = "/NativeScript.bundle/Contents/MacOS/NativeScript";
22+
public const string PluginPath = "/Plugins/NativeScript.bundle/Contents/MacOS/NativeScript";
2323
#elif UNITY_EDITOR_LINUX
24-
public const string PluginPath = "/NativeScript.so";
24+
public const string PluginPath = "/Plugins/NativeScript.so";
2525
#elif UNITY_EDITOR_WIN
26-
public const string PluginPath = "/NativeScript.dll";
26+
public const string PluginPath = "/Plugins/NativeScript.dll";
2727
#endif
2828

2929
/// <summary>

‎Unity/Assets/Plugins.meta

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
Please sign in to comment.