当一个物体到达离它开始的地方一定距离时,我将如何摧毁它?



我目前有一个敌人(对象(和一个火球(对象(。 当敌人检测到目标时,它会向该目标发射火球。我遇到的问题是,如果火球错过了目标,它将永远继续移动,并阻止敌人发射另一个火球。如果火球击中目标,则没有这个问题。

我尝试获取敌人的矢量位置和火球的矢量位置,然后检查两者之间的距离是否大于触发它摧毁火球实例的阈值。但是,它一直告诉我它缺少对敌方对象的引用。我希望这段代码足以解决我的问题。

敌人脚本:

private Vector3 E_pos
//this method finds the vector3 position of the enemy
public Vector3 getEnemyPos()
{
e_Pos = transform.position;
return e_Pos;
}

火球脚本:

private  Vector3 f_Pos;
private Vector3 e_Pos;
WanderingAI w = new WanderingAI();
void Update()
{
e_Pos = w.getEnemyPos();
transform.Translate(0, 0, speed * Time.deltaTime);
if(totalDistance() > 10f || totalDistance() < -10f)
{
Debug.Log("Distance from Enemy: " + totalDistance());
Destroy(this.gameObject);
}
}
//this method finds the current vector3 Coordinates for the fireball instance 
public Vector3 getCurrentFireballPos()
{    
f_Pos = transform.position;
return f_Pos;
}
//This method finds the total distance between the fireball instance and the enemy
public float totalDistance()
{
float data = 0;
data = Vector3.Distance(getCurrentFireballPos(), w.getEnemyPos());
return data;
}

好吧,您的主要问题似乎不是计算,而是缺少参考。到目前为止,您的代码还不足以说明为什么它不起作用,但我会尝试:

如果WanderingAIMonoBehaviour组件(似乎是这种情况,因为您正在尝试访问transform

WanderingAI w = new WanderingAI();

绝对不行!此组件应附加到GameObject,并在实例化时设置,或者必须在运行时动态找到。

我猜缺少的引用异常不是针对w

而是针对行
transform.position

getEnemyPos.

我们看不到您在何处或如何实例化此功能。因此,举个例子,你可以(见下面的更好方式(简单地将实例化的火球交给谁发射它的Transform参考:

在火球中有一个领域

public Transform enemyTransform;

然后将其与实例化一起设置

public Fireball fireballPrefab;
...
var fireball = Instantiate(fireballPrefab, transform.position, transform.rotation);
fireball.enemyTransform = transform;

您的获取位置方法是多余的。transform.position对于任何GameObjectComponnet(MonoBehaviour(参考都是公开的,因此一旦您有对敌人或火球(物体或组件无关紧要(的引用,您就可以简单地直接访问例如

enemy.transform.position

只是一般说明:c# 中的方法名称应以大写字母开头。将每个值存储在局部变量或类字段中也是非常不必要的。


然而

与其使用负责任的敌人变身,不如简单地将火球存储在自己的起始位置。那你就不用再关心敌人了。此外,如果敌人同时移动Update,考虑到敌人的位置可能无法正常工作;)

由于您只是向z方向移动,因此您可以简单地检查到目前为止的行驶距离,甚至不需要参考敌人

// Adjust in the Inspector
[SerializeField] private float range = 10;
// Stores the initial position
private Vector3 startPosition;
private void Start()
{
// Store position before starting to move
startPosition = transform.position;
}
private void Update ()
{
transform.Translate(Vector3.forward * speed * Time.deltaTime);
// Directly compare to the initial position
// Without having to care who fired this ball
if(Mathf.Abs(startPosition.z - transform.position.z) >= range)
{
Destroy(gameObject);
}
// Or simply
if(Vector3.Distance(startPosition, transform.position) >= range)
{
Destroy(gameObject);
}
}

目前你也只在向全球Z方向移动..这真的是你想做的吗?否则,我宁愿在实例化球时设置正确的旋转并沿其本地前进方向移动,例如

transform.Translate(transform.forward * speed * Time.deltaTime);

此问题最重要的部分是,您应该对火球使用预制件,并在需要时创建火球预制件的新实例。 然后我会从这 2 个(或同时选择两者(:

  1. 创建"假想"边界:这是最简单的边界。例如,如果你的火球在y轴上的位置达到50,它将被摧毁。您可以为所有维度创建这些规则。

  2. 与起始位置
  3. 的距离:您基本上要存储对象的起始位置。然后在更新方法中,只需以某种方式计算与它的当前距离,如下所示:

    var f_pos = transform.position;
    double distance = Mathf.Abs(f_pos.x - startingPos.x) + Mathf.Abs(f_pos.z - startingPos.z) + Mathf.Abs(f_pos.y - startingPos.y);
    

抱歉,如果代码不适用于这些参数,我没有对其进行测试,但我希望您明白这个想法。

最新更新