This article shows how to control scenes on a Unity application by a Windows application with NamedPipe like the following demonstration. The full source is on the GitHub repository.
You can use this IPC class as a NamePipe client to send requests to a Unity application. In the WPF application, a property setter bound to a view sends a request with IPC.Send as follows. IPC.Send waits and returns the response from the player.
In the first place, you must change Api Compatibility Level to .NET 4.x in Player Settings to make NamedPipe available. NamePipe works on the Unity editor's play mode even in .NET Standard 2.0, but it results in an error on a standalone player.
You can use this IPC class as a NamedPipe server to receive requests from a Windows application. The following is the implementation of IPC.Receive to wait for connections from a Windows application.
This is an asynchronous method implemented with UniTask. UniTask is much easier than coroutines to implement asynchronous operations. This method uses synchronous methods of NamedPipe because Unity doesn't implement the asynchronous versions. They don't cause any errors in compilation but result in errors at runtime.
The following Controller class processes requests from the Windows application. You have to put an empty GameObject on every scene and attach a Controller object to the GameObject.
Awake invokes DontDestroyOnLoad not to destroy the Controller on a scene change. Otherwise, the Controller can't send the response for a scene change request after LoadScene. Start invokes IPC.Run with a request handler to start receiving requests.
OnApplicationQuit invokes IPC.Close of which implementation is shown below. This method connects own NamedPipe to stop IPC.Receive waiting for connections. Otherwise, IPC.Receive leaves a waiting thread when it runs on the editor's play mode. The thread prevents the editor from terminating.
I originally implemented the above IPC classes. Some articles are showing how to use NamedPipe on Unity. But they are just experimentations and not appropriate to use in real applications. So I Implemented them.
This article shows a quite simple memory pool to make a thread-unsafe library thread-safe without performance degradation in single-threaded programs. Same as the previous article, this article is about DynaJson.
Thread-safety requires overhead to allocate an instance by each invocation to isolate data being altered. Unless thread-safety is required, we can use a static class or a singleton to eliminate any additional allocation.
You can use Physics.OverlapCapsule to get two Colliders overlapped with a CapsulCollider as above. This method takes the position and the size of a capsule and returns all Colliders overlapped by the capsule.
You can get the Colliders by configuring a Kinematic Rigidbody Trigger Collier and handling the OnTriggerEnter message, but the method is handy.
I developed a JSON Parser for C# named DynaJson. It is very strict to the standard of RFC 8259. It accepts all conformant and rejects all non-conformant JSONs except for two exceptions.
One exception is trailing-commas. Another is leading 0 in numbers, for example, 02 and -02. The former is for practicality. The latter is for compatibility with DynamicJson.
JSON's grammar is simple, but carelessly implemented parsers don't accept all conformant and not reject non-conformant JSONs. An excellent article of Parsing JSON is a Minefield shows where mines are in implementing JSON parsers.
In a native Docker environment, you can mount /source in a container host onto /destination in a container by docker run -v /source:/destination and access it from the container.
Well then, how can you mount C:\Source in Windows onto /destination in a container on Docker for Windows? You can't directly mount C:\Source in the VM host into the container, of course.
As the first step, you have to set up C:\Source as a shared folder for a VM when you create it with docker-machine. You can specify the shared folder with the --virtualbox-share-folder option of the VirtualBox deriver as follows.