对象坐标未按预期更新

Object coordinates not updating as expected

我在脚本中实例化的预制件有问题。我想要做的是模拟炮弹弹丸运动背后的物理原理。我的预制件附有以下脚本:

using UnityEngine;
using System.Collections;

public class ShootPhysics : MonoBehaviour {

    // vectors & angles to be calculated
    private float fx = 0f;
    private float fy = 0f;
    private float angle;

    // forces acting upon object
    private float gravity = 9.8f;
    private float force = 1.2f;

    // new distance & vector variables
    private float dis_x = 0f;
    private float dis_y = 0f;

    // Script & CannonBall transform
    private CannonPhysics cannon_angle;

    void Start() {
        cannon_angle = GameObject.FindWithTag("Gun").GetComponent<CannonPhysics>();
        angle = cannon_angle.getAngle ();
        fx = Mathf.Round (force * Mathf.Cos(Mathf.Deg2Rad * angle));
        fy = Mathf.Round (force * Mathf.Sin(Mathf.Deg2Rad * angle));
    }

    void FixedUpdate() {
        dis_x = (float)(fx * Time.timeSinceLevelLoad);
        dis_y = (float)(fy + Time.timeSinceLevelLoad + (0.5) * (-gravity) * Time.timeSinceLevelLoad * Time.timeSinceLevelLoad);
        Debug.Log (dis_x+", "+dis_y);
        gameObject.transform.Translate (new Vector2(dis_x, dis_y));
    }

}

预制件将从以下脚本实例化:

using UnityEngine;
using System.Collections;

public class CannonPhysics : MonoBehaviour {

    // This will be our script to rotate our cannon
    private float angle = 0f;

    // cannonball object
    public Transform FirePoint;
    GameObject cannon = null;

    void Update() {
        if(Input.GetKey(KeyCode.UpArrow)) {
            angle = angle + 1;
        }
        if(Input.GetKey(KeyCode.DownArrow)) {
            angle = angle - 1;
        }

        // update cannon angle
        transform.rotation = Quaternion.Euler (new Vector3(0, 0, angle));

        if(Input.GetMouseButtonDown(0)) {
            CreateCannon();
        }
    }

    public float getAngle() {
        return angle;
    }

    private void CreateCannon() {
        cannon = Instantiate (Resources.Load("Prefabs/CannonBall"), FirePoint.position, FirePoint.rotation) as GameObject;
        Destroy (cannon, 3f);
    }

}

对象按应有的方式被实例化,对象在 3 秒后按应有的方式销毁,但是对象 xy 的位置根本没有改变,也不是什么我应该期望他们是。让我举个例子:

这些是我在控制台中显示的 xy 坐标。

然而,这些是 Unity 检查器中显示的实际坐标:

同样奇怪的是,这些坐标不会因每个对象而改变,它们实际上会保持不变,即使在对象被销毁后也是如此。谁能解释为什么会这样?也许提供解决方案?

编辑: 更清楚的例子:

每次我实例化我的炮弹对象时,下一个要实例化的对象的 xy 坐标都是从上一个对象引用的。这是我的第一个实例化对象被销毁后的结果。

这里是在实例化第二个对象之后。

现在我期望实例化的每个新对象都应该从它的 "original" 位置开始(比喻地说)并且 xy 值应该重置并重新开始有效。

您在代码的 FixedUpdate() 部分提供的代码中发生了一些事情,我在下面复制了这些代码:

void FixedUpdate()
{
    dis_x = (float)(fx * Time.timeSinceLevelLoad);
    dis_y = (float)(fy + Time.timeSinceLevelLoad + (0.5) * (-gravity) * Time.timeSinceLevelLoad * Time.timeSinceLevelLoad);
    Debug.Log (dis_x+", "+dis_y);
    gameObject.transform.Translate (new Vector2(dis_x, dis_y));
}

首先,Time.timeSinceLevelLoad 为您提供自关卡加载以来经过的时间(以秒为单位)。这对您的代码意味着 dis_xdis_y 始终具有较大的值,您打开应用程序的时间越长。所以,当你生成一个新的预制件时,d_xd_y 值已经位于一个位置,看起来好像它正在使用最后一个预制件的位置。

相反,如果您想根据物体的速度计算物体的新位置,通常需要使用 deltaTime。例如:

dx = vel.x * Time.fixedDeltaTime;
dy = vel.y * Time.fixedDeltaTime;

在此示例中,dxdy 表示给定对象速度的位置变化。 Time.fixedDeltaTime 表示自上次调用 FixedUpdate() 以来经过的时间(以秒为单位)。然后,您可以将 dxdy 添加到您的位置以获得新位置。

其次,gameObject.transform.Translate()平移GameObject的位置;它设置游戏对象的位置。 Translate 只会将 Vector3 添加到您的当前位置。这就是为什么你的调试输出看起来很奇怪; dis_xdis_y 不是您的位置;它们是您通过调用 Translate().

将 GameObject 移动了多远

要设置游戏对象的位置,请执行以下操作:

gameobject.transform.position = newPosition;

...其中 newPosition 是代表游戏对象新位置的 Vector3。