Unity Platform 07 Afterimage with Sprite Pool === 2020.08.13 ###### tags: `platform` ## List 1. [Sprite Pool](#SP) 2. [How to make Pool](#HP) 3. [Apply Dash](#AD) ## Content ### Sprite Pool<a id="SP"/> Sprite Pool is one of technic for decresing memories used by creating resources.<br>Make Set(Array) named <b>*'Pool'*</b>, use sprite(Image) in pool when it needs.<br>This example show sprite pool with afterimage of dash.<br><br> ### How to make Pool<a id="HP"/> Commonly, Pool is Queue(*or some list*) consist of prefab.<br>First, push prefab into Queue, and get it when prefab is needs.<br>`instance` in `Awake()` is technic for acess class outside of scipt. ```csharp= public class PlayerAfterImagePool : MonoBehaviour { [SerializeField] private GameObject afterImagePrefab; private Queue<GameObject> availableObjects = new Queue<GameObject>(); public static PlayerAfterImagePool Instance { get; private set; } private void Awake() { Instance = this; GrowPool(); } private void GrowPool() { for (int i =0 ; i < 10 ; i++) { var instanceToAdd = Instantiate(afterImagePrefab); instanceToAdd.transform.SetParent(transform); AddToPool(instanceToAdd); } } public void AddToPool(GameObject instance) { instance.SetActive(false); availableObjects.Enqueue(instance); } public GameObject GetFromPool() { if (availableObjects.Count == 0) { GrowPool(); } var instance = availableObjects.Dequeue(); instance.SetActive(true); return instance; } } ``` <br> `AfterImageSprite` is class for afterimage for dash.<br>It must go slowly transparency.<br>And set thier position player's position when dashing.<br>Like below. ```csharp= public class PlayerAfterImageSprite : MonoBehaviour { [SerializeField] private float activeTime = 0.1f; private float timeActivated; private float alpha; [SerializeField] private float alphaSet = 0.8f; private float alphaMultiplier = 0.05f; private Transform player; private SpriteRenderer SR; private SpriteRenderer playerSR; private Color color; private void OnEnable() { SR = GetComponent<SpriteRenderer>(); player = GameObject.FindGameObjectWithTag("player").transform; playerSR = player.GetComponent<SpriteRenderer>(); alpha = alphaSet; SR.sprite = playerSR.sprite; transform.position = player.position; transform.rotation = player.rotation; timeActivated = Time.time; } private void Update() { alpha *= alphaMultiplier; color = new Color(1f, 1f, 1f, alpha); SR.color = color; if (Time.time >= (timeActivated + activeTime)) { PlayerAfterImagePool.Instance.AddToPool(gameObject); } } } ``` <br><br> ### Apply Dash<a id="AD"/> For Dash, use technic like action script before(*jump, ...*)<br>Use conditions below. ```csharp= private bool isDashing; public float dashTime; public float dashSpeed; public float distanceBetweenImages; public float dashCooldown; private float dashTimeLeft; private float lastImageXpos; private float lastDash = -100f; ``` <br> And Setting Input.<br>`Attempt Dash()` set dash conditions. ```csharp= protected void CheckInput() { ~~~ if (Input.GetButtonDown("Dash")) { if (Time.time >= (lastDash + dashCooldown)) AttemptDash(); } } private void AttemptDash() { isDashing = true; dashTimeLeft = dashTime; lastDash = Time.time; PlayerAfterImagePool.Instance.GetFromPool(); lastImageXpos = transform.position.x; } ``` <br> Last, like other actions, write check_function `CheckDash()`.<br>Dash have to check end of action because of pool stop.<br>Use distance, Control it. ```csharp= private void CheckDash() { if (isDashing) { if (dashTimeLeft > 0) { canMove = false; canFlip = false; rb2D.velocity = new Vector2(dashSpeed * facingDirection, rb2D.velocity.y); dashTimeLeft -= Time.deltaTime; if (Mathf.Abs(transform.position.x - lastImageXpos) > distanceBetweenImages) { PlayerAfterImagePool.Instance.GetFromPool(); lastImageXpos = transform.position.x; } } if (dashTimeLeft <= 0 || isTouchingWall) { isDashing = false; canMove = true; canFlip = true; } } } ```