|
IDeamageable.cs
- using UnityEngine;
- public interface IDamageable
- {
- void TakeHit(float damage, RaycastHit hit);
- void TakeDamage(float damage);
- }
LivingEntity.cs
- using UnityEngine;
- using System.Collections;
- public class LivingEntity : MonoBehaviour, IDamageable {
- public float startingHealth;
- protected float health;
- protected bool dead;
- public event System.Action OnDeath;
- protected virtual void Start()
- {
- health = startingHealth;
- }
- public void TakeHit(float damage, RaycastHit hit)
- {
- //Do some stuff here with hit
- TakeDamage(damage);
- }
- public void TakeDamage(float damage)
- {
- health -= damage;
- if (health <= 0 && !dead)
- {
- Die();
- }
- }
- protected void Die()
- {
- dead = true;
- if (OnDeath != null)
- {
- OnDeath();
- }
- GameObject.Destroy(gameObject);
- }
- }
Enemy.cs
- using UnityEngine;
- using System.Collections;
- [RequireComponent (typeof (NavMeshAgent))]
- public class Enemy : LivingEntity
- {
- public enum State;
- State currentState;
- NavMeshAgent pathfinder;
- Transform playertargeting;
- LivingEntity targetEntity;
- Material skinMaterial;
- Color originalColor;
- float attackDistanceThreshold = 1.5f;
- float timeBetweenAttacks = 1;
- float damage=1;
- float nextAttackTime;
- float myCollisionRadius;
- float targetCollisionRadius;
- bool hasTarget;
- protected override void Start () {
- base.Start();
- pathfinder = GetComponent<NavMeshAgent>();
- skinMaterial = GetComponent<Renderer>().material;
- originalColor = skinMaterial.color;
- if (GameObject.FindGameObjectsWithTag("Player") != null)
- {
- currentState = State.Chasing;
- hasTarget = true;
- playertargeting = GameObject.FindWithTag("Player").GetComponent<Transform>();
- targetEntity = playertargeting.GetComponent<LivingEntity>();
- targetEntity.OnDeath += OnTargetDeath;
- StartCoroutine(UpdatePath());
- myCollisionRadius = GetComponent<CapsuleCollider>().radius;
- targetCollisionRadius = playertargeting.GetComponent
- <CapsuleCollider>().radius;
- }
- }
- void OnTargetDeath()
- {
- hasTarget = false;
- currentState = State.Idle;
- }
- void Update () {
- if (hasTarget)
- {
- if (Time.time > nextAttackTime)
- {
- float sqrDstTotarget = (playertargeting.position -
- transform.position).sqrMagnitude;
- if (sqrDstTotarget < Mathf.Pow(attackDistanceThreshold
- +myCollisionRadius+targetCollisionRadius, 2))
- {
- nextAttackTime = Time.time + timeBetweenAttacks;
- StartCoroutine(Attack());
- }
- }
- }
- }
- IEnumerator Attack()
- {
- currentState = State.Attacking;
- pathfinder.enabled = false;
- Vector3 originalPosition = transform.position;
- Vector3 dirToTarget = (playertargeting.position -
- transform.position).normalized;
- Vector3 AttackPosition = playertargeting.position - dirToTarget *
- (myCollisionRadius);
- float attackSpeed = 3;
- float percent = 0;
- skinMaterial.color = Color.red;
- bool hasAppliedDamage = false;
- while (percent <= 1)
- {
- if (percent >= .5f && !hasAppliedDamage)
- {
- hasAppliedDamage = true;
- targetEntity.TakeDamage(damage);
- }
- percent += Time.deltaTime * attackSpeed;
- float interpolation = (-Mathf.Pow(percent, 2) + percent) * 4;
- transform.position = Vector3.Lerp(originalPosition,
- AttackPosition, interpolation);
- yield return null;
- }
- skinMaterial.color = originalColor;
- currentState = State.Chasing;
- pathfinder.enabled = true;
- }
- IEnumerator UpdatePath()
- {
- float refreshRate = 0.25f;
- while (hasTarget)
- {
- if (currentState == State.Chasing)
- {
- Vector3 dirToTarget = (playertargeting.position -
- transform.position).normalized;
- Vector3 targetPosition = playertargeting.position - dirToTarget *
- (myCollisionRadius +
- targetCollisionRadius+
- attackDistanceThreshold/2);
- if (!dead)
- {
- pathfinder.SetDestination(targetPosition);
- }
- }
- yield return new WaitForSeconds(refreshRate);
- }
- }
- }
반응형
'응용프로그램 > 유니티(Unity)' 카테고리의 다른 글
Unity - Editor 개념 및 사용 (0) | 2016.11.19 |
---|---|
Unity - 근접했을때도 발사체 동작하게 하기 (0) | 2016.11.18 |
unity - 대칭함수을 활용한 공격 (0) | 2016.11.16 |
Unity - 스폰 시스템 만들기 (0) | 2016.11.14 |
Unity - 데미지 시스템 (0) | 2016.11.14 |