Quick Bites 02 : Local Syncing Projects

Quick Bites 02 : Local Syncing Projects

The following Quick Bites is only applicable to MAC people…  You might be able to get it working on Windows, but I have never tried so don’t blame me if it deletes your whole project.

When testing multiplayer games, you generally need to simulate more than one client simultaneously. In Unity there’s no ‘Super Easy Unity-Esque™’ way of doing this. You have to resort to old school methods like actually building a client (shock) to test with and run that alongside your editor session. If you’re thinking you could open 2 copies of Unity, point them to the project folder and then you’ve got 2 clients. Well you’re half way to the answer. The only problem is Unity likes to be in control of its directories. If another Unity comes along and starts changing the  library folder, it’s going to get mighty pissed off and probably crash to desktop.

Read on for the full workaround for this.

 

  • NOTE : Even if you don’t use version control, version control needs to be set to META files for this sync operation to work properly. (It will work, (sort of) without doing this, but scene files wont always sync correctly and you’ll have a much better time with it enabled.

Add the script (code at the end of the post) to your project in an editor folder then hit up the new menu option Quick Fingers/Sync/Force Sync Now.

What this does is create a duplicate copy of your project right next to the current one. (The only difference being the 2nd project folder will have ‘Copy’ appended to it) Like so :

 

Hmm I wonder what project I could be working on...

Hmm I wonder what project I could be working on…

 

(It uses rsync internally which is included on the Mac. If you are on Windows you can probably still get this to work if rsync exists for Windows and you change the Process.Start line to refer to the path to where rsync is located. Again, this is untested on Windows so backup before doing any experimenting).

Now you have 2 seperate projects you can open a 2nd Unity Instance and run them side by side. 

To do this open Preferences within Unity and make sure the following option is checked :

 

Make sure this is checked, otherwise expect pain.

Make sure this is checked, otherwise expect pain.

 

Now you need to open a 2nd instance of Unity. Simply run the terminal command ‘open -n /Applications/Unity/Unity.app’ or if you’d rather not do that every time you need it. Here is a handy application you can download to do exactly that.

Download New Unity Instance App

 

(If you installed Unity to a non standard directory, simply open the New Unity Instance.app in Applescript Editor and change the path to Unity in there) 

Now when you open your 2nd copy of Unity. The project wizard will pop up, make sure to open the Project COPY.

So far you should have 1 Unity open with the main project (the master) and 1 Unity open with the copy (the slave).

Now in the Master goto the ‘Quick Fingers -> Sync -> Enable Project Syncing’ menu option (this enabled the automatic syncing). Now every time  the master Unity recompiles (when any file changes and it gets focus),  the slave will sync up in nano seconds. (rsync is seriously quick).

This will make debugging multiplayer games waaaay easier as you have 2 full editor views, so console commands are readable as are inspectors and you can pause mid game on either. So there we go!

 

IMPORTANT NOTES
  • Always make edits in the master project (Not the copy).  Consider the Copy a slave you use just for playback and debugging. (If you accidentally start editing the slave, your changes will be overwritten the next time you edit the master). I find it helps to use different window layouts for each Unity instance,  my normal layout for the master, and a more minimal layout for the slave so I can tell at a glance which one I’m looking at)

  • If you use version control you might want to exlude version control folders from the slave project. (This is done automatically with the script as is for GIT repositories)

  • Do not open the same project in 2 seperate Unity instances. They will fight for library control. (This is the whole reason we need to make and maintain a copy)

  • Don’t forget to enable Run in Background on your Unity project Player Settings! (Although if your making a multiplayer game you’ve probably already done that)

 

Code drop time! Thanks for reading and hope this is helpful to some of you.

 

AssetPostProcessSync class
using System.Diagnostics;
using UnityEditor;
using UnityEngine;
using Debug = UnityEngine.Debug;
 
public class AssetPostProcessSync : AssetPostprocessor {
 
	[MenuItem("Quick Fingers/Sync/Enable Project Syncing")]
	public static void EnableProjectSyncing() {
		EditorPrefs.SetBool("ProjectSyncing", true);
        Debug.Log("Automatic Project Syncing ENABLED");
	}
 
	[MenuItem("Quick Fingers/Sync/Disable Project Syncing")]
	public static void DisableProjectSyncing() {
		EditorPrefs.SetBool("ProjectSyncing", false);
        Debug.Log("Automatic Project Syncing DISABLED");
	}
 
    [MenuItem("Quick Fingers/Sync/Force Sync Now")]
    private static void Sync() {
        if (Application.dataPath.IndexOf("Copy", System.StringComparison.Ordinal) == -1) {
            string dataPath = Application.dataPath.Substring(0, Application.dataPath.LastIndexOf('/'));
            Process.Start("rsync", "-a --delete --exclude='.git' " + dataPath + "/ " + dataPath + "Copy/");
        }
    }
 
    protected static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) {
        if (!EditorPrefs.HasKey("ProjectSyncing")) return;
        if (!EditorPrefs.GetBool("ProjectSyncing")) return;
        Sync();
    }
}