3 ms·
Especially since the Unity docs encourage bad architecture! Like putting all of your game logic directly in untestable Monobehaviours and writing total spaghett
by Jorge1o1 6y ago
Especially since the Unity docs encourage bad architecture! Like putting all of your game logic directly in untestable Monobehaviours and writing total spaghetti code. For me, the most useful thing that Unity docs or tutorials never taught me is that your complex logic shouldn’t necessarily be in the Monobehavior itself. If you instead put logic in plain C# classes that implement interfaces it becomes far easier to test and mock game logic. I’ve seen people having to manually test things like running out of ammo by clicking 30 times because they had the logic in the Monobehaviour and they couldn’t unit-test it.
If you use Microsoft’s DI Extension it gets even easier.
- jayd16 6y agoThe Unity example code is laughably bad. But don't use dependency injection. Unity's Scene/Prefab load/instantiation is already a form of DI. Using another causes issues with juggling multiple lifecycles. You also lose the ability for Unity to prefetch assets because Unity can't inspect the dependency graph if it's not done through the asset system. Instead you hit situations where you're loading several objects and running DI code over several frames when unity could have loaded everything at once.
- andypants 6y agoYou can use unity-aware dependency injection with extenject: https://github.com/svermeulen/Extenject https://github.com/svermeulen/Extenject
- tomduncalf 6y agoYep, totally agree about the docs and tutorials promoting bad practices, it’s almost impossible to find up to date, modern examples. I am not a game dev, more app/audio/web, but our app uses Unity for the 3D and interactive video lesson playback parts and recently I’ve been refactoring the video part, which is a perfect candidate for building out with unit and integration tests. It took a lot of digging to work out how to use the Unity unit test stuff effectively as there are really just a few toy examples out there, same with async/await (and the unit test runner still cannot handle async/await in tests!). I guess maybe it’s a culture thing to some extent, unit testing maybe isn’t as prevalent in games for whatever reason? Once I worked out, as you say, that I could move most of the logic into plain C# classes and test them much the same way I would any old business logic, things became much easier to deal with. I did think about using DI but in the end found that passing GameObjects in via the IDE and public members as the other comment says sufficed for anything which is a GameObject, and the other (plain class) dependencies I am new’ing up in a top level Manager class and passing down through the constructor, and using NSubstitute to pass in mocks in the unit tests. I might write up my experience/findings some time when the work is complete. On the whole, I do think Unity is great, I’ve seen how fast we were able to build out a great looking experience and it’s pretty easy to figure out. C# is a really nice language too. Just a shame that more “modern” dev practices are not actively promoted, and parts like async/await and unit testing seem to be left half-finished.