question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[C#] Codegen for Unity

See original GitHub issue
Description

This is an issue to discuss how a C# generator can be effectively useful in a Unity project. I’ve been told the C# codegen is under a refactor phase, so my suggestion is to consider the next few points, to maybe include in this refactor.

I don’t know if Unity will require a separate template, but it’s a possibility.

Related issues/PRs

This issue will extend the points discussed here, kindly consider taking a look at it before continuing: https://github.com/swagger-api/swagger-codegen/issues/8569

Suggest a fix/enhancement

Here’s a list of things one might want to consider when supporting codegen for Unity:

  • Using UnityWebRequest (see issue above): the usual way to call a UnityWebRequest and wait for a response is through Coroutines (example) or through the completed event.

Note that the response is returned on the main thread (and of course, the deserialization of the response should happen on a background thread).

Also, this can easily be made into an async/await style by creating an Awaiter, maybe something like this:

    //UnityWebRequestAsyncOperation is an AsyncOperation
    public static TaskAwaiter GetAwaiter(this AsyncOperation asyncOperation)
    {
        var taskCompletionSource = new TaskCompletionSource<bool>();

        asyncOperation.completed += operation => { taskCompletionSource.TrySetResult(true); };

        return ((Task) taskCompletionSource.Task).GetAwaiter();
    }

Which will bring me to the next point:

  • Depending on the configuration of a Unity project, the .Net version running can be 3.5 or 4.x equivalent. For that reason, some C# features are not always accessible. Fortunately, Unity has define symbols allowing to identify the configuration, and have code to support it accordingly. For example:
public class API {
//
//APIs using Coroutines here, which is supported on both runtime versions
//

#if NET_4_6

//
//APIs using async/await here, only available in 4.6
//

#endif
}
  • As for Json serialization, the obvious choice would be Newtonsoft’s, although it is known that there are few modifications needed for it to work correctly on different platforms. This asset could be of help.

  • The IL2CPP backend converts C# code into C++, for performance purposes. While this is a great feature, it has few limitations, including working with generic virtual methods (see the bottom of the page). In one of the cases (as an example), the deserialization fails because the converter tries to construct a CollectionWrapper<decimal?> object, which was not generated. So what I had to do is to make a call to it somewhere, so the the IL2CPP backend would pick it up, and generate the C++ equivalent:

#if ENABLE_IL2CPP
//THIS IS NEEDED SO THAT IL2CPP CAN JSON DESERIALIZE List<decimal?>
    void UsedOnlyForAOTCodeGeneration()
    {
        new CollectionWrapper<decimal?>((IList<decimal?>) new List<decimal?>());
    }
#endif
}

Once the constructor is actually called anywhere in the code, the code converter picks it up and generate equivalent C++ code for it.

Note 1: When il2cpp backend is used, the symbol ENABLE_IL2CPP is defined. Note 2: in this case, CollectionWrapper is internal, that’s why I had to make it public, and recompile the Json.Net library. For this reason, any method generic virtual method needed for the correct deserialization can be generated accordingly, as needed (a work around for private/internal types might be needed)

  • Script compilation and assembly definition files Unity recompiles the project after every code change automatically. Assembly definition files can divide code into separate assemblies/projects, for faster compilation. An OpenAPI generated project can have it’s own probably.

  • In my previous issue, I mention editor extensions to make it easier to generate code. This can be a separate project which makes a call to the C# generator (either through a CLI or a rest service). This is something I have implemented with the current C# generator of swagger, and it helped me iterate faster (after changing a json file containing my spec, I can regenerate the code with a click of a button, see image from previous issue)

  • Unity mostly doesn’t need any build scripts, only raw C# files.

  • Supporting Unity Test Runner

Please feel free to ask questions, and discuss. But from my experience with codegen and Unity, these are the main points that would make working with REST APIs a seamless experience when using Unity.

Issue Analytics

  • State:open
  • Created 5 years ago
  • Comments:18 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
iBichacommented, Oct 1, 2018

Sorry it’s taking me a while to respond. I’ve been meaning to respond with proper feedback for some time now but I didn’t get the time around it. Will do asap

1reaction
iBichacommented, Aug 21, 2018

That’s a good question. Just to clarify, the JSON deserialization will run at runtime during api calls. But the reason the json utility probably not the best suited is because it’s very limited when it comes to supported types.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Code Generation in Unity - Game Developer
Code generation is an immensely powerful tool that any developer can use. In it's super basic form it's code that outputs text. This...
Read more >
C# Source Generators? - Unity Forum
I was trying to look up information regarding C# source generators, ... of this in my Datasacks package, where I have a "CODEGEN"...
Read more >
Roslyn analyzers and source generators - Unity - Manual
Use Roslyn analyzers, source generators and ruleset files in Unity projects to inspect your code for style, quality, and other issues.
Read more >
The Easy Power of Code Generation - JacksonDunstan.com
C# generics are weak. The where clause allows you to know a little about the generic (“ T “) types you're given, but...
Read more >
Experience with basic Code Generation in Unity? : r/Unity3D
... to start with the simplest kinds of code generation in C# that works within the Unity Editor? ... So far I didn't...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found