Advertisement
JontePonte

Particle life draft

Oct 6th, 2024
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.50 KB | None | 0 0
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using System.Security.Cryptography;
  4. using Unity.VisualScripting;
  5. using UnityEngine;
  6.  
  7. //Red = 0
  8. //Blue = 1
  9. //Yellow = 2
  10. //Green = 3
  11.  
  12. public struct Particle
  13. {
  14.     public byte type;
  15.     public Vector2 pos;
  16.     public Vector2 vel;
  17. }
  18.  
  19. public enum matrixPreset
  20. {
  21.     random,
  22.     symmetry,
  23.     chains,
  24.     chains2,
  25.     chains3,
  26.     snakes,
  27.     zero
  28. }
  29.  
  30. public class Main : MonoBehaviour
  31. {
  32.     public matrixPreset preset;
  33.     public RenderTexture renderTexture;
  34.     public ComputeShader computeShader;
  35.  
  36.     public int particleCount;
  37.     public float particleSize;
  38.     public float forceFactor;
  39.     public float maxDist;
  40.     public float friction;
  41.     public Material particleMaterial;
  42.  
  43.     float[,] attractionMatrix;
  44.     Particle[] particles;
  45.  
  46.     void Start()
  47.     {
  48.         switch (preset)
  49.         {
  50.             case matrixPreset.random:
  51.                 attractionMatrix = new float[,]
  52.                 {
  53.                     {Rand(), Rand(), Rand(), Rand(), Rand(), Rand()},
  54.                     {Rand(), Rand(), Rand(), Rand(), Rand(), Rand()},
  55.                     {Rand(), Rand(), Rand(), Rand(), Rand(), Rand()},
  56.                     {Rand(), Rand(), Rand(), Rand(), Rand(), Rand()},
  57.                     {Rand(), Rand(), Rand(), Rand(), Rand(), Rand()},
  58.                     {Rand(), Rand(), Rand(), Rand(), Rand(), Rand()},
  59.                 };
  60.                 break;
  61.  
  62.             case matrixPreset.symmetry:
  63.  
  64.                 float[] rand = new float[22];
  65.                 for (int i = 0; i < rand.Length; i++)
  66.                 {
  67.                     rand[i] = Rand();
  68.                 }
  69.  
  70.                 attractionMatrix = new float[,]
  71.                 {
  72.                     {rand[0], rand[1], rand[2], rand[3], rand[4], rand[5]},
  73.                     {rand[1], rand[7], rand[8], rand[9], rand[10], rand[11]},
  74.                     {rand[2], rand[8], rand[12], rand[13], rand[14], rand[15]},
  75.                     {rand[3], rand[9], rand[13], rand[16], rand[17], rand[18]},
  76.                     {rand[4], rand[1], rand[14], rand[17], rand[19], rand[20]},
  77.                     {rand[5], rand[1], rand[15], rand[18], rand[20], rand[21]},
  78.                 };
  79.                 break;
  80.  
  81.             case matrixPreset.chains:
  82.                 attractionMatrix = new float[,]
  83.                 {
  84.                     {1, 1, -1, -1, -1, 1},
  85.                     {1, 1, 1, -1, -1, -1},
  86.                     {-1, 1, 1, 1, -1, -1},
  87.                     {-1, -1, 1, 1, 1, -1},
  88.                     {-1, -1, -1, 1, 1, 1},
  89.                     {1, -1, -1, -1, 1, 1},
  90.                 };
  91.                 break;
  92.  
  93.             case matrixPreset.chains2:
  94.                 attractionMatrix = new float[,]
  95.                 {
  96.                     {1, .2f, -1, -1, -1, .2f},
  97.                     {.2f, 1, .2f, -1, -1, -1},
  98.                     {-1, .2f, 1, .2f, -1, -1},
  99.                     {-1, -1, .2f, 1, .2f, -1},
  100.                     {-1, -1, -1, .2f, 1, .2f},
  101.                     {.2f, -1, -1, -1, .2f, 1},
  102.                 };
  103.                 break;
  104.  
  105.             case matrixPreset.chains3:
  106.                 attractionMatrix = new float[,]
  107.                 {
  108.                     {1, .2f, 0, 0, 0, 0},
  109.                     {.2f, 1, .2f, 0, 0, 0},
  110.                     {0, .2f, 1, .2f, 0, 0},
  111.                     {0, 0, .2f, 1, .2f, 0},
  112.                     {0, 0, 0, .2f, 1, .2f},
  113.                     {.2f, 0, 0, 0, .2f, 1},
  114.                 };
  115.                 break;
  116.  
  117.             case matrixPreset.snakes:
  118.                 attractionMatrix = new float[,]
  119.                 {
  120.                     {1, .2f, 0, 0, 0, 0},
  121.                     {0, 1, .2f, 0, 0, 0},
  122.                     {0, 0, 1, .2f, 0, 0},
  123.                     {0, 0, 0, 1, .2f, 0},
  124.                     {0, 0, 0, 0, 1, .2f},
  125.                     {.2f, 0, 0, 0, 0, 1},
  126.                 };
  127.                 break;
  128.  
  129.             case matrixPreset.zero:
  130.                 attractionMatrix = new float[,]
  131.                 {
  132.                     {0, 0, 0, 0, 0, 0},
  133.                     {0, 0, 0, 0, 0, 0},
  134.                     {0, 0, 0, 0, 0, 0},
  135.                     {0, 0, 0, 0, 0, 0},
  136.                     {0, 0, 0, 0, 0, 0},
  137.                     {0, 0, 0, 0, 0, 0},
  138.                 };
  139.                 break;
  140.         }
  141.  
  142.         particles = new Particle[particleCount];
  143.  
  144.         ParticleRenderer.particleSize = particleSize;
  145.         ParticleRenderer.particleMat = particleMaterial;
  146.  
  147.         for (int i = 0; i < particleCount; i++)
  148.         {
  149.             Vector2 position = new Vector2(Random.Range(-9f, 9f), Random.Range(-9f, 9f));
  150.  
  151.             particles[i] = new Particle
  152.             {
  153.                 type = (byte)Random.Range(0, 6),
  154.                 pos = position,
  155.                 vel = Vector2.zero
  156.             };
  157.  
  158.         }
  159.  
  160.         renderTexture = new RenderTexture(256, 256, 24);
  161.         renderTexture.enableRandomWrite = true;
  162.         renderTexture.Create();
  163.     }
  164.  
  165.     private void OnRenderImage(RenderTexture source, RenderTexture destination)
  166.     {
  167.         computeShader.SetTexture(0, "Result", renderTexture);
  168.  
  169.         Graphics.Blit(renderTexture, destination);
  170.     }
  171.  
  172.     void Update()
  173.     {
  174.         for (int i = 0; i < particleCount; i++)
  175.         {
  176.             UpdatePosition(i);
  177.             UpdateForce(i);
  178.         }
  179.  
  180.         // int length = particleCount * particleCount;
  181.         // for (int index = 0; index < length; index++)
  182.         // {
  183.         //     int i = index / particleCount;
  184.         //     int j = index % particleCount;
  185.  
  186.         //     if (j < particleCount)
  187.         //     {
  188.         //         UpdatePosition(i);
  189.         //     }
  190.  
  191.         //     if (j == i) { continue; }
  192.         //     UpdateForce(i, j);
  193.         // }
  194.  
  195.         ParticleRenderer.Render(particles);
  196.     }
  197.  
  198.  
  199.  
  200.     void UpdatePosition(int i)
  201.     {
  202.         particles[i].pos += particles[i].vel * Time.deltaTime;
  203.  
  204.         //If particle is outside screen, put it on other side
  205.         if (Mathf.Abs(particles[i].pos.x) > 10f || Mathf.Abs(particles[i].pos.y) > 10f)
  206.         {
  207.             particles[i].pos = -particles[i].pos;
  208.             particles[i].pos += particles[i].vel;
  209.         }
  210.  
  211.     }
  212.  
  213.     //Explanation: https://www.youtube.com/watch?v=scvuli-zcRc&t=101s
  214.     void UpdateForce(int i)
  215.     {
  216.         Vector2 totalForce = new();
  217.         byte thisType = particles[i].type;
  218.  
  219.         for (int j = 0; j < particleCount; j++)
  220.         {
  221.             if (j == i) { continue; }
  222.  
  223.             byte targetType = particles[j].type;
  224.  
  225.             Vector2 diff = particles[j].pos - particles[i].pos;
  226.             float dist = diff.magnitude;
  227.  
  228.             if (dist > 0 && dist < maxDist)
  229.             {
  230.                 float force = Force(dist / maxDist, attractionMatrix[thisType, targetType]);
  231.  
  232.                 totalForce += new Vector2(diff.x / dist * force, diff.y / dist * force);
  233.             }
  234.  
  235.         }
  236.  
  237.         totalForce *= maxDist * forceFactor;
  238.         particles[i].vel *= friction;
  239.         particles[i].vel += totalForce * Time.deltaTime;
  240.  
  241.     }
  242.  
  243.     float Force(float dist, float attraction)
  244.     {
  245.         const float beta = .3f;
  246.  
  247.         if (dist < beta)
  248.         {
  249.             return dist / beta - 1;
  250.         }
  251.         else if (beta < dist && dist < 1)
  252.         {
  253.             return attraction * (1 - Mathf.Abs(2 * dist - 1 - beta) / (1 - beta));
  254.         }
  255.         else
  256.         {
  257.             return 0;
  258.         }
  259.     }
  260.  
  261.     float Rand()
  262.     {
  263.         return Random.Range(-1f, 1f);
  264.     }
  265. }
  266.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement