Tuesday, 26 May 2020

How to use Git & GitHub for Unity projects

In this tutorial, I will outline how to use Git/GitHub to provide source/version control service for Unity projects.

Challenges & Solution

There are 2 main challenges to using Git & GitHub for Unity projects:
  1. Unity projects create lots of temporary & internal-used files, which should be excluded from the source control system. The ".gitignore" mechanism of Git could be configured to solve this in the prefect way, i.e., exclude unwanted files from Git;
  2. Unity project contains lots of binary format files, esp. large binary files, which are difficult to be tracked by the source control systems. To solve this challenge, 2 following methods should be deployed side by side:
    • Configure Unity project to use text format instead of binary format if possible
    • Use Git LFS(Git Large File Storage) service to track these large binary files such as images, audios, 3d models and etc

How-to guide

1. Prepare

  • install & config Git
  • setup GitHub account
  • install Git LFS (Git LFS has been included in Git for Windows)
  • your Unity project waiting for version control

2. Config Unity Project

You may check the following settings of the Unity project - "Edit > Project Settings > Editor":
  • "Version Control > Mode" should be "Visible Meta Files"
  • "Asset Serialization > Mode" should be "Force Text"
In general, I found the default settings of Unity 2018 or later should be correct for version control.

3. Config Git for Unity Project

You create the file ".gitignore" as follows and put it at the root directory of the Unity project:

# This .gitignore file should be placed at the root of your Unity project directory
#
# Get latest from https://github.com/github/gitignore/blob/master/Unity.gitignore
#
/[Ll]ibrary/
/[Tt]emp/
/[Oo]bj/
/[Bb]uild/
/[Bb]uilds/
/[Ll]ogs/
/[Uu]ser[Ss]ettings/

# MemoryCaptures can get excessive in size.
# They also could contain extremely sensitive data
/[Mm]emoryCaptures/

# Asset meta data should only be ignored when the corresponding asset is also ignored
!/[Aa]ssets/**/*.meta

# Uncomment this line if you wish to ignore the asset store tools plugin
# /[Aa]ssets/AssetStoreTools*

# Autogenerated Jetbrains Rider plugin
/[Aa]ssets/Plugins/Editor/JetBrains*

# Visual Studio cache directory
.vs/

# Gradle cache directory
.gradle/

# Autogenerated VS/MD/Consulo solution and project files
ExportedObj/
.consulo/
*.csproj
*.unityproj
*.sln
*.suo
*.tmp
*.user
*.userprefs
*.pidb
*.booproj
*.svd
*.pdb
*.mdb
*.opendb
*.VC.db

# Unity3D generated meta files
*.pidb.meta
*.pdb.meta
*.mdb.meta

# Unity3D generated file on crash reports
sysinfo.txt

# Builds
*.apk
#*.unitypackage

# Crashlytics generated file
crashlytics-build.properties

# Packed Addressables
/[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin*

# Temporary auto-generated Android Assets
/[Aa]ssets/[Ss]treamingAssets/aa.meta
/[Aa]ssets/[Ss]treamingAssets/aa/*


# Ignore some common files for Windows
#
# Get latest from https://github.com/github/gitignore/blob/master/Global/Windows.gitignore
#
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db

# Dump file
*.stackdump

# Folder config file
[Dd]esktop.ini

# Recycle Bin used on file shares
$RECYCLE.BIN/

# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp

# Windows shortcuts
*.lnk

Note - this sample ".gitignore" file contains:
  • common files for Unity projects should be ignored
  • common files for Windows should be ignored

4. Config Git LFS for Unity Project

4.1 Activate Git LFS
You need to activate Git LFS as follows, only need run this once per user account:

$ git lfs install
verify that the installation was successful:

> Git LFS initialized.

4.2 ".gitattributes"
You create the file ".gitattributes" as follows and put it at the root directory of the Unity project:

# Git LFS tracking file list:
# 3D models
*.3dm filter=lfs diff=lfs merge=lfs -text
*.3ds filter=lfs diff=lfs merge=lfs -text
*.blend filter=lfs diff=lfs merge=lfs -text
*.c4d filter=lfs diff=lfs merge=lfs -text
*.collada filter=lfs diff=lfs merge=lfs -text
*.dae filter=lfs diff=lfs merge=lfs -text
*.dxf filter=lfs diff=lfs merge=lfs -text
*.fbx filter=lfs diff=lfs merge=lfs -text
*.jas filter=lfs diff=lfs merge=lfs -text
*.lws filter=lfs diff=lfs merge=lfs -text
*.lxo filter=lfs diff=lfs merge=lfs -text
*.ma filter=lfs diff=lfs merge=lfs -text
*.max filter=lfs diff=lfs merge=lfs -text
*.mb filter=lfs diff=lfs merge=lfs -text
*.obj filter=lfs diff=lfs merge=lfs -text
*.ply filter=lfs diff=lfs merge=lfs -text
*.skp filter=lfs diff=lfs merge=lfs -text
*.stl filter=lfs diff=lfs merge=lfs -text
*.ztl filter=lfs diff=lfs merge=lfs -text
# Audio
*.aif filter=lfs diff=lfs merge=lfs -text
*.aiff filter=lfs diff=lfs merge=lfs -text
*.it filter=lfs diff=lfs merge=lfs -text
*.mod filter=lfs diff=lfs merge=lfs -text
*.mp3 filter=lfs diff=lfs merge=lfs -text
*.ogg filter=lfs diff=lfs merge=lfs -text
*.s3m filter=lfs diff=lfs merge=lfs -text
*.wav filter=lfs diff=lfs merge=lfs -text
*.xm filter=lfs diff=lfs merge=lfs -text
# Fonts
*.otf filter=lfs diff=lfs merge=lfs -text
*.ttf filter=lfs diff=lfs merge=lfs -text
# Images
*.bmp filter=lfs diff=lfs merge=lfs -text
*.exr filter=lfs diff=lfs merge=lfs -text
*.gif filter=lfs diff=lfs merge=lfs -text
*.hdr filter=lfs diff=lfs merge=lfs -text
*.iff filter=lfs diff=lfs merge=lfs -text
*.jpeg filter=lfs diff=lfs merge=lfs -text
*.jpg filter=lfs diff=lfs merge=lfs -text
*.pict filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.psd filter=lfs diff=lfs merge=lfs -text
*.tga filter=lfs diff=lfs merge=lfs -text
*.tif filter=lfs diff=lfs merge=lfs -text
*.tiff filter=lfs diff=lfs merge=lfs -text
# Unity packages
*.unitypackage filter=lfs diff=lfs merge=lfs -text

# Collapse Unity-generated files on GitHub
*.asset linguist-generated
*.mat linguist-generated
*.meta linguist-generated
*.prefab linguist-generated
*.unity linguist-generated

Note - this sample ".gitattributes" file contains:
  • Git LFS tracking file types that Unity currently supports
  • automatically collapsing the diffs on GitHub for Unity-generated files
  • see more details

Alternatively, you may configure additional file types at anytime, such as:

$ git lfs track "*.jpg"

4.3 Verify Git LFS
You may verify which files are being tracked as Git LFS files:

$ git lfs ls-files

5. Initial Commit

After all of Unity project, Git and Git LFS are configured, you can startup Git version control with Unity project as usual.

Just run the following Git commands under the root directory of Unity project:

$ git init
$ git add .
$ git commit -m 'Initial commit'
$ git log

Note:
  • start a Git repo
  • add all source files into staging area(index)
  • make initial commit
  • show commit log

6. Upload to GitHub

  1. login in your GitHub account
  2. create a new repository for Unity project - "Click the top-right-corner plus-sign button > New repository"
  3. copy the new repo url - "repository page > click Clone or download button > click copy button"
  4. run the following commands to upload Unity project to GitHub repo at the first time:
  5. $ git remote add origin <repo_url>
    $ git remote -v
    $ git push -u origin master
    $ git log
    
    
    Note:
    • config remote for the new repo
    • show remote repositories
    • upload Unity source files to remote repo
    • show commit log
  6. run the following command to update Unity project's GitHub repo later on:
  7. $ git push

7. Well done, finished!


References

Wednesday, 1 January 2020

How to Configure Visual Studio Code for C++ Development

In this tutorial, I provide the configuration details to setup a simple, modern C++ development environment:
  • Visual Studio Code as editor
  • Microsoft C++ compiler (msvc)
  • C++17
  • UTF-encoding source code
  • MS Windows 10 OS

Configure Steps

1. Install Tool-sets

  1. Install Visual Studio Code (version 1.41.1)
  2. Install C++ extension for VS Code (version 0.26.3)
  3. Install Microsoft C++ compiler tool-set, i.e., install either of the following tools:

2. Config C++ Project

  1. create an empty folder, for example, called "project", this is used to store all files for a VS Code project
  2. create an sub-folder called "debug" under "project" folder, this is used to store compiler producing files
  3. create an sub-folder called ".vscode" under "project" folder, this is used to store VS Code config files
  4. create 3 configure files of VS Code under "project/.vscode" folder:
    • c_cpp_properties.json
    • {
          "configurations": [
              {
                  "name": "Win32",
                  "includePath": [
                      "${workspaceFolder}/**"
                  ],
                  "defines": [
                      "_DEBUG",
                      "UNICODE",
                      "_UNICODE"
                  ],
                  "windowsSdkVersion": "10.0.18362.0",
                  "compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.23.28105/bin/Hostx64/x64/cl.exe",
                  "cStandard": "c11",
                  "cppStandard": "c++17",
                  "intelliSenseMode": "${default}"
              }
          ],
          "version": 4
      }
      
      Note:
      • this configure file is for configuring compiler path and IntelliSense settings
      • the value of "compilerPath" may be adjusted based on your installation options for MS C++ compiler tool-set accordingly
      • the value of "cppStandard" is C++17, this configures VS Code source code editor accordingly
    • launch.json
    • {
        "version": "0.2.0",
        "configurations": [
          {
            "name": "(msvc) Launch",
            "type": "cppvsdbg",
            "request": "launch",
            "program": "${workspaceFolder}/debug/app.exe",
            "args": [],
            "stopAtEntry": true,
            "cwd": "${workspaceFolder}/debug",
            "environment": [],
            "externalConsole": false
          }
        ]
      }
      
      Note:
      • this configure file is for configuring MS C++ debugger
      • the executable file is configured as "app.exe", this may be adjusted based on your project needs accordingly
    • tasks.json
    • {
        "version": "2.0.0",
        "tasks": [
          {
            "label": "msvc build",
            "type": "shell",
            "command": "cl.exe",
            "args": ["/EHsc", "/Zi", "/std:c++17", "/utf-8", "/Fe:", "app.exe", "../*.cpp"],
            "options": {
              "cwd": "${workspaceRoot}/debug"
            },
            "group": {
              "kind": "build",
              "isDefault": true
            },
            "presentation": {
              "reveal": "always",
              "focus": true
            },
            "problemMatcher": "$msCompile"
          },
          {
            "label": "clean build",
            "type": "shell",
            "command": "del",
            "args": ["/Q", "*"],
            "options": {
              "cwd": "${workspaceRoot}/debug"
            },
            "group": "build",
            "presentation": {
              "reveal": "always",
              "focus": true
            },
            "problemMatcher": "$msCompile"
          },
          {
            "label": "run build",
            "type": "shell",
            "command": "app.exe",
            "options": {
              "cwd": "${workspaceRoot}/debug"
            },
            "dependsOn": [
              "msvc build"
            ],
            "group": {
              "kind": "test",
              "isDefault": true
            },
            "presentation": {
              "reveal": "always"
            }
          }
        ]
      }
      
      Note:
      • this configure file is for configuring build instructions, including build/clean/run tasks
      • the executable file is configured as "app.exe", this may be adjusted based on your project needs accordingly
      • quick explanation for the compile arguments of "msvc build" task:
        • /EHsc - specify the exception handling mode
        • /Zi - produce a debug build with symbols
        • /std:c++17 - enable C++17 standard-specific features and behavior explicitly, preferable than /std:c++latest due to long-term maintenance
        • /utf-8 - set source and execution character sets to UTF-8
        • /Fe: - specify the executable file name

Work with C++ Project

  1. start "Developer Command Prompt for VS 2019", this is required for msvc
  2. from the developer command prompt, navigate into the folder "project", and start VS Code under the folder "project"
  3. > cd project
    > code .
    
  4. create a C++ source code under the folder "project" with VS Code, for example, let's create the following sample C++ source code "helloworld.cpp"
  5. #include <iostream>
    
    using namespace std;
    
    int main() {
     cout << "Hello, world!" << endl;
    
     return 0;
    }
    
  6. compile C++ code by either one of the following methods:
    • press the shortcut key: ctrl + shift + b
    • run tasks: msvc build
    Note:
    • The executable file "app.exe" will be generated by msvc under the subfolder "debug" if everything works properly
    • different methods to run task in VS Code:
      • press the shortcut key: F1 to access the command palette of VS Code, and then choose the desired task to run
      • press the shortcut key: ctrl + shift + p to access the command palette of VS Code, and then choose the desired task to run
      • through the menu of VS Code: terminal > run task, and then choose the desired task to run
  7. compile C++ code and then run the executable file with a single task:
    • run tasks: run build
  8. start debugging:
    • press the shortcut key: F5 to access the debugger GUI of VS Code
  9. clean up all of last build generated files:
    • run tasks: clean build

References