MeshInstanceRenderer - possibility to consider scale and color of the texture to be drawn?

Hi,

I wanted to start off by saying I'm a little mad - this is a repost because my previous post was deleted. The reason I got was "duplicate post", but I couldn't find my exact question and I have searched on the forum.
The ECS is fairly new and I have a difficult time to find good resources and tutorials, so why deleting this post?

Here is my original question:

There are these requirements for my game and I would like to know if it is possible to achieve them with the MeshInstanceRenderer.

So in my game I want to:
- set position of a sprite
- set the rotation of a sprite
- set the scale of a sprite, uniform - one value for both axes
- set the color of my sprite.

  • without the use of a GameObject.

The SpriteInstanceRenderer that is available on Github here (https://github.com/paullj/unity-ecs-instanced-sprite-renderer) let's me scale the sprite with a little bit of tweaking but not rotate it.
As for the size and color adjustment:
One way I tried to do it was to render with batches of 1 and change the mesh for the size and the material for the color each time.
As you can imagine, performance was abysmal.

So do you have a hint how to go about this?
I might have to resort to regular gameObjects for rendering again.

Kind regards

1 Like

As mentioned on previous post, you can se the color either on Mesh (by vertex basis) ou on Material, which will require a new material per color setting.

And here is the scale system script again:

Component:

public struct Scale : IComponentData
{
    public float3 Value;
}

System:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;

public class ScaleSystem : ComponentSystem
{
    struct ScaleData
    {
        public int Length;
        [ReadOnly] public ComponentDataArray<Scale> Scales;
        public ComponentDataArray<TransformMatrix> Matrices;
    }

    [Inject] private ScaleData _Data;

    protected override void OnUpdate()
    {
        for (var i = 0; i < _Data.Length; i++)
        {
            var baseMat = _Data.Matrices[i].Value;
            var scaleMat = math.scale(_Data.Scales[i].Value);
            var newMat = math.mul(baseMat, scaleMat);

            _Data.Matrices[i] = new TransformMatrix { Value = newMat };
        }
    }
}
1 Like

Awesome! Thanks again!

So I have actually found a thread that covers scaling, together with your post.
But I'm still unsure how to go about the colors. Since this is purely cosmetic, I'm fine though. I'll definitely look into the option to set the colors for the Mesh and apply a shader that takes it into account.

Here is the scaling post:
https://discussions.unity.com/t/696453
And here is the gist on github of a full system:
https://gist.github.com/JoeCoo7/f497af9b1ba2ab5babae3060635a9c6a

@Afonso-Lage

math.scale() works really well. One optimization though: I would make it a JobComponentSystem class, so that the calculations happen in parallel.

Here is my script. My BulletBDStruct component has 2 separate scale values that have to be combined to get the real scale, a z-rotation (rotationVisual) and of course a position. The following job calculates the Matrix of the component.
ModelMatrix is actually the same as TransformMatrix, the different struct is only used to be able to interact with different systems.

public class BulletMatrixTransformJobSystem : JobComponentSystem
    {

        [ComputeJobOptimization]
        private struct BulletMatrixTransformJob : IJobProcessComponentData<BulletBDStruct, ModelMatrix>
        {
            public void Execute(ref BulletBDStruct bullet, ref ModelMatrix transform)
            {
                float scale = bullet.baseScaling * bullet.scaleMultiplier;
                float3 scaleVec = new float3(scale, scale, scale);
                transform.Value = math.mul(math.rottrans(Quaternion.Euler(0, 0, bullet.rotationVisual), new float3(bullet.posX, bullet.posY, bullet.posZ)), math.scale(scaleVec));
            }
        }

        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {
            var job = new BulletMatrixTransformJob();
            return job.Schedule(this, 20, inputDeps);
        }
    }
1 Like

[quote=“FM-Productions”, post:1, topic: 703715]
Hi,

I wanted to start off by saying I’m a little mad - this is a repost because my previous post was deleted. The reason I got was “duplicate post”, but I couldn’t find my exact question and I have searched on the forum.
The ECS is fairly new and I have a difficult time to find good resources and tutorials, so why deleting this post?
I chose to post again, because contacting Unity per mail would take most likely a few days until someone answers.

If this post gets deleted again, could you at least provide me with the link of the “original thread” if this is a duplicate? I posted my question on a different thread too as comment, but that question was directed to the developer of the SpriteInstanceRenderer package.

So, that’s the end of my rant.
[/quote]

So, my assumption, is that your search scope was rather too focused on the words you were looking for where as other questions have been answered, that answer yours. I know personally I find myself searching this forum for questions via Google, since using the unity search feature gives far from ideal results :stuck_out_tongue:

Here are two examples I know of personally that matched what you were looking for in terms of a built in mechanics.

https://discussions.unity.com/t/695721
https://discussions.unity.com/t/697862

I have also seen the “scaled” question about 3 times on this forum already. These features are coming, and while build-able solutions are doable, I wouldn’t go so far as to say they are necessarily viable

My recommendation for the future, would be to NOT repost without contacting the moderators as 1) they deleted it within the same day of you posting, so it is unlikely they wouldn’t see your inquiry on elaborating why.

2 Likes

Okay, sorry. Usually I don't mind that much, but since I haven't gotten the chance to copy the useful Afonso-Lange posted, I was a bit startled. Luckily I had an older version of the thread opened in another tab, so I could see his user tag and write him a message about the code he posted.

And thanks for posting the link the the property blocks thread. I think that is what I would have to use in the future for color swaps. But I would have never looked for those keywords.

As for the scaling problem, I am very satisfied with the solution I posted above. position, rotation and scale are applied to the ModelMatrix and rendered by a custom system that works very similar to the regular MeshInstanceRendererSystem I think. The system was shared by a community member here: https://gist.github.com/JoeCoo7/f497af9b1ba2ab5babae3060635a9c6a#file-renderersystem

So to conclude this thread, some awesome people from this forum helped me to solve the color problem by using a MaterialPropertyBlock as parameter for the DrawMeshInstanced function. You can find the solution in this thread:
https://discussions.unity.com/t/697299/29

And the repository for a sprite rendering system that can manage scale and color here:
https://github.com/Necromantic/ECS-Sandbox

A small showcase can be found here:


Thanks to @Necromantic and @Rennan24 for helping me out!

1 Like