Home Game Development unity – How do create good trying sprite coloration stretching metaballs?

unity – How do create good trying sprite coloration stretching metaballs?

0
unity – How do create good trying sprite coloration stretching metaballs?

[ad_1]

It has been 8 months I have been engaged on my metaball algorithm an the ultimate method I’m attempting out is writing magnets to which the sprite mesh edge vertices will replace its place to, after discovering the closest magnet level. The crimson traces shall be magnet areas.

enter image description here

The issue is, after a number of hours of debugging and at last implementing an ECS construction that updates the positions of every gameobject sprite vertex to the closest magnet level, these are the ugly results under:

enter image description here

enter image description here

Could I ask for some recommendation on implement these coloration stretching metaballs for any recreation object sprite? It is near a yr I am engaged on it now… Ought to making use of Lerp assist??

Right here is the ECS code that updates slime mesh vertex positions:

utilizing System.Collections;
utilizing System.Collections.Generic;
utilizing UnityEngine;
utilizing Unity.Entities;
utilizing Unity.Jobs;
utilizing Unity.Collections;
utilizing HerminkasGams.SpriteSquash;
utilizing System.Linq;
utilizing UnityEditor;
utilizing Unity.Burst;
utilizing System.Runtime.Serialization;
utilizing Unity.VisualScripting;

public partial class VertexUpdater : SystemBase
{
    public GameObject ObjectManager;
    public ObjectManagerController objectManagerController;
    [HideInInspector] public Record<SpriteMeshModifier> spriteMeshModifiers = new Record<SpriteMeshModifier>();
    // [HideInInspector] public Record<Vertex> vertices = new Record<Vertex>();  // Record of vertices; every ingredient of this variable is what I have to make magnetic

    non-public struct VertexCopy {
        public Vector3 currentPos;
        public Vector3 initialPos;
        public Vector3 revertingPos;
        public int _metaballEdgePointCount;

        //_parentSpriteMeshModifier variables:
        public Vector3 _parentSpriteMeshModifierPosition;
        public Quaternion _parentSpriteMeshModifierRotation;
        public Vector3 _parentSpriteMeshModifierLocalscale;

        [HideInInspector]public int _index;
        [HideInInspector]public Vector3 _closestMagnetPoint;
    
        public VertexCopy(Vector3 pos, int index, int metaballEdgePointCount, Vector3 parentSpriteMeshModifierPosition, Quaternion parentSpriteMeshModifierRotation, Vector3 parentSpriteMeshModifierLocalscale, Vector3 closestMagnetPoint) {
            currentPos = pos;
            initialPos = pos;
            revertingPos = pos;
            _index = index;
            _metaballEdgePointCount = metaballEdgePointCount;
            //_parentSpriteMeshModifierPosition variables
            _parentSpriteMeshModifierPosition = parentSpriteMeshModifierPosition;
            _parentSpriteMeshModifierRotation = parentSpriteMeshModifierRotation;
            _parentSpriteMeshModifierLocalscale = parentSpriteMeshModifierLocalscale;
            _closestMagnetPoint = closestMagnetPoint;
        }

        public (Vector3, float) FindNearestMagnetPoint(NativeArray<Vector3> metaballVertexPositionArray) {
            float minDistanceUnaltered = 99999;
            //Compute the closest metaball edge magnet level by iterating by means of them if metaballEdgePointVertexGOs shouldn't be empty
            if (_metaballEdgePointCount > 0) {
                int index = 0;
                Vector3 scp = _parentSpriteMeshModifierRotation * currentPos;
                Vector3 level = new Vector3(scp.x * _parentSpriteMeshModifierLocalscale.x, scp.y * _parentSpriteMeshModifierLocalscale.y, scp.z * _parentSpriteMeshModifierLocalscale.z) + _parentSpriteMeshModifierPosition;
                
                float minDistance = 99999;

                //Will iterate by means of metaballEdgePointVertexGOs to search out closest
                //Vector3 scpMagnet = new Vector3(0,0,0);
                for (int i = 0; i < _metaballEdgePointCount; i++)
                {   
                    var dis = Vector2.Distance(level, metaballVertexPositionArray[i]);
                    if (dis < minDistance)
                    {
                        index = i;
                        minDistance = dis;
                    }
                }
                
                //Invert metaballVertexPositionArray[index] again to vertex coordinates
                Vector3 vec1 = metaballVertexPositionArray[index] - _parentSpriteMeshModifierPosition;
                Vector3 vec2 = _parentSpriteMeshModifierLocalscale;
                Vector3 outcome = new Vector3(vec1.x / vec2.x, vec1.y / vec2.y, vec1.z / vec2.z);
                Vector3 scpLocal = Quaternion.Inverse(_parentSpriteMeshModifierRotation) * (outcome);
                // Debug.Log(currentPos);
                return (scpLocal, minDistance);
            }
            return (new Vector3(0,0,-1), minDistanceUnaltered);
        }
    }

    [BurstCompile]
    non-public struct ComputeJob : IJobFor {
        [NativeDisableParallelForRestriction]
        public NativeArray<VertexCopy> vertexCopyArray;
        [ReadOnly]
        public NativeArray<Vector3> metaballVertexPositionArray;
        
        public void Execute(int index) {
            VertexCopy vertexCopy = this.vertexCopyArray[index];
            float minDistance = 9999;
            (vertexCopy._closestMagnetPoint, minDistance) = vertexCopy.FindNearestMagnetPoint(metaballVertexPositionArray);
            //If closest distance is lower than threshold
            if (minDistance < 0.2) {
                vertexCopy.currentPos = vertexCopy._closestMagnetPoint;
                this.vertexCopyArray[index] = vertexCopy;
            }
        }
    }

    protected override void OnStartRunning()
    {
        ObjectManager = GameObject.Discover("ObjectManager");
        objectManagerController = ObjectManager.GetComponent<ObjectManagerController>();
        // GameObject.Discover("SpriteMeshModifier");
        // EntityManager entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
        // // Create an Entity "archetype" that may have MyComponent
        // EntityArchetype spriteMeshModifierArchetype = entityManager.CreateArchetype(typeof(SpriteMeshModifier));
        // // Create an entity with that archetype
        // Entity spriteMeshModifierEntity = entityManager.CreateEntity(spriteMeshModifierArchetype);

        Record<GameObject> waterslimesDisplay = objectManagerController.colorSlimesDisplayGlobal;
        foreach (GameObject waterslimeDisplay in waterslimesDisplay) {
            spriteMeshModifiers.Add(waterslimeDisplay.GetComponent<SpriteMeshModifier>());
        }
        base.OnStartRunning();
    }

    protected override void OnUpdate()
    {
        CallJobs();
        //throw new System.NotImplementedException();
    }

    non-public void CallJobs() {
        foreach (SpriteMeshModifier spriteMeshModifier in spriteMeshModifiers) {
            if(spriteMeshModifier.vertices.Depend > 0 && spriteMeshModifier._isRegenerated && spriteMeshModifier.objectManagerController.metaballEdgePointVertices.Depend > 0) {
                NativeArray<VertexCopy> vertexCopies = new NativeArray<VertexCopy>(spriteMeshModifier.vertices.Depend, Allocator.TempJob);
                NativeArray<Vector3> metaballVertexPositions = new NativeArray<Vector3>(spriteMeshModifier.objectManagerController.metaballEdgePointVertices.Depend, Allocator.TempJob);
                CopyThingsTo(ref vertexCopies, ref metaballVertexPositions, spriteMeshModifier);
                // Do heavy computation in a job
                ComputeJob job = new ComputeJob() {
                    vertexCopyArray = vertexCopies,
                    metaballVertexPositionArray = metaballVertexPositions
                };
                job.ScheduleParallel(vertexCopies.Size, 64, default).Full();
                AssignComputedValues(vertexCopies, spriteMeshModifier);
                UpdatePositions(vertexCopies, spriteMeshModifier);
                // Do not forget to dispose
                vertexCopies.Dispose();
                metaballVertexPositions.Dispose();
            }
        }
    }

    non-public void CopyThingsTo(ref NativeArray<VertexCopy> copiesArray, ref NativeArray<Vector3> metaballVertexPositionsArray, SpriteMeshModifier spriteMeshModifier) {
        for (int i = 0; i < spriteMeshModifier.vertices.Depend; i++) {
            Vertex vertex = spriteMeshModifier.vertices[i];
            copiesArray[i] = new VertexCopy(vertex.currentPos, i, vertex._objectManagerController.metaballEdgePointVertices.Depend, vertex._parentSpriteMeshModifier.remodel.mum or dad.gameObject.remodel.place, vertex._parentSpriteMeshModifier.gameObject.remodel.rotation, vertex._parentSpriteMeshModifier.gameObject.remodel.localScale, vertex._closestMagnetPoint);
        }
        for (int i = 0; i < spriteMeshModifier.objectManagerController.metaballEdgePointVertices.Depend; i++) {
            MetaballEdgePointVertex metaballEdgePointVertex = spriteMeshModifier.objectManagerController.metaballEdgePointVertices[i];
            metaballVertexPositionsArray[i] = metaballEdgePointVertex.currentPos;
        }
    }

    non-public void AssignComputedValues(in NativeArray<VertexCopy> copiesArray, SpriteMeshModifier spriteMeshModifier) {
        for (int i = 0; i < spriteMeshModifier.vertices.Depend; ++i) {
            spriteMeshModifier.vertices[i]._closestMagnetPoint = copiesArray[i]._closestMagnetPoint;
        }
    }

    non-public void UpdatePositions(in NativeArray<VertexCopy> copiesArray, SpriteMeshModifier spriteMeshModifier) {
        for (int i = 0; i < spriteMeshModifier.vertices.Depend; ++i) {
            if(copiesArray[i].currentPos == copiesArray[i]._closestMagnetPoint) {
                //Ought to I lerp between copiesArray[i]._closestMagnetPoint and copiesArray[i].initialPos?
                spriteMeshModifier.vertices[i].UpdateCurrentVertex(copiesArray[i]._closestMagnetPoint, copiesArray[i]._index);
            }
            else {
                spriteMeshModifier.ResetPositionOfSelectedVertex(copiesArray[i]._index);
                spriteMeshModifier.UpdateMesh();
            }
        }
    }
}

[ad_2]

LEAVE A REPLY

Please enter your comment!
Please enter your name here