杀死敌人后攻击计时器停止(当攻击脚本松散目标时)(Unity)

时间:2016-06-27 14:51:24

标签: c# unity3d countdowntimer

嘿伙计们!我有一个问题,我的攻击脚本有冷却时间和内容,我已经创建了基本的战斗系统,一切正常,直到我杀死敌人,它按照预期摧毁它然后我的攻击计时器停止计数,直到我选择另一个敌人此外,我一直收到错误,直到我选择第一个敌人,因为攻击脚本中的目标字段在开始时为空。

脚本:

攻击脚本:

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class BasicAttack : MonoBehaviour {

public GameObject target; //target to attack

public int damage;

public float range = 4;
public float attackTimer;
public float cooldown = 2.0f;

public GameObject damageNumber;
public GameObject cooldownImage;
public Text cooldownText;

Targeting t;
UserInterface UI;

void Start () {

    cooldownImage.SetActive(false);

    attackTimer = 0;

    t = FindObjectOfType<Targeting>();
    UI = FindObjectOfType<UserInterface>();
}

void Update () {

    float distance = Vector3.Distance(target.transform.position, transform.position); //calculating distance

    cooldownText.text = attackTimer.ToString("F0");

    if (attackTimer > 0) {
        attackTimer -= Time.deltaTime;
    }
    if (attackTimer <= 0) {
        attackTimer = 0;
    }
    if (Input.GetKeyUp("1")) { //attack key
        if (attackTimer == 0 && distance < range) {
            Attack();
            attackTimer = cooldown;
            //damage numbers
            var clone = (GameObject)Instantiate(damageNumber, t.selectedTarget.GetComponent<EnemyAI>().hitPoint.position, t.myTransform.rotation);
            clone.GetComponent<DamageNumbers>().damageNumber = damage;
        }
        else {
            Debug.Log("Target is out of range!");
        }
    }
    else {
        cooldownImage.SetActive(true);
    }

    if (attackTimer == 0) {
        cooldownImage.SetActive(false);
    }
}

public void Attack() {

        float distance = Vector3.Distance(target.transform.position, transform.position); //calculating distance

        Vector3 dir = (target.transform.position - transform.position).normalized; //calculating direction
        float direction = Vector3.Dot(dir, transform.forward); //calculating direction

        if (distance < range) { //making player not be able to attack if too far

            if (direction > 0) { //making player not be able to attack if target not in front of him
                EnemyHealth eh = (EnemyHealth)target.GetComponent("EnemyHealth"); //getting enemy health
                t.selectedTarget.GetComponent<EnemyHealth>().TakeDamage(-damage); //adjusting enemy health

                UI.infoText.text = "";
            }
            else {
                Debug.Log("Target needs to be in front of you!");
            }
            UI.infoText.text = "";
        }
        else {
            Debug.Log("Target is out of range!");
        }
} //attack
}

EnemyHealth Script:

using UnityEngine;
using System.Collections;

public class EnemyHealth : MonoBehaviour {

public float maxHealth = 100;
public float curHealth = 100;

CombatTargetUI ct;

void Start () {
    ct = FindObjectOfType<CombatTargetUI>();
}

void Update () {
    TakeDamage(0);
}

public void TakeDamage (int ad) {
    curHealth += ad;

    if (curHealth <= 0) {
        curHealth = 0;
        /*ct.HideUI();*/
        Die();
    }
    if (curHealth >= maxHealth) {
        curHealth = maxHealth;
    }
    if (maxHealth <= 1) {
        maxHealth = 1;
    }
}

void Die () {

    StartCoroutine(TimeToDestroy());
}

IEnumerator TimeToDestroy () {
    yield return new WaitForSeconds(0.5f);
    ct.HideUI();
    Destroy(gameObject);
}

}

定位脚本:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Targeting : MonoBehaviour {

public List<Transform> targets;
public Transform selectedTarget;

public Transform myTransform;

CombatTargetUI ct;

void Start () {
    targets = new List<Transform>();
    selectedTarget = null;
    myTransform = transform;

    ct = FindObjectOfType<CombatTargetUI>();

    AddAllEnemies();
}

public void AddAllEnemies () {

    GameObject[] go = GameObject.FindGameObjectsWithTag("Enemy");

    foreach (GameObject enemy in go) {
        AddTarget(enemy.transform);
    }
}

public void AddTarget (Transform enemy) {
    targets.Add(enemy);
}

void SortTargetsByDistance () {

    targets.RemoveAll(target => target == null);
    targets.Sort(delegate(Transform t1, Transform t2) {
        return Vector3.Distance(t1.position, myTransform.position).CompareTo(Vector3.Distance(t2.position, myTransform.position));
            });
}

void TargetEnemy () {

    if (selectedTarget == null) {
        SortTargetsByDistance();
        selectedTarget = targets[0];
    }
    else {
        int index = targets.IndexOf(selectedTarget);

        if (index < targets.Count - 1) {
            index++;
        }
        else {
            index = 0;
        }
        DeselectTarget();
        selectedTarget = targets[index];
    }
    SelectTarget();
}

void SelectTarget () {

    ct.ShowUI();

    selectedTarget.GetComponent<Renderer>().material.color = Color.red;

    BasicAttack ba = (BasicAttack)GetComponent("BasicAttack");
    ba.target = selectedTarget.gameObject;
}

public void DeselectTarget () {
    if (selectedTarget != null) {
        selectedTarget.GetComponent<Renderer>().material.color = Color.white;
    }

    selectedTarget = null;
}

void Update () {

    if (Input.GetKeyDown(KeyCode.Tab)) {
        TargetEnemy();
    }
}

}

我认为这些都是可能导致问题的脚本,任何人都可以帮助我吗?我很绝望。 :(

2 个答案:

答案 0 :(得分:0)

在攻击脚本的Update方法开始时,添加null target对象检查,如下所示:

if(target == null)
{
    return;
}

答案 1 :(得分:0)

我想我知道你的计时器问题是什么。

如果我理解正确,在Basic Attack类 - Start Method中,你可以使用计时器。

然后,计时器下降到0,然后你可以攻击。

我认为问题在于,一旦你摧毁了敌人,就没有其他事情发生了。

我的意思是,一旦敌人死亡,你实际上不会重置计时器。这就是为什么当你选择另一个敌人时它才会再次起作用。

当发生这种情况时,将从Targeting类调用BasicAttack类,因此再次调用Start方法。

我希望它有所帮助。

问候!