---
# System prepended metadata

title: Unity Platform 07 Afterimage with Sprite Pool
tags: [platform]

---

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;
        }
    }
}
```
