Procedural Scripts

Each of the Project Constants systems generates a procedural script and you can create your own by making a procedural MonoScript with a generator method that takes a System.Text.StringBuilder parameter. To generate the script, Weaver will run your method then save the contents of the StringBuilder as a .cs file for Unity to import as a script.

  • The Build Details Script Builder demonstrates how to generate a simple procedural script.
  • In order to generate their script text, the Project Constants systems use the Kybernetik.ProceduralScripting namespace which contains classes like ScriptBuilder and TypeBuilder. These classes are located in Kybernetik.dll, meaning that their source code is available even to Weaver Lite users.
    • The Weaver.SimpleScriptBuilder class inherits from the base ScriptBuilder and simplifies the creation of procedural scripts containing a single root type with the same name as the script.
  • Procedural scripts using this system will be automatically regenerated if necessary whenever assets are saved such as when the user presses Ctrl + S to save the scene or when the project is built.
  • The ScriptBuilder base class defines the member naming conventions, code region names, and handling rules for Obsolete Members.
    • The GetPrimaryMemberName method is used to turn an input string such as an animation name like "Heavy Attack" into a valid C# member name like HeavyAttack.
    • If multiple members in the same type get the same primary member name, GetFallbackMemberName will be used to get a more unique name like Heavy_Attack for each of them. If there are still conflicts after that, an error will be logged.
  • The TypeBuilder class is used to gather the members you want and compare them to existing members using reflection to determine if anything has changed and the script needs to be regenerated.
    • Add members using the various Add... methods. These methods return the added member builder in case you need any additional customisation.
    • Call PrepareToBuild which determines the Name of each member from its NameSource and resolves any naming conflicts, then compares its member builders to the existing member information using reflection to determine if the script needs to be regenerated, in which case the method returns true.
    • Call AppendScript to build the actual text of the script.
    • Call PrepareForReuse to release all of the members back to their object pools so they can be reused with minimal memory allocation and garbage collection.
  • If you want to group procedural scripts using an Assembly Definition File, you need to make sure to give the assembly a unique name. Weaver.dll is already used by this plugin, but Weaver.Procedural.dll would be an appropriate name.

Utilities

  • Kybernetik.Utils.Indent is useful for generating neat procedural scripts and other multi-line text.
  • Kybernetik.CSharp contains a variety of methods relating to C# code which are particularly useful for generating procedural scripts such as OpenScope and CloseScope which are simply shorthand for appending indented curly brackets and incrementing/decrementing the indent counter.
  • Kybernetik.CSharp.GetNameCS returns the name of a type or member (such as a field or method) as it would appear in C# code, which is particularly important for generics and other irregular types (arrays, nullables, pointers):
    • typeof(List<float>).Name returns "List`1"
    • typeof(List<float>).FullName returns "System.Collections.Generic.List`1[[System.Single, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"
    • typeof(List<float>).GetNameCS() returns "System.Collections.Generic.List<float>"
    • typeof(List<float>).GetNameCS(CSharp.NameVerbosity.Name) returns "List<float>"
    • typeof(List<float>).GetNameCS(CSharp.NameVerbosity.FullName) returns "System.Collections.Generic.List<float>"
    • typeof(List<float>).GetNameCS(CSharp.NameVerbosity.GlobalFullName) returns "global::System.Collections.Generic.List<float>"
  • Kybernetik.Reflection contains methods to easily perform common reflection functions such as iterating through all types in the project to find everything with a particular attribute or everything which inherits from a particular base type.
  • These classes are all in Kybernetik.Core.dll so their source code is included even with Weaver Lite.