Skip to content

Repository files navigation

PolymorphicStructs

See the forum thread for more information https://forum.unity.com/threads/sources-included-polymorphism-in-dots-now-with-source-generators.1264616/

Installing into your project

  1. Import the PolymorphicStructs.unitypackage into your project (find it in the Releases section)
  2. Make sure all of the code that's going to use PolymorphicStructs is under an .asmdef and references the PolymorphicStructs.asmdef

How to use

  1. Create an interface that will represent the various functions your polymorphic structs will share. This interface must have the [PolymorphicStruct] attribute on it
[PolymorphicStruct]publicinterfaceIMyState{publicvoidOnStateEnter(refStateUpdateData_ReadWriterefData,inStateUpdateData_ReadOnlyinData);publicvoidOnStateExit(refStateUpdateData_ReadWriterefData,inStateUpdateData_ReadOnlyinData);publicvoidOnStateUpdate(refStateUpdateData_ReadWriterefData,inStateUpdateData_ReadOnlyinData);}
  1. Create the structs that implement that interface, representing all the different forms that the polymorphic stuct can assume. Make sure these structs are partial
[Serializable]publicpartialstructStateA:IMyState{publicfloatDuration;publicfloat3MovementSpeed;privatefloat_durationCounter;publicvoidOnStateEnter(refStateUpdateData_ReadWriterefData,inStateUpdateData_ReadOnlyinData){_durationCounter=Duration;}publicvoidOnStateExit(refStateUpdateData_ReadWriterefData,inStateUpdateData_ReadOnlyinData){refData.Translation=refData.StateMachine.StartTranslation;}publicvoidOnStateUpdate(refStateUpdateData_ReadWriterefData,inStateUpdateData_ReadOnlyinData){refData.Translation+=MovementSpeed*inData.DeltaTime;_durationCounter-=inData.DeltaTime;if(_durationCounter<=0f){refData.StateMachine.CurrentStateIndex=refData.StateMachine.StateBIndex;}}}[Serializable]publicpartialstructStateB:IMyState{publicfloatDuration;publicfloat3RotationSpeed;privatefloat_durationCounter;publicvoidOnStateEnter(refStateUpdateData_ReadWriterefData,inStateUpdateData_ReadOnlyinData){_durationCounter=Duration;}publicvoidOnStateExit(refStateUpdateData_ReadWriterefData,inStateUpdateData_ReadOnlyinData){refData.Rotation=quaternion.identity;}publicvoidOnStateUpdate(refStateUpdateData_ReadWriterefData,inStateUpdateData_ReadOnlyinData){refData.Rotation=math.mul(quaternion.Euler(RotationSpeed*inData.DeltaTime),refData.Rotation);_durationCounter-=inData.DeltaTime;if(_durationCounter<=0f){refData.StateMachine.CurrentStateIndex=refData.StateMachine.StateCIndex;}}}
  1. This will generate a MyState struct (takes the name of the interface, minus the first character "I") that will have all the functions of the IMyState interface. You can now call polymorphic functions on MyState like this and it will call the implementation of whichever version of the struct was assigned to MyState:
myState.OnStateUpdate(...)
  1. You can also create a MyState from the various specific structs and vice-versa like this:
// Creating a MyState from a StateAStateAstateA=newStateA();MyStatestate=stateA.ToMyState();// Creating a StateA from a MyStateStateAstateA=newStateA(state);

How the sample works

  1. TestScene is the sample scene
  2. CubeSpawnerSystem initializes the scene by spawning thousands of cube prefabs (Cube)
  3. The Cube prefab has a StateMachineAuthoring component
  4. The StateMachineAuthoring component adds a MyStateMachine as well as a DynamicBuffer<MyState>. This buffer is the place where we store all of our polymorphic states. You can see how we create a polymorphic MyState from individual state structs in the StateMachineAuthoring.AddStateToStatesBuffer() method
  5. MyStateMachineSystem iterates over all state machine entities, and for each one, handles calling OnStateUpdate() on whichever state is set as the CurrentState. It also handles transitions

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages