At the moment, IL2CPP build generates the generic game executable and two native dll’s where other contains your game code. Would it be possible in the future to do static build where executable included all three?
I’m asking this as it would help with some DRM solutions. For example Steamworks DRM (I mean the actual DRM that modifies executable) can only “protect” the executable afaik and since the exe itself is generic (same for all, with just modified properties), this would seem like it would pretty much render any exe DRM inefficient as people could just generate new non-DRM exe with Unity editor. If the executable actually contained all game code with static linking, it would be easier to protect it.
As additional note, I hope this thread will not turn into discussion how efficient the Steamworks DRM is, as this is not the point of the thread, I used Steamworks as example as it’s probably the most common solution people would use.
This is a possibility, although we’ve not considered it from the DRM angle. Even without IL2CPP, a Mono build of a player on Windows Desktop uses an executable, a native DLL, and managed assemblies, so the change goes beyond IL2CPP. We’ll discuss how feasible this is. I would not expect it in the near future, but we’ll keep it in mind.
It’s not likely we will make such a change. There are several good reasons why we’re using several binaries.
The main executable being a thin wrapper allows us to ship its source code to you and also allows you to change it and recompile it however you wish.
UnityPlayer.dll being in a DLL allows us to cryptographically sign it using our certificate, which allows everyone to verify that this binary has not been tampered with (if you tamper with it, the signature will become invalid).
GameAssembly.dll is where your executable code lives, and it needs to be loaded by UnityPlayer.dll, so it cannot be compiled into the .exe (or we could never unload it otherwise). It is also compiled on your machine.
In 2018.2, we’ll be adding a feature that will allow you to opt-into generating Visual Studio project for your build instead of final binary output. That will allow you to more easily modify the executable and how it is built.
Since GameAssembly.dll contains all your game logic, couldn’t you add DRM to that too? I’m not familiar with how steam DRM works, but being unable to protect DLLs seems like a pretty big limitation on DRMs.
Oh, so we get actually sources for the main exe too? I wasn’t aware of this I thought the exe and UnityPlayer.dll both were closed source. As far for Steam DRM goes, it’s not a very strong protection overall, more like measure that reduces trivial piracy. I’m pretty sure you can only protect the main executable with it. Although, it would probably be possible for me to add additional checks in the GameAssembly.dll to see that executable hasn’t been tampered with. Again, not the most ideal case but would prevent casual game distribution without permission.
Looking forward to that 2018.2 solution generation, if you have earlier tech previews with this functionality, I’d love to test it in advance too as I’m really curious about the advantages I could take with this. Btw been testing today that preview for upcoming beta and the custom c++ code inclusion in editor works now as intended on my initial tests, thanks for fixing this I haven’t had much luck with including custom libs with pragma with it but it’s really a nonissue when we get 2018.2 changes as then I could just include the additional projects directly to the solution.
I’m also very interested in getting direct access to some of the native code Unity functions that are not done in IL. I’ve seen some of these calls referred in the generated IL2CPP code and I think it’s already possible to look up the function names from the generated code and call them from my own native code. Is there some special considerations one would have to make before going this route?
I understand that things like these wouldn’t probably be officially supported by Unity for the time being but it would let me do things like sync transforms from third party physics engine to Unity without going back and forth with native and c# code just to sync things for example. I already run my physics, input and steamworks via custom native dll, which is main reason why I’m so interested in customizing the IL2CPP results.
That being said, since IL2CPP is getting used across most of Unity platforms now, could you consider exposing some public c++ API which we could interface with. There’s been a big demand for c++ scripting support for Unity in the feature requests and I feel that if we could hook things even more easily into IL2CPP builds, this would reduce the need of having fully fledged c++ API for everything. Simply publicly exposing existing native calls would be a great for giving even more power to Unity users.
Yeah, you can find it in \Editor\Data\PlaybackEngines\WindowsStandaloneSupport\Source.
I just finished implementing the feature last weekend, so it will be a while before it’s available in a preview build. But I’ll see what I can do.
Which functions are you talking about? Generally I’d not recommend it as it’s way too easy to shoot yourself in the foot in it and cause the garbage collector to flip out on you.
Unfortunately this is out of scope of IL2CPP support. Some big parts of our engine are written in C# (like UI system), so there’s nothing to expose in C++. But never say never I guess - perhaps we will consider that in the future.
Thanks for the reply, I’ll look for the playback engine source for sure. Also nice to hear the solution generation is on track
For the functions, I’m mainly after some internal calls which managed unity dll used to call from native code. I’m well aware that most of the API is done in c#, but I’d love to get access to those final native function calls directly from c++ to bypass the c# wrapping in cases where there’s no benefit from going back and forward with c# and native code. Of course it’ll be less safe, but that’s something you take always into account when you work in c++ side (I totally get why Unity uses c# for scripting).
I’ll probably do some further testing with those transform updates from native code to Unity. I don’t know for example if the new job system could be used to make this more efficient or if it really matters on raw array copy operations at all (like, does the new job system let you update the unity transforms in separate threads?). For anything else, I doubt there will be any meaningful perf impact, would just want to make the 3rd party physics world updates to unity as efficient as possible as there will be tons of objects to sync each frame.
I’ve actually followed the blog series, great stuff there. I’d still love to cut away the C# wrapping part where ever possible, even though it probably doesn’t give meaningful perf benefit for most of the things
No, it will not be as safe as normally working in C++. Our bindings code is automatically generated and makes assumptions on how C# will call into it and it subtly interacts with garbage collector. Call it incorrectly and you’ll be dealing with impossible to debug memory corruptions. We are not going to support that path.
This would give me direct access to the transform setter and I could update transforms directly from native code. Does calling this function directly give similar side effects you warned about? I totally understand Unity can’t support these kinds of approaches but would be nice to know about the side effects if you still use them.
Additionally, I have some interest on related getters:
but these are not as important as the setter as that has to run hundreds and sometimes thousand+ times each frame.
edit-> oh wait, the functions I linked still call final things through _il2cpp_icall_func so I guess it doesn’t really make a big difference, could mainly bypass the initial pinvoke call
Yes, RuntimeObject is an object managed by garbage collector. Do not touch it from your own C++ Code.
Yes. Your best bet is to call them from your C# code and then pass result to your C++ code via __Internal P/Invoke. That should give you the best performance.
Either way, if you’re looking for improving performance with Transform component, you should look at TransformAccessArray, instead of hacking IL2CPP :).
+1 for using TransformAccessArray and the new jobsystem instead of trying to poke at SetPositionAndRotation, especially if you are looking to set thousands of transform positions/rotations per frame.
Thanks for the replies, I actually looked into the job system yesterday as I’ve wondered about it’s usability for this purpose before as well. I watched the Unite talk where Joachim gave examples about it but couldn’t really find any specific info about how things are actually synced with the transforms for the main thread.
My main question is, if you use IJobParallelForTransform, it still has to pass the results from the job thread into main eventually? like it can’t set the transfroms from job thread directly or have you made those setters threadsafe internally? If it can, then it would be obvious perf improvement as I could just set few jobs in parallel to do this for all transforms while other code executes.
If it still has to manually pass the transform to the main thread, I don’t really see where the benefits of job system comes into play (for other than having related data arranged in array, which I already do).
I wouldn’t be doing any additional operations on the jobs either, I just need to update the transform values from my own data source.
Nope, the job is setting the data in the transforms directly. (Also, best not to think about it in terms of threads - jobs are not threads, there is no guarantee that a job executes on a non-main thread, or that the platform you’re on even has non-main threads).
Only one job can write to the given array of transforms at a time (though if that job is an IJobParallelForTransform, it might be getting executed across multiple CPU cores at once). If you want to have two separate jobs that write to the same transforms, you will need to make one a dependency of the other.