Unity Platform 11 Enermy's Touch Attack
===
2020.08.16
###### tags: `platform`
## List
1. [Touch Attack in Enermy](#TAE)
2. [Touch Attack in Player](#TAP)
3. [Game Manager](#GM)
## Content
### Touch Attack in Enemry<a id="TAE"/>
Almost platformmer player touch enemry, damaged.<br>This technic is simillar player attack and enermy damaged technics.<br>First, write `CheckTocuhDamage()` function in Enemry script.<br>Set hitbox with custom height and width.<br>In real, not just box, poligon shape is better I think.
```csharp=
private void CheckTouchDamage()
{
// Normal game, in player damaged, give undamageable state is better.
if (Time.time >= lastTouchDamageTime + touchDamageCooldown)
{
touchDamageBotLeft.Set(touchDamageCheck.position.x - (touchDamageWidth / 2), touchDamageCheck.position.y - (touchDamageHeight / 2));
touchDamageTopRight.Set(touchDamageCheck.position.x + (touchDamageWidth / 2), touchDamageCheck.position.y + (touchDamageHeight / 2));
Collider2D hit = Physics2D.OverlapArea(touchDamageBotLeft, touchDamageTopRight, whatIsPlayer);
if (hit != null)
{
lastTouchDamageTime = Time.time;
attackDetails[0] = touchDamage;
attackDetails[1] = alive.transform.position.x;
hit.SendMessage("damage", attackDetails);
}
}
}
```
### Touch Attack in Player<a id="TAP"/>
If player touch enermy, knockback like enermy.<br>Same technic enemrys.<br>Not only write below, but also change move condition with knockback flag in `applyMovemet()` and `Flip()`.
```csharp=
private bool knockback;
private float knockbackStartTime;
[SerializeField]
private float knockbackDuration;
[SerializeField]
private Vector2 knockbackSpeed;
public void Knockback(int direction)
{
knockback = true;
knockbackStartTime = Time.time;
rb2D.velocity = new Vector2(knockbackSpeed.x * direction, knockbackSpeed.y);
}
private void CheckKnockback()
{
if (Time.time >= knockbackStartTime + knockbackDuration && knockback)
{
knockback = false;
rb2D.velocity = new Vector2(0.0f, rb2D.velocity.y);
}
}
```
<br>
In PlayerCombat Script, write Damage function like enermy.<br>Check some state(*This is 'dash'*), apply non-damaging check.<br>Call `knockback()` in this.
```csharp=
private void Damage(float[] attackDetails)
{
if (!PC.GetDashState())
{
int direction;
//PS is Player State written below content
PS.DecreaseHealth(attackDetails[0]);
if (attackDetails[1] < transform.position.x)
direction = 1;
else
direction = -1;
PC.Knockback(direction);
}
}
```
And Damaging & Dying in game.<br>Split these action to other class `PlayerState`<br>It just has `DecreaseHealth()` and `Die()`.
```csharp=
public void DecreaseHealth(float damage)
{
currentHealth -= damage;
if (currentHealth <= 0.0f)
Die();
}
private void Die()
{
Instantiate(deathChunkParticle, transform.position, deathChunkParticle.transform.rotation);
Instantiate(deathBloodParticle, transform.position, deathBloodParticle.transform.rotation);
// This is for respawn, in GameManager Class
GM.Respawn();
Destroy(gameObject);
}
```
### GameManager<a id="GM"/>
GameManager control all game objs and play.<br>This time, only check respawn, but add more components later.<br>Respawn also has `check()` and activate function.<br>Activate function is called in PlayerState class.
```csharp=
[SerializeField]
private Transform respawnPoint;
[SerializeField]
private GameObject player;
[SerializeField]
private float respawnTime;
private float respawnTimeStart;
private bool respawn;
// This is unity package, Some Action camera
private CinemachineVirtualCamera CVC;
private void Start()
{
CVC = GameObject.Find("Player Camera").GetComponent<CinemachineVirtualCamera>();
}
public void Respawn()
{
respawnTimeStart = Time.time;
respawn = true;
}
// This is called in Update()
private void CheckRespawn()
{
if (Time.time >= respawnTimeStart + respawnTime && respawn)
{
var playerTemp = Instantiate(player, respawnPoint);
CVC.m_Follow = playerTemp.transform;
respawn = false;
}
}
```