C# Toolkit
The Impossible Odds C# Toolkit for Unity is a set of carefully crafted tools to help you kick-start your project’s codebase. It’s designed with ease-of-use in mind, provide tools to keep your codebase clean and efficient. It combines several utilities and frameworks to help you think more about your game and gameplay design rather than code design.
You can expect to find the following features in this tookit:
Core utilities: extension and utility functions to speed-up programming work and reduce boiler-plate code. Set up execution order dependencies for your Unity scripts, define a split logging level for editor and your builds, invoke events and check values in single line of code, etc.
Dependency injection: keep your code clean and organized by removing tightly coupled design patterns. Increase the potential of your code by defining resources and dependencies on a much higher level.
Runnables: avoid the MonoBehaviour and GameObject runtime tax if your objects only need the update or coroutine functionality. Simply hand them to a runner object to hook them into the game loop.
State machines: use the state machine design pattern with a quick, easy and robust setup.
JSON: serialize your data to and from the JSON data format, with support for saving type information to keep your inheritance chain intact when deserializing content.
XML: prefer the XML data format over anything else? With support for saving type information, setting values in XML attributes and serializing binary data in CDATA sections, you can quickly generate clean XML documents.
HTTP: easily create request and response objects to send and receive from your web server or a third-party web API using Unity’s web requests.
Photon - WebRPC Extensions: using Photon as your multiplayer service and have a custom web server running? Create and send requests over Photon's network using the WebRPC feature by leveraging the serialization and messaging systems in this toolkit.
Release Notes
General note about installing updates: it is recommended that you remove the current installed package first before updating to a newer one. Some files may have been deleted or moved, which may cause conflicts or compilation errors. The default location for this package in your Unity project is at Assets/Impossible Odds/Toolkit.
Version 1.5.3
Added
- Added `TryFindIndex` extension methods for lists and arrays.
- Added `InjectStatic` and `InjectStaticAll` methods to the `DependencyInjector` class, to explicitly allow injection of static members of a type.
Updated
- Properties that are used for serialization now no longer require both their `get` and `set` methods to be defined. A warning is now displayed whenever a value is trying to write to a getter-only property, and another warning whenever a value is trying to be retrieved when only a setter has been provided.
- An improved base method filtering is done during (de)serialization of properties. This prevents getting or setting the value multiple times.
Fixed
- Fixed issue with deserializing a Json string containing the `\"` sequence. This could cause an infinite loop.
- Fixed issue with deserializing a Json double or long value, where the serialization definition's format provider wasn't used. This could result in formatting exceptions on platforms that have a different notation for floating point numbers.
- Fixed issue with resolving the proper type during deserialization, where it would return back to a base-type.
- Fixed issue where the type resolve parameter defined on an interface wouldn't get picked up by the serialization cache.
- Fixed issue with dependency injection of static members not injecting the correct target.
- Several typo's in the documentation.
Version 1.5.2
Fixed
- Fixed issue where injecting resources using an injection identifier would throw a NullReferenceException.
Version 1.5.1
Fixed
- Fixed issue where purging the delegates of an object would try to purge non-existing delegates on the object, and throw and exception.
Version 1.5.0
This release brings the State Machine module, a common coding pattern used in a variety of situations. This tool can help you streamline the use of the pattern in your project. Additionally, the Dependency Injection module has been given some useful and nifty additions to speed up managing of your runtime resources. The serialization framework has had a pretty big caching update to reduce memory garbage generation. And finally, a bunch of smaller extension functions have been added to keep your code more concise and readable.
Happy coding!
Added
- Added the State Machines functionality to set up and manage state machines.
- Added Unity package data so that this toolkit can now be included as an embedded project package.
- Added `IsNullOrEmpty` and `IsNullOrWhitespace` string extension functions in analogy of their static counterparts.
- Added `IsNullOrEmpty` collection extension functions to quickly check if a list, array or other type of collection is null or empty.
- Added `TryFindIndex` list and array extensions to find an index of an element.
- Added additional sorted insertion extension functions for list-structures.
- Added additional logging functions to provide an object as parameter, rather than a string to quickly log the value of an object without having to convert it to string manually.
- Added a serialization processor for the `System.Version` and `System.Guid` types so these can be included in serialized data. This processor has been added to all available serialization definitions.
- Added Dependency Injection extension functions to add a component to a game object and inject it immediately.
- Added Dependency Injection extension functions to inject a scene, which will loop over all game objects in the scene.
- Added an optional injection identifier for the `Scene` and `Hierarchy` scopes, to inject their scopes to objects requiring their resources to come from specific sources only.
- Added the `CompositeDependencyContainer` type which is a resource container that is built by combining multiple resource containers. This allows to inject a large set objects in one go instead of going over them per resource container.
- Added an `IReadOnlyDependencyContainer` interface which allows to only get resources from the container. The `IDependencyContainer` now inherits from this new interface as well.
- Added a reflection caching framework to optimize and unify the way meta-data is cached and stored. The enum display names, dependency injection, weblink and serialization frameworks now use this caching instead of their internal solutions.
Updated
- Updated the Dependency Injection framework to allow constructor-based injection.
- Updated the Dependency Injection framework to allow static injection. If the object to inject is of type `Type`, then its static fields and properties will be injected.
- Updated most dependency injection methods to receive a read-only container now if they only require resources to be read from the container.
- Updated the `GlobalDependencyScope` to have its `GlobalScope` property be `public` instead of `internal`.
- Updated the `GlobalDependencyScope` to be able to adjust the `AutoInjectLoadedScenes` at runtime.
- Updated most frameworks to work with concurrency-safe structures. This should make (most of) this toolkit safe to use and run in multi-threaded environments.
- Updated most attribute-related functions to work with the static `Attribute` functions rather than the member functions defined on the `MemberInfo` classes to ensure the frameworks work with attribute-related data.
- Updated most internal workings to use arrays instead of the `IEnumerable<T>` interface to optimize iterating the collections.
- Updated reflection-based method invocation to use a cached parameter list to reduce garbage generation.
Fixed
- Fixed an issue where serialization callbacks would get invoked multiple times if overrides of the same method had the callback attribute defined as well.
- Fixed an issue with the `Shuffle` extension function for lists, where certain placement patterns weren't possible.
Breaking Changes
- The `IDependencyScope` requires the implementation of an `Inject` method now. Calling this method on your scope object should inject the objects under its scope with the resources found in its resources container. If you have a custom dependency scope type, you'll have to provide an implementation for this.
For earlier versions and their update notes, check here.