我目前有一个敌人(对象(和一个火球(对象(。 当敌人检测到目标时,它会向该目标发射火球。我遇到的问题是,如果火球错过了目标,它将永远继续移动,并阻止敌人发射另一个火球。如果火球击中目标,则没有这个问题。
我尝试获取敌人的矢量位置和火球的矢量位置,然后检查两者之间的距离是否大于触发它摧毁火球实例的阈值。但是,它一直告诉我它缺少对敌方对象的引用。我希望这段代码足以解决我的问题。
敌人脚本:
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;
}
好吧,您的主要问题似乎不是计算,而是缺少参考。到目前为止,您的代码还不足以说明为什么它不起作用,但我会尝试:
如果WanderingAI
是MonoBehaviour
组件(似乎是这种情况,因为您正在尝试访问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
对于任何GameObject
和Componnet
(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 个(或同时选择两者(:
-
创建"假想"边界:这是最简单的边界。例如,如果你的火球在y轴上的位置达到50,它将被摧毁。您可以为所有维度创建这些规则。
与起始位置 的距离:您基本上要存储对象的起始位置。然后在更新方法中,只需以某种方式计算与它的当前距离,如下所示:
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);
抱歉,如果代码不适用于这些参数,我没有对其进行测试,但我希望您明白这个想法。