2016-06-27 7 views
0

ねえ!私は問題を抱えています。私は基本的な戦闘システムを作りました。敵を殺すまではすべて動作しますが、それは意図どおりに破壊されますが、別の敵を選択するまで攻撃タイマーはカウントを停止します。また、攻撃スクリプトのターゲットフィールドが開始時に空であるため、最初の敵を選択するまではエラーが発生します。敵を殺した後に攻撃タイマーが止まる(攻撃スクリプトがゆるいターゲットの場合)

スクリプト:

攻撃スクリプト:

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スクリプト:Scはターゲット

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

}

RIPT:

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(); 
    } 
} 

}

私はそれらの問題を引き起こす可能性のあるすべてのスクリプトがあり、誰も私を助けることができると思いますか?私は絶望的です。 :(

答えて

0

あなたの攻撃スクリプトの更新方法の初めに、このようなtargetオブジェクトのnullチェックを追加します。私はあなたのタイマーの問題が何であるかを知っていると思う

if(target == null) 
{ 
    return; 
} 
0

もし私が基本攻撃のクラスStart Methodで、タイマを開始することを正しく理解しています。

その後、タイマーは0になり、攻撃することができます。

私はその問題を、あなたの敵を破壊したら、それ以外は何も起こらないと思います。

つまり、実際には敵が死んだらタイマーをリセットしません。それは、あなたが別の敵を選択したときにのみ再び働く理由です。

この場合、TargetingクラスからBasicAttackクラスが呼び出され、Startメソッドが再度呼び出されます。

私はそれが助けてくれることを願っています。

よろしくお願いいたします。

関連する問題