Advertisement
Guest User

AfterImage.cs (URP)

a guest
Nov 23rd, 2021
829
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.71 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4.  
  5. public class AfterImage : MonoBehaviour
  6. {
  7.     [SerializeField]
  8.     bool RandomColor;
  9.     [SerializeField]
  10.     float delay;
  11.     [SerializeField]
  12.     string fadeProperty = "_Fade";
  13.     [SerializeField]
  14.     GameObject presetObj;
  15.     [SerializeField]
  16.     int poolSize = 1000;
  17.     [SerializeField]
  18.     Rigidbody rb;
  19.     Renderer[] renderers;
  20.     [SerializeField]
  21.     float fadeSpeed = 3f;
  22.     float[] fadeTimers;
  23.     float timer;
  24.     SkinnedMeshRenderer[] skinRenderers;
  25.     MeshRenderer[] meshRenderers;
  26.     Matrix4x4 matrix;
  27.     CombineInstance[] combine;
  28.     List<GameObject> objectPool;
  29.     MeshFilter[] poolMeshFilters;
  30.     MeshFilter[] meshFilters;
  31.  
  32.  
  33.     void Start()
  34.     {
  35.         SetUpRenderers();
  36.  
  37.         // create a pool for all the objects for the trail
  38.         objectPool = new List<GameObject>();
  39.         poolMeshFilters = new MeshFilter[poolSize];
  40.         renderers = new Renderer[poolSize];
  41.         fadeTimers = new float[poolSize];
  42.  
  43.         // instantiate the pool of objects
  44.         for (int i = 0; i < poolSize; i++)
  45.         {
  46.             GameObject obj = Instantiate(presetObj);
  47.             poolMeshFilters[i] = obj.GetComponent<MeshFilter>();
  48.             renderers[i] = obj.GetComponent<Renderer>();
  49.             // renderers[i].material = dodgeMat;
  50.             obj.SetActive(false);
  51.             objectPool.Add(obj);
  52.         }
  53.     }
  54.  
  55.     void SetUpRenderers()
  56.     {
  57.         // get the skinned mesh renderers
  58.         skinRenderers = transform.GetComponentsInChildren<SkinnedMeshRenderer>();
  59.         // get normal mesh renderers and their filters
  60.         meshRenderers = transform.GetComponentsInChildren<MeshRenderer>();
  61.         meshFilters = new MeshFilter[meshRenderers.Length];
  62.         for (int i = 0; i < meshRenderers.Length; i++)
  63.         {
  64.             meshFilters[i] = meshRenderers[i].GetComponent<MeshFilter>();
  65.         }
  66.         // create combineinstances for every mesh we need to grab
  67.         combine = new CombineInstance[skinRenderers.Length + meshRenderers.Length];
  68.     }
  69.  
  70.  
  71.  
  72.     void Update()
  73.     {
  74.  
  75.         timer -= Time.deltaTime;
  76.  
  77.         // only create image if moving and timer is down
  78.         if (timer < 0 && rb.velocity.magnitude > 0.1f)
  79.         {
  80.             timer = delay;
  81.             CreateAfterImage();
  82.         }
  83.  
  84.         // fade the property block
  85.         for (int i = 0; i < poolSize; i++)
  86.         {
  87.             fadeTimers[i] -= Time.deltaTime * fadeSpeed;
  88.             renderers[i].material.SetFloat(fadeProperty, fadeTimers[i]);
  89.  
  90.         }
  91.  
  92.     }
  93.  
  94.  
  95.  
  96.     // get a gameobject from the pool, and its index
  97.     public (GameObject, int) GetPooledObject()
  98.     {
  99.         for (int i = 0; i < objectPool.Count; i++)
  100.         {
  101.             if (!objectPool[i].activeInHierarchy)
  102.             {
  103.                 return (objectPool[i], i);
  104.             }
  105.         }
  106.         return (null, -1);
  107.     }
  108.  
  109.     void CreateAfterImage()
  110.     {
  111.         // grab a pooled object
  112.         (GameObject, int) obj = GetPooledObject();
  113.         // if no object to assign, return
  114.         if (obj.Item1 == null)
  115.         {
  116.             return;
  117.         }
  118.         // current transform matrix
  119.         matrix = transform.worldToLocalMatrix;
  120.         //  create mesh snapshot for all skinned meshes      
  121.         for (int i = 0; i < skinRenderers.Length; i++)
  122.         {
  123.             Mesh mesh = new Mesh();
  124.             skinRenderers[i].BakeMesh(mesh);
  125.             combine[i].mesh = mesh;
  126.             combine[i].transform = matrix * skinRenderers[i].localToWorldMatrix;
  127.         }
  128.         // also add normal meshes
  129.         for (int i = 0; i < meshRenderers.Length; i++)
  130.         {
  131.             combine[skinRenderers.Length + i].mesh = meshFilters[i].sharedMesh;
  132.             combine[skinRenderers.Length + i].transform = matrix * meshRenderers[i].transform.localToWorldMatrix;
  133.         }
  134.  
  135.         // set property block
  136.         fadeTimers[obj.Item2] = 1f;
  137.         renderers[obj.Item2].material.SetFloat(fadeProperty, fadeTimers[obj.Item2]);
  138.         if (RandomColor)
  139.         {
  140.             renderers[obj.Item2].material.SetColor("_Color", Random.ColorHSV(0, 1, 0.5f, 1, 1, 1));
  141.         }
  142.  
  143.         // combine meshes into the right instance
  144.         poolMeshFilters[obj.Item2].mesh.CombineMeshes(combine);
  145.  
  146.         // set object to transform and active
  147.         obj.Item1.transform.position = transform.position;
  148.         obj.Item1.transform.rotation = transform.rotation;
  149.         obj.Item1.SetActive(true);
  150.  
  151.         StartCoroutine(DisableClone(obj.Item1));
  152.  
  153.     }
  154.     IEnumerator DisableClone(GameObject objec)
  155.     {
  156.         yield return new WaitForSeconds(3f);
  157.         objec.SetActive(false);
  158.     }
  159.  
  160. }
  161.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement