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