---
# System prepended metadata

title: Unity Platform 11 Enermy's Touch Attack
tags: [platform]

---

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