2016-02-10 3 views
0

У меня есть скрипт, который используется для управления целевыми противниками, а другой - для контроля над атаками игроков. Сценарий таргетинга, похоже, отлично работает, пока не будет уничтожена первая цель, поэтому, когда я нажимаю Tab, мои враги в дистанционном порядке, но когда моя первая цель умирает, он не может предназначаться другой, и я получаю сообщение:Атака только целевых противников Unity

MissingReferenceException: объект типа «Transform» был разрушен, но вы все еще пытаетесь получить к нему доступ. Ваш скрипт должен либо проверить, является ли он нулевым, либо вы не должны уничтожать объект.

Также я не могу атаковать ничего, кроме первого игрока, будь то цель или нет. Я попытался переключить свои игровые атаки, поэтому он работал со списком, как и мой скрипт таргетинга, но я получаю все те же ошибки.

Мой ориентируется сценарий:

public class Targetting : MonoBehaviour { 

public List<Transform> targets; 
public Transform selectedTarget; 
public string targetTag = "Enemy"; 
private Transform myTransform; 

//Use this for initialization 
void Start() { 
    targets = new List<Transform>(); 
    selectedTarget = null; 
    myTransform = transform;   
    AddAllEnemies(); 
} 

public void AddAllEnemies() { 
    GameObject[] go = GameObject.FindGameObjectsWithTag(targetTag);  
    foreach(GameObject enemy in go) { 
     AddTarget(enemy.transform); 
    } 
} 

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

private void SortTargetsByDistance() { 
    targets.Sort(delegate(Transform t1, Transform t2) { 
     return (Vector3.Distance(t1.position, myTransform.position).CompareTo) 
      (Vector3.Distance(t2.position, myTransform.position)); 
    }); 
} 

private void TargetEnemy() { 
    if(selectedTarget == null) { 
     SortTargetsByDistance(); 
     selectedTarget = targets[0]; 
    } else { 
     int index = targets.IndexOf(selectedTarget);  
     if (index < targets.Count -1) { 
      index++; 
     } else { 
      index = 0;  
     } 

     selectedTarget = targets[index]; 
    } 
} 

//Update is called once per frame 
void Update() 
{ 
    if(Input.GetKeyDown(KeyCode.Tab)) 
    { 
     TargetEnemy(); 
    } 
} 
} 

И мой PlayerAttack Script в настоящее время:

public class PlayerAttack : MonoBehaviour { 

public enemyHealth eHealth; 
public GameObject enemy; 
private float MHCD; // MeleeHit CD 

private float hitChance; 

// Use this for initialization 
void Start() { 

} 

void Update() { 
    hitChance = Random.Range (1, 100); 

    if (Input.GetKeyDown (KeyCode.Alpha1) && Time.time - MHCD > 1) { 
     if (hitChance > 0 && hitChance < 90) { 
      Attack1(); 
      MHCD = Time.time; 
     } 
    } 
} 

void Attack1() { 
    float distance = Vector3.Distance (enemy.transform.position, transform.position); 

    if (distance < 4) { 
     eHealth.SendMessage ("MeleeHit"); 
    } else { 
     Debug.LogWarning ("You are too far away!"); 
    } 
} 
} 

В основном то, что я ищу, чтобы сделать это, чтобы сделать оба скрипта работать с Афоризмом так, когда враг нацеленный на то, что он только вычитает урон от целевого врага, а когда убивают врага, он удаляется из списка «целей»

ответ

2

Я полностью согласен с диагнозом Джо, что Ключевой проблемой здесь является то, что вы не обновляете свой List<Transform> targets после вызова Destroy() на любые связанные с ним объекты. Тем не менее, я собираюсь предложить немного другое решение проблемы.

При попытке отсортировать цели по расстоянию от игрока со следующим методом:

private void SortTargetsByDistance() { 
    targets.Sort(delegate(Transform t1, Transform t2) { 
     return (Vector3.Distance(t1.position, myTransform.position).CompareTo) 
      (Vector3.Distance(t2.position, myTransform.position)); 
    }); 
} 

Вы пытаетесь получить доступ к Transform на каждой потенциальной мишенью для сравнения, но не принимая во учтите, что цель может быть уже уничтожена (что делает ее Transform несуществующей). Простое исправление для этого, чтобы удалить все пустые ссылки на Transform объектов, прежде чем пытаться разобраться targets, сместив его к следующему:

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

Надеется, что это помогает! Дайте знать, если у вас появятся вопросы.

(Хотя это самое минимальное изменение в вашем коде, я по-прежнему поддерживаю идею о том, что менеджер отслеживает врагов, как то, что предложил Джо.Это в конечном итоге избавит вас от некоторых головных болей, если ваш проект продолжает расти.)

+0

Perfect! Большое спасибо! – Amy

+1

@cantdothis Отлично, я рад, что смог помочь! Не забывайте, что если ответ решает вашу проблему, вы должны принять его, нажав галочку рядом с ответом. (Вероятно, вы должны сделать это и с некоторыми из своих более старых вопросов!) – Serlite

+0

Просто еще один вопрос, что на самом деле делает цель «target => target»? – Amy

Смежные вопросы