攻击只针对敌人Unity

时间:2016-02-10 15:27:46

标签: c# unity3d targeting

我有一个用于控制目标敌人的脚本和另一个控制玩家攻击的脚本,目标脚本似乎可以自行正常工作直到第一个目标被杀死,所以当我点击Tab时它会按距离顺序瞄准我的敌人但是当我的第一个目标死亡时,它无法定位另一个目标,我收到了消息:

  

MissingReferenceException:类型'变换'一直都是   被摧毁但你还在试图访问它。你的脚本应该   要么检查它是否为空,否则你不应该销毁该对象。

此外,我无法攻击除第一位玩家以外的任何东西,无论是否有针对性。我尝试切换我的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!"); 
    }
}
}

基本上我要做的就是让两个脚本相互配合使用,这样当敌人成为目标时,它只会从目标敌人中扣除伤害,当敌人被杀死时,它会从列表中移除&#39;目标&#39;

1 个答案:

答案 0 :(得分:2)

我完全同意Joe的诊断,这里的关键问题是,在对任何成员的相关对象调用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)); }); } 个对象的所有空引用,方法是将其调整为以下内容:

public string firstValue {get; set;}
public string secondValue {get; set;}

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

(虽然这是对你的代码进行的最小改动,但我仍然支持让管理员跟踪敌人的想法,就像乔建议的那样。从长远来看,如果能让你头疼,你的项目不断发展。)