只攻击目标敌人 Unity

Attack only targeted enemies Unity

我有一个用于控制目标敌人的脚本,另一个用于控制玩家攻击,目标脚本似乎可以自己正常工作,直到第一个目标被杀死,所以当我单击 Tab 时,它会瞄准我的敌人距离顺序但是当我的第一个目标死亡时它不能瞄准另一个并且我收到消息:

MissingReferenceException: The object of type 'Transform' has been destroyed but you are still trying to access it. Your script should either check if it is null or you should not destroy the object.

此外,我无法攻击除了第一个玩家之外的任何东西,无论它是否被瞄准。我尝试切换我的 playerattacks 以便它可以像我的目标脚本一样使用列表但是我得到了所有相同的错误。

我的定位脚本是:

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 脚本目前是:

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

基本上我想要做的是让两个脚本相互配合,这样当一个敌人成为目标时,它只会从目标敌人身上扣除伤害,当一个敌人被杀死时它会从列表中移除'targets'

我完全同意 Joe 的诊断,这里的关键问题是您在对其任何成员的关联对象调用 Destroy() 后没有更新您的 List<Transform> targets。不过,我将提出一个稍微不同的解决方案。

当您尝试使用以下方法按目标与玩家的距离对目标进行排序时:

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 不存在).一个简单的解决方法是在尝试对 targets 进行排序之前删除对 Transform 对象的所有空引用,方法是将其调整为以下内容:

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

希望对您有所帮助!如果您有任何问题,请告诉我。

(尽管这是对您的代码所做的最小更改,但我仍然支持拥有一个跟踪敌人的管理器的想法,就像 Joe 所建议的那样。它会在长期 运行,如果您的项目不断增长。)