【问题标题】:Attack only targeted enemies Unity只攻击目标敌人团结
【发布时间】:2016-02-10 15:27:46
【问题描述】:

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

MissingReferenceException:“Transform”类型的对象已 已销毁,但您仍在尝试访问它。你的脚本应该 检查它是否为空,或者您不应该销毁该对象。

此外,我无法攻击除了第一个玩家之外的任何东西,无论它是否被指定为目标。我尝试切换我的 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!"); 
    }
}
}

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

【问题讨论】:

    标签: c# unity3d targeting


    【解决方案1】:

    我完全同意 Joe 的诊断,即这里的关键问题是您在调用 Destroy() 后没有更新您的 List&lt;Transform&gt; 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 建议的那样让一个经理跟踪敌人的想法。从长远来看,如果您的项目不断增长。)

    【讨论】:

    • 完美!非常感谢!
    • @cantdothis 太好了,我很高兴能帮上忙!不要忘记,如果某个答案解决了您的问题,您应该通过单击答案旁边的复选标记来接受它。 (您可能也应该对一些较早的问题这样做!)
    • 再问一个问题,“target => target”到底是做什么的?
    • @cantdothis 括号中的那位是lambda expression=&gt; 具体是 lambda 运算符 - 左侧的 target 是输入参数,右侧的 target == null 是给出结果的表达式。您基本上可以将target =&gt; target == null 读作“对于提供的列表中的每个项目target,如果它是null,则返回target”。因此,当它在 RemoveAll() 中时,它将删除列表中所有为空的元素。
    • 优秀的答案!!对于任何在谷歌上搜索其他有趣的成语的人,包括hits = hits.OrderBy(x =&gt; Vector2.Distance(this.transform.position,x.transform.position)).ToList();
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-01
    • 2017-06-29
    • 2015-01-19
    • 2019-11-29
    • 1970-01-01
    相关资源
    最近更新 更多