Should I split up this System to smaller sub systems?

I’m working on a character controller using DOTS. Currently I’m running 1.5K chickens around 0.5ms according to the entity debugger (I’m not sure if its accurate since I’m using a job). I think that’s really good. My question is should I split up this into smaller systems. This currently planned to get grounded state, move, rotate, and jump. I feel like getting grounded state and possibly other recasting stuff might be better off in a new system and maybe rotation as well?

using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
using Unity.Jobs;
using Unity.Mathematics;
using Unity.Transforms;
using Unity.Physics;

namespace DOTSMovement
{
    public class MovementBipedSystem : JobComponentSystem
    {
        [BurstCompile]
        struct MovementBipedSystemJob : IJobForEach<MovementInputComponent, MovementBipedComponent, PhysicsVelocity, PhysicsMass, Translation, Rotation>
        {

            public float deltaTime;

            private float3 originalVelocity;
            private float3 newVelocity;
            private float3 movementDirection;
            private quaternion newRotation;

            public void Execute(ref MovementInputComponent movementInputComponent, ref MovementBipedComponent movementBipedComponent, ref PhysicsVelocity physicsVelocity, ref PhysicsMass physicsMass, ref Translation translation, ref Rotation rotation)
            {

                //Check If Grounded : T0 DO
                movementInputComponent.isGrounded = true;

                //Movement
                {
                    originalVelocity = physicsVelocity.Linear;
                    newVelocity = originalVelocity;

                    //Read Movement Input
                    newVelocity.x = movementInputComponent.input.x;
                    newVelocity.z = movementInputComponent.input.z;

                    //Multiply Our Velocity By Our Movement Characters Speed
                    newVelocity *= movementInputComponent.doSprint == 0 ? (movementBipedComponent.walkRunSpeed) : movementBipedComponent.sprintSpeed;

                    //Apply Back Our Original Velocity Y
                    newVelocity.y = originalVelocity.y;

                    //Set Linar Physics Velocity
                    physicsVelocity.Linear = newVelocity;
                }

                //Rotation
                {
                    //Rotate Twords Movement Direction
                    if (movementInputComponent.input.x != 0 || movementInputComponent.input.z != 0)
                    {
                        movementDirection = math.normalize(movementInputComponent.input);
                        movementDirection.y = 0;
                        newRotation = quaternion.LookRotation(movementInputComponent.input, new float3(0, 1, 0));
                        rotation.Value = math.nlerp(rotation.Value, newRotation, movementBipedComponent.rotationSpeed * 10 * deltaTime);
                    }

                    //Constrain Physics Rotation
                    physicsMass.InverseInertia = float3.zero;
                }

                //Jumping
                {
                    //Get Some States
                    movementInputComponent.jumpCount = 0;

                    //Jump And Increment Entity's Jump Count
                    if (movementInputComponent.doJump == 1 &&  movementInputComponent.jumpCount >= 0)
                    {
                        physicsVelocity.Linear.y = movementInputComponent.isGrounded ? movementBipedComponent.groundedJumpForce : movementBipedComponent.inAirJumpForce;
                        movementInputComponent.jumpCount++;
                    }

                    if (movementInputComponent.isGrounded)
                        movementInputComponent.jumpCount = 0;
                }
            }
        }

        protected override void OnCreate()
        {
            base.OnCreate();
        }

        protected override void OnDestroy()
        {
            base.OnDestroy();
        }

        protected override JobHandle OnUpdate(JobHandle inputDependencies)
        {
            var job = new MovementBipedSystemJob();
            job.deltaTime = Time.DeltaTime;
            return job.Schedule(this, inputDependencies);
        }
    }
}

You may consider splitting up the system if you find yourself duplicating logic.

Thanks. I split up my Biped into multiple components. I’m running more systems but there each faster than the one big one so I think it works out. Thanks.
-Ground Movement
-Jump
-Rotate
-Collision

Architecturally, it’s better to have one system per behavior (exactly the way you broke it down above). And from a performance perspective it can be better too since it’s easier for Burst to apply SIMD vectorization on systems that do one single thing than systems that do many things, and also it makes it more possible for the job system to run your code in parallel. Sometimes, it can be faster to combine two systems than it is to keep them separate. But this should be done towards the end of the project as an optimization technique and only after profiling your code.

2 Likes

Thanks for the feedback.