Advertisement
Guest User

AfterImage.cs

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