Common patterns in gameplay code | Entities | 0.14.0-preview.19
docs.unity3d.com
    Show / Hide Table of Contents

    Common patterns in gameplay code

    Structuring code with Entities.ForEach

    Entities.ForEach allows you to write inline jobified code that deals with a set of entities. When organizing your code, it can help to encapsulate functionality into methods and structures. The following patterns provide ways to do this:

    • Static methods
    • Encapsulate data and methods

    Call static methods from an Entities.ForEach

    This pattern helps you to re-use functionality in multiple places. It can also help simplify the structure of complex systems and make your code more readable.

    You can use a static method as the ForEach lambda function, as illustrated in the following example. A static function called this way is Burst compiled (if the function is not Burst-compatible, add .WithoutBurst() to the Entities.ForEach construction).

    public class RotationSpeedSystem_ForEach : SystemBase
    {
        protected override void OnUpdate()
        {
            float deltaTime = Time.DeltaTime;
            Entities
                .WithName("RotationSpeedSystem_ForEach")
                .ForEach((ref Rotation rotation, in RotationSpeed_ForEach rotationSpeed) 
                    => DoRotation(ref rotation, rotationSpeed.RadiansPerSecond * deltaTime))
                .ScheduleParallel();
        }
    
        static void DoRotation(ref Rotation rotation, float amount)
        {
            rotation.Value = math.mul(
                math.normalize(rotation.Value), 
                quaternion.AxisAngle(math.up(), amount));
        }
    }
    

    For more information about creating ECS systems, see:

    • Systems
    • SystemBase

    Encapsulate data and method in a captured value-type:

    This pattern helps you organize data and work together into a single unit.

    You can define a struct that declares local fields for the data together with the method called by Entities.ForEach. In the system OnUpdate() function, you can create an instance of the struct as a local variable and then call the function as illustrated in the following examle:

    public class RotationSpeedSystem_ForEach : SystemBase
    {
        struct RotateData
        {
            float3 m_Direction;
            float m_DeltaTime;
            float m_Speed;
    
            public RotateData(float3 direction, float deltaTime, float speed) 
                => (m_Direction, m_DeltaTime, m_Speed) = (direction, deltaTime, speed);
            public void DoWork(ref Rotation rotation) 
                => rotation.Value = math.mul(math.normalize(rotation.Value), 
                    quaternion.AxisAngle(m_Direction, m_Speed * m_DeltaTime));
        }
    
        protected override void OnUpdate()
        {
            var rotateUp = new RotateData(math.up(), Time.DeltaTime, 3.0f);
            Entities.ForEach((ref Rotation rotation) 
                => rotateUp.DoWork(ref rotation))
                .ScheduleParallel();
        }
    }
    

    Note: this pattern copies the data into your job struct (and back out if used with .Run). If you do this with very large job structs it can have some performance overhead due to struct copying. In this case it might be a sign that your job should be split up into multiple smaller jobs.

    For more information about creating ECS systems, see:

    • Systems
    • SystemBase
    In This Article
    • Structuring code with Entities.ForEach
      • Call static methods from an Entities.ForEach
      • Encapsulate data and method in a captured value-type:
    Back to top
    Copyright © 2023 Unity Technologies — Terms of use
    • Legal
    • Privacy Policy
    • Cookies
    • Do Not Sell or Share My Personal Information
    • Your Privacy Choices (Cookie Settings)
    "Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
    Generated by DocFX on 18 October 2023