Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Linq;
- using TMPro;
- using Unity.Burst;
- using Unity.Collections;
- using Unity.Jobs;
- using Unity.Profiling;
- using UnityEngine;
- using static Unity.Mathematics.math;
- using static ProofMath.mathUtils;
- using float3 = Unity.Mathematics.float3;
- using Random = Unity.Mathematics.Random;
- public struct Entity
- {
- public float3 Position;
- public float Orientation;
- public float3 Scale;
- public float3 MovementDirection;
- public float Speed;
- public float RotationSpeed;
- }
- public struct EntityRenderState
- {
- public Material Material;
- public Mesh Mesh;
- }
- public struct InstanceData
- {
- public Matrix4x4 objectToWorld;
- }
- public class Proof : MonoBehaviour
- {
- public TMP_Text FrameTime;
- public TMP_Text FrameRate;
- public int EntitiesCount = 10000;
- public Sprite EntitySprite;
- public Material EntityMaterial;
- public Texture EntityTexture;
- private NativeArray<Entity> _entities;
- private EntityRenderState _renderState;
- private static InstanceData[] _perInstanceData;
- private static readonly int MainTex = Shader.PropertyToID("_MainTex");
- private static readonly ProfilerMarker UpdateEntities = new ProfilerMarker(nameof(UpdateEntities));
- private static readonly ProfilerMarker Render = new ProfilerMarker(nameof(Render));
- private void Start()
- {
- _entities = new NativeArray<Entity>(EntitiesCount, Allocator.Persistent);
- _perInstanceData = new InstanceData[EntitiesCount];
- var random = Random.CreateFromIndex(123);
- var size = new float3(100f, 100f, 0f);
- var one = new float3(1f, 1f, 1f);
- for (var i = 0; i < EntitiesCount; ++i)
- {
- var position = random.NextFloat3(-size, size);
- var direction = random.NextFloat3(new float3(1, 1, 0));
- var speed = random.NextFloat(15f);
- var rotationSpeed = random.NextFloat(180f);
- var startOrientation = random.NextFloat(360f);
- _entities[i] = new Entity
- {
- Position = position,
- MovementDirection = direction,
- Speed = speed,
- RotationSpeed = rotationSpeed,
- Orientation = startOrientation,
- Scale = one
- };
- }
- //Convert sprite to mesh
- var mesh = new Mesh();
- mesh.SetVertices(Array.ConvertAll(EntitySprite.vertices, i => (Vector3)i).ToList());
- mesh.SetUVs(0, EntitySprite.uv.ToList());
- mesh.SetTriangles(Array.ConvertAll(EntitySprite.triangles, i => (int)i),0);
- _renderState = new EntityRenderState()
- {
- Material = new Material(EntityMaterial),
- Mesh = mesh
- };
- _renderState.Material.SetTexture(MainTex, EntityTexture);
- }
- private void OnDestroy()
- {
- _entities.Dispose();
- }
- private void Update()
- {
- //move entities
- var deltaTime = Time.deltaTime;
- FrameTime.text = deltaTime.ToString();
- FrameRate.text = (1.0f / deltaTime).ToString();
- UpdateEntities.Begin();
- var job = new MovementJob()
- {
- Entities = _entities,
- DeltaTime = deltaTime
- };
- var handle = job.Schedule(EntitiesCount, 32);
- handle.Complete();
- UpdateEntities.End();
- //Render entities
- Render.Begin();
- var rp = new RenderParams(_renderState.Material);
- for (var i = 0; i < EntitiesCount; ++i)
- {
- var entity = _entities[i];
- var trs = Matrix4x4.TRS(
- entity.Position,
- Quaternion.Euler(0, 0, entity.Orientation),
- entity.Scale);
- _perInstanceData[i].objectToWorld = trs;
- }
- Graphics.RenderMeshInstanced(rp, _renderState.Mesh, 1, _perInstanceData, EntitiesCount);
- Render.End();
- }
- }
- [BurstCompile]
- public struct MovementJob : IJobParallelFor
- {
- public NativeArray<Entity> Entities;
- public float DeltaTime;
- public void Execute(int index)
- {
- var entity = Entities[index];
- var targetOrientation = degrees(atan2(entity.MovementDirection.y, entity.MovementDirection.x)) - 90f;
- entity.Position += entity.MovementDirection * entity.Speed * DeltaTime;
- entity.Orientation = movetoangle(entity.Orientation, targetOrientation, entity.RotationSpeed * DeltaTime);
- Entities[index] = entity;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement