Skip to content

Unity setup

Stanislav Silin edited this page Jun 3, 2023 · 8 revisions

Setup for Untiy is complicated because Unity build system doesn't work well with rest of the dotnet ecosystem. However, it is still possible to make it work.

Create assembly definition and set name and root namespace. We need it because 'Assembly-CSharp' is not a valid namespace, and later on, the generation will fail.

Open the Unity project root folder(not Assets! Folder above). Open terminal there. Then create netstandard2.1 library and add ZeroQL to it:

# add tools manifest
dotnet new tool-manifest 
# add ZeroQL cli
dotnet tool install ZeroQL.Cli 
# create class library
dotnet new classlib -f netstandard2.1 -o QLClient 
# go to class library
cd QLClient
# add ZeroQL
dotnet add package ZeroQL 
# add json serializer
dotnet add package System.Text.Json
# pull schema
dotnet zeroql schema pull --url http://localhost:10000/graphql
# create ZeroQL config 
dotnet zeroql config init
# generate client
dotnet zeroql generate -c ./zeroql.json

Open QLClient.csproj in your IDE. You will see that it fails to compile because of errors in Generete/GraphQL.g.cs.

Open csporj in editor and add line <LangVersion>latestmajor</LangVersion> in first PropertyGroup. Most errors should go away except one. The class ModuleInitializer is missing.

Open zeroql.json and add option "netstandardCompatibility": true. Regenerate client:

dotnet zeroql generate -c ./zeroql.json

Now all compilation errors should go away.

The next steps will export our QLClient to Unity. Change output and pushlish folder in csproj. Open it and add next lines in first property group:

    <OutDir>../Assets/ZeroQL</OutDir>
    <PublishDir>../Assets/ZeroQL</PublishDir>

Publish the class library:

dotnet publish -c Release

Open Unity editor. You should see a new folder ZeroQL, C# assemblies inside, and no compilation errors.

Now we have two options. You can just start writing ZeroQL queries inside the class library. Then rebuild it to apply changes to the Unity project. For example:

public class NetstandardGraphQLClient
{
    private readonly HttpClient httpClient;
    private readonly ZeroQL.Client.ZeroQLClient qlClient;

    public NetstandardGraphQLClient(HttpClient httpClient)
    {
        this.httpClient = httpClient;
        this.qlClient = new ZeroQL.Client.ZeroQLClient(httpClient);
    }
    
    public async Task<string> GetMyName()
    {
        var response = await qlClient.Query(q => q.Me(o => o.FirstName));
        return response.Data;
    }
}

Build it and in then somewhere in Unity script:

namespace UnityZeroQLClient
{
    public class Main : MonoBehaviour
    {
        // Start is called before the first frame update
        void Start()
        {
            Execute().ContinueWith(t =>
            {
                Debug.Log(t.Result);
            });
        }

        public Task<string> Execute()
        {
            var httpClient = new HttpClient();
            httpClient.BaseAddress = new System.Uri("http://localhost:10000/graphql");

            var client = new NetstandardGraphQLClient(httpClient);
            return client.GetMyName();
        }

        // Update is called once per frame
        void Update()
        {
        
        }
    }
}

It works fine and don't require any additional configuration.

However, it is possible to enable writing ZeroQL queries inside the Unity scripts project itself. To make it work, we need to download the raw nuget package.

  1. Go to https://www.nuget.org/packages/ZeroQL/.
  2. Select the latest version and press the download button.
  3. Open the file as a zip archive and find analyzers/dotnet/cs/ZeroQL.SourceGenerators.dll
  4. Copy it to Assets/ZeroQL
  5. The compilation should fail.
  6. Open properties of the ZeroQL.SourceGenerators.dll and uncheck all target platforms as if you don't plan to use them.

  1. On the bottom, add the asset label RoslynAnalyzer.

All compilation errors should go away, and you will be able to write ZeroQL queries in the Unity script project directly:

public class Main : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        Execute().ContinueWith(t =>
        {
            Debug.Log(t.Result);
        });
    }

    public async Task<string> Execute()
    {
        var httpClient = new HttpClient();
        httpClient.BaseAddress = new System.Uri("http://localhost:10000/graphql");

        var qlClient = new ZeroQL.Client.ZeroQLClient(httpClient);
        var response = await qlClient.Query(q => q.Me(o => o.FirstName));

        return response.Data;
    }

    // Update is called once per frame
    void Update()
    {
    
    }
}