Browsed by
Category: Unity

Stop Unity from compiling every time you save a script in Visual Studio

Stop Unity from compiling every time you save a script in Visual Studio

It can quickly become a frustrating experience when one small change and save to a script causes your entire project to recompile in Unity when tabbing back and forth from Unity and Visual Studio (VS). This is especially frustrating if you tab back and forth frequently, only to be prompted with the script recompiling loading bar.

Googling this and looking for a solution on StackExchange, Unity discussion forum, among other places, the responses do not directly address the question. Some people have recommend disabling Unity Editor Auto Refresh in the General options in Unity 2021 or earlier, or Asset Pipeline in Unity 2022 or later. Unfortunately, this doesn’t respond to this specific issue. Another recommendation is to add Burst in Unity’s Package Manager – and while this improves and optimizes compilation, it does not stop every small save in VS from compiling. In fact, the solution is not found in Unity Editor, but rather, in VS which is refreshing Unity’s AssetDatabase through Tools for Unity every time a file is saved.

There’s a really simple solution in Visual Studio:

In Visual Studio 2019 or 2022, click Tools -> Options -> Tools for Unity -> Refresh Unity’s AssetDatabase on save -> Set to False.

Then close and reopen Unity and Visual Studio for the changes to take place. That’s it. And when you do want to compile, simply press Ctrl + R within the Unity Editor.

A thread safe way of updating the main thread from another thread in Unity

A thread safe way of updating the main thread from another thread in Unity

As you develop your game or project, you may require updating the main thread from within another thread. If you’re stuck and need a solution, here’s a quick way to get things moving.

The code defines a class named MainThreadDispatcher. This class is designed to enable the execution of actions on the main Unity thread from other threads in a thread-safe manner. It accomplishes this by using a ConcurrentQueue to store and process actions, and ConcurrentQueue handles all synchronization internally.

The Update method is automatically called once per frame by Unity, and it dequeues and executes actions from the concurrentActionQueue while ensuring that the operation is thread-safe. Additionally, a static method EnqueueAction is provided to allow other parts of the code to enqueue actions for execution on the main thread.

This mechanism is useful for handling tasks that require interaction with Unity’s main thread from background or worker threads, such as updating UI elements, handling game events, or modifying Unity objects in a thread-safe way.

To use this, create a GameObject in your scene and attach a script with the following:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Collections.Concurrent;
using System;

public class MainThreadDispatcher : MonoBehaviour
{
    private static ConcurrentQueue<Action> concurrentActionQueue = new ConcurrentQueue<Action>();

    // Update is called once per frame
    void Update()
    {
        while (concurrentActionQueue.TryDequeue(out var actionItem))
        {
            actionItem();
        }
    }
    public static void EnqueueAction(Action action)
    {
        concurrentActionQueue.Enqueue(action);
    }
}

ThreadWorker example to test the MainThreadDispatcher:

MainThreadDispatcher.EnqueueAction method queues an actions for execution on the Unity main thread. A lambda expression is used to encapsulate a set of actions. By enqueuing this lambda expression, it ensures that these actions are performed on the main thread, thereby safely allowing changes to Unity objects and user interface elements without risking threading issues.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading;

public class ThreadedWork : MonoBehaviour
{
    private bool isUpdating = false;
    void Start()
    {
        // Start a background thread to perform work
        Thread backgroundThread = new Thread(PerformBackgroundWork);
        backgroundThread.Start();
    }
    private void PerformBackgroundWork()
    {
        while(true)
        {
            // Simulate some work on a different thread
            Thread.Sleep(5000);
            // To update the main thread, enqueue an action
            MainThreadDispatcher.EnqueueAction(() =>
            {
                isUpdating = true;
                // Perform any updates or modifications to Unity objects here

                isUpdating = false;
            });
        }
    }
}