unity開發遊戲邏輯:敵人攻擊距離

/***
 * 
 * 把所有存活的敵人放入一個GameObject集合
 * 在一定範圍內,遍歷集合找出距離最近的敵人
 * 攻擊,朝向敵人,對攻擊範圍內敵人進行傷害處理
 * 
 */
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AttrckCtrl : MonoBehaviour
{
    private List<GameObject> _EnemyList;        //當前存活的敵人集合
    private float _MinAttackDis = 1;            //最近攻擊距離
    private float _MaxAttackDis = 5;           //最遠攻擊距離
    private GameObject _NearestEnemy;           //距離最近的敵人

    void Start()
    {
        _EnemyList = new List<GameObject>();
        StartCoroutine("EnemyDetector");                    //協程開啓時使用名字,方便關閉
    }

    /// <summary>開啓敵人距離檢測/// </summary>
    IEnumerator EnemyDetector()
    {
        while (true)
        {
            yield return 0;
            FindAliveEnemy();
            FindNearestEnemy();
        }
    }

    /// <summary>更新存活的敵人/// </summary>
    private void FindAliveEnemy()
    {
        _EnemyList.Clear();
        GameObject[] _Enemys = GameObject.FindGameObjectsWithTag("Enemy");
        for (int i = 0; i < _Enemys.Length; i++)
        {
            if (_Enemys[i].activeInHierarchy)        //敵人處於存活狀態
            {
                _EnemyList.Add(_Enemys[i]);
            }
        }
    }

    /// <summary>判斷距離最近的存活敵人/// </summary>
    private void FindNearestEnemy()
    {
        if (_EnemyList == null || _EnemyList.Count <= 0) return;

        _NearestEnemy = null;
        float _CurNearestDis = _MaxAttackDis;
        for (int i = 0; i < _EnemyList.Count; i++)
        {
            float _TempDis = CalculationOfDistance(_EnemyList[i].transform.position);
            if (_CurNearestDis > _TempDis)
            {
                _CurNearestDis = _TempDis;
                _NearestEnemy = _EnemyList[i];
            }
        }

        if (_NearestEnemy != null)
        {
            if (InAttackRange(_CurNearestDis))
            {
                //距離最近的敵人在攻擊範圍內
                Debug.Log("距離最近的敵人 在攻擊範圍內! 參數: _NearestEnemy = " + _NearestEnemy.name);
            }
        }
    }

    /// <summary>攻擊 血值結算/// </summary>
    private void AttackDamageCalculation(GameObject _AttackEnemy)
    {
        if (_AttackEnemy == null) return;

        float _DisOfEnemyAndMe = CalculationOfDistance(_AttackEnemy.transform.position);

        Vector3 _EAndMNormalized = (_AttackEnemy.transform.position - transform.position).normalized;
        float _EAndMDot = Vector3.Dot(transform.forward, _EAndMNormalized);             //判斷敵人方位 >0敵人在前方

        if (InAttackRange(_DisOfEnemyAndMe))
        {
            if (_EAndMDot > 0)
            {
                Debug.Log("直接正面發動攻擊! 參數: 被攻擊的敵人 = " + _AttackEnemy.name);
            }
            else
            {
                Quaternion _Dir = Quaternion.LookRotation(new Vector3(_AttackEnemy.transform.position.x,0, _AttackEnemy.transform.position.z)
                    -new Vector3(transform.position.x, 0, transform.position.z));
                transform.rotation = _Dir;
                Debug.Log("轉向發動攻擊! 參數: 被攻擊的敵人 = " + _AttackEnemy.name);
            }
        }
    }

    /// <summary>
    /// 計算與敵人的距離
    /// </summary>
    /// <param name="v">敵人位置</param>
    /// <returns>距離</returns>
    private float CalculationOfDistance(Vector3 v)
    {
        float _Dis = Vector3.Distance(transform.position, v);
        return _Dis;
    }

    /// <summary>敵人是否攻擊範圍內/// </summary>
    private bool InAttackRange(float _Dis)
    {
        if (_Dis >= _MinAttackDis && _Dis <= _MaxAttackDis)
        {
            return true;
        }
        return false;
    }

    void OnDestroy()
    {
        StopCoroutine("EnemyDetector");
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章