How do I assign a public variable inside a JobComponentSystem(ECS)?

I’m attempting to test the viability of running a compute-shader inside OnUpdate() inside the ECS Job system. However, I’m not sure when and where the JobComponentSystem object is created so I can’t assign the compute shader below. I’m afraid my only option is to find it at runtime in the OnCreateManager() method. Even still, I don’t think you can access Resources from job’s threads at this time so I’m not quite sure how I’d find the compute-shader using pure scripting.

I thoroughly googled before coming here. I don’t think anybody else has been crazy enough to try something like this yet.

The following code compiles, but of course gives a NullReference Error for the compute Shader when it runs.

using System.Collections;
using Unity.Collections;
using UnityEngine;
using Unity.Entities;
using Unity.Jobs;
using Unity.Mathematics;
using Unity.Transforms;


public class PositionSystem : JobComponentSystem
{
    public ComputeShader locGen;

    public struct PositionData
    {
        
        public readonly ComponentDataArray<Position> Pos;
        public readonly int Length;
    }

    [Unity.Burst.BurstCompile]
    public struct PositionJob : IJobProcessComponentData<Position, Rotation>
    {
        public float deltaTime;

        public void Execute(ref Position position, [ReadOnly] ref Rotation rotation)
        {

            //float3 value = position.Value;

            //position.Value = value;
        }
    }

    [Inject] PositionData m_Positions;

    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {

        int kernelHandle = locGen.FindKernel("CSMain");

        RenderTexture tex = new RenderTexture(256, 256, 24);
        tex.enableRandomWrite = true;
        tex.Create();

        locGen.SetTexture(kernelHandle, "Result", tex);
        locGen.Dispatch(kernelHandle, 256 / 8, 256 / 8, 1);

        /*
        for (int i = 0; i < m_Positions.Length; i++)
        {

            //Debug.Log(m_Positions.Pos*.Value);*

}*/

PositionJob posJob = new PositionJob
{
deltaTime = Time.deltaTime
};

JobHandle positionHandle = posJob.Schedule(this, inputDeps);

positionHandle.Complete();

return positionHandle;
}
}
@5argon please halp :slight_smile:

So as it turns out, all my notions about ECS and Jobs were wrong.

OnUpdate() is actually called from the main thread so you can access (mostly?)everything from the monobehaviour API. What ended up actually doing is loading my ComputeShader at the top of my class
and then finding a plane in my scene to paste the render texture to every update.

So basically I ended up not utilizing the jobs system at all. But my plan is to move the execution of this ComputeShader into a job of its own and use an ISharedComponentData to share a compute buffer between ECS and my compute shader which I’m hoping will give me a pretty good powerhouse for the simulation I’m attempting to do.

For now, here’s the code that allows you to run the ComputeShader in OnUpdate(), which again, AFAIK is run on the main thread.

public class PositionSystem : JobComponentSystem
{
    public ComputeShader locGen = Resources.Load<ComputeShader>("locationDraw");
    public GameObject plane;
 
    public struct PositionData
    {
        
        public readonly ComponentDataArray<Position> Pos;
        public readonly int Length;
    }

    [Unity.Burst.BurstCompile]
    public struct PositionJob : IJobProcessComponentData<Position, Rotation>
    {
        public float deltaTime;

        public void Execute(ref Position position, [ReadOnly] ref Rotation rotation)
        {

            //float3 value = position.Value;

            //position.Value = value;
        }
    }

    [Inject] PositionData m_Positions;

    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        int kernelHandle = locGen.FindKernel("CSMain");

        RenderTexture tex = new RenderTexture(256, 256, 24);
        tex.enableRandomWrite = true;
        tex.Create();

        locGen.SetTexture(kernelHandle, "Result", tex);
        locGen.Dispatch(kernelHandle, 256 / 8, 256 / 8, 1);

        //really hacky way to assign this, but its just for debug so who cares
        if(plane == null) plane = GameObject.FindGameObjectWithTag("RenderPlane");
        plane.GetComponent<MeshRenderer>().material.SetTexture("_MainTex",tex);

        /*
        for (int i = 0; i < m_Positions.Length; i++)
        {

            //Debug.Log(m_Positions.Pos*.Value);*

}*/

PositionJob posJob = new PositionJob
{
deltaTime = Time.deltaTime
};

JobHandle positionHandle = posJob.Schedule(this, inputDeps);

positionHandle.Complete();

return positionHandle;
}
}