응용프로그램/유니티(Unity)

Unity - 적 공격으로 Player에게 데미지 입히기

zelkova 2016. 11. 17. 15:52

<목차로 돌아가기>

 

  적 공격으로 Player 데미지 입히기

출처 : Sebastian Lague

 

IDeamageable.cs

  1. using UnityEngine;
  2.  
  3. public interface IDamageable
  4. {
  5.     void TakeHit(float damage, RaycastHit hit);
  6.  
  7.     void TakeDamage(float damage);
  8. }

 

 

LivingEntity.cs

 

 

  1. using UnityEngine;
  2.  using System.Collections;
  3.  
  4.  public class LivingEntity : MonoBehaviour, IDamageable {
  5.  
  6.     public float startingHealth;
  7.     protected float health;
  8.     protected bool dead;
  9.  
  10.     public event System.Action OnDeath;
  11.  
  12.     protected virtual void Start()
  13.     {
  14.         health = startingHealth;
  15.     }
  16.  
  17.     public void TakeHit(float damage, RaycastHit hit)
  18.     {
  19.         //Do some stuff here with hit
  20.         TakeDamage(damage);
  21.     }
  22.  
  23.     public void TakeDamage(float damage)
  24.     {
  25.         health -= damage;
  26.  
  27.         if (health <= 0 && !dead)
  28.         {
  29.             Die();
  30.         }
  31.     }
  32.  
  33.     protected void Die()
  34.     {
  35.         dead = true;
  36.         if (OnDeath != null)
  37.         {
  38.             OnDeath();
  39.         }
  40.         GameObject.Destroy(gameObject);
  41.     }
  42.  
  43.  }

 

 

 

Enemy.cs

 

 

  1. using UnityEngine;
  2.  using System.Collections;
  3.  
  4.  [RequireComponent (typeof (NavMeshAgent))]
  5.  public class Enemy : LivingEntity
  6.  {
  7.     public enum State;
  8.     State currentState;
  9.  
  10.     NavMeshAgent pathfinder;
  11.     Transform playertargeting;
  12.     LivingEntity targetEntity;
  13.     Material skinMaterial;
  14.     
  15.  
  16.     Color originalColor;
  17.  
  18.     float attackDistanceThreshold = 1.5f;
  19.     float timeBetweenAttacks = 1;
  20.     float damage=1;
  21.  
  22.     float nextAttackTime;
  23.     float myCollisionRadius;
  24.     float targetCollisionRadius;
  25.  
  26.     bool hasTarget;
  27.  
  28. protected override void Start () {
  29.         base.Start();
  30.         pathfinder = GetComponent<NavMeshAgent>();
  31.         skinMaterial = GetComponent<Renderer>().material;
  32.         originalColor = skinMaterial.color;
  33.  
  34.         if (GameObject.FindGameObjectsWithTag("Player") != null)
  35.         {      
  36.             currentState = State.Chasing;
  37.             hasTarget = true;
  38.  
  39.             playertargeting = GameObject.FindWithTag("Player").GetComponent<Transform>();
  40.             targetEntity = playertargeting.GetComponent<LivingEntity>();
  41.             targetEntity.OnDeath += OnTargetDeath;
  42.  
  43.             StartCoroutine(UpdatePath());
  44.  
  45.             myCollisionRadius = GetComponent<CapsuleCollider>().radius;
  46.             targetCollisionRadius = playertargeting.GetComponent
  47.                                            <CapsuleCollider>().radius;
  48.         }
  49.     }
  50.     void OnTargetDeath()
  51.     {
  52.         hasTarget = false;
  53.         currentState = State.Idle;
  54.     }
  55.  
  56. void Update () {
  57.         if (hasTarget)
  58.         {
  59.             if (Time.time > nextAttackTime)
  60.             {
  61.                 float sqrDstTotarget = (playertargeting.position - 
  62.                                               transform.position).sqrMagnitude;
  63.                 if (sqrDstTotarget < Mathf.Pow(attackDistanceThreshold   
  64.                                          +myCollisionRadius+targetCollisionRadius, 2))
  65.                 {
  66.                     nextAttackTime = Time.time + timeBetweenAttacks;
  67.                     StartCoroutine(Attack());
  68.                 }
  69.             }
  70.         }
  71.     }
  72.  
  73.     IEnumerator Attack()
  74.     {
  75.         currentState = State.Attacking;
  76.         pathfinder.enabled = false;
  77.         Vector3 originalPosition = transform.position;
  78.         Vector3 dirToTarget = (playertargeting.position - 
  79.                                       transform.position).normalized;
  80.         Vector3 AttackPosition = playertargeting.position - dirToTarget *
  81.                                          (myCollisionRadius);
  82.         float attackSpeed = 3;
  83.         float percent = 0;
  84.  
  85.         skinMaterial.color = Color.red;
  86.         bool hasAppliedDamage = false;
  87.  
  88.         while (percent <= 1)
  89.         {
  90.             if (percent >= .5f && !hasAppliedDamage)
  91.             {
  92.                 hasAppliedDamage = true;
  93.                 targetEntity.TakeDamage(damage);
  94.             }
  95.             percent += Time.deltaTime * attackSpeed;
  96.  
  97.             float interpolation = (-Mathf.Pow(percent, 2) + percent) * 4;
  98.             transform.position = Vector3.Lerp(originalPosition,                         
  99.                                        AttackPosition, interpolation);
  100.  
  101.             yield return null;
  102.  
  103.         }
  104.         skinMaterial.color = originalColor;
  105.         currentState = State.Chasing;
  106.         pathfinder.enabled = true;
  107.     }
  108.  
  109.     IEnumerator UpdatePath()
  110.     {
  111.         float refreshRate = 0.25f;
  112.         
  113.         while (hasTarget)
  114.         {
  115.             if (currentState == State.Chasing)
  116.             {
  117.                 Vector3 dirToTarget = (playertargeting.position - 
  118.                                                transform.position).normalized;
  119.                 Vector3 targetPosition = playertargeting.position - dirToTarget * 
  120.                                                 (myCollisionRadius + 
  121.                                                 targetCollisionRadius+ 
  122.                                                 attackDistanceThreshold/2);
  123.                 if (!dead)
  124.                 {
  125.                     pathfinder.SetDestination(targetPosition);
  126.                 }
  127.             }
  128.             yield return new WaitForSeconds(refreshRate);   
  129.         }
  130.     }
  131. }

 

 

 

 

 

 

반응형