对象坐标未按预期更新

时间:2015-03-21 02:48:34

标签: c# unity3d game-physics

我遇到了预制件的问题,我在我的脚本中进行了实例化。我试图做的是模拟炮弹弹丸运动背后的物理学。我的预制件附有以下脚本:

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坐标。

enter image description here

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

enter image description here

奇怪的是,这些坐标对于每个对象都不会改变,即使在对象被破坏之后它们也会保持不变。任何人都可以解释为什么会这样吗?也许提供解决方案?

修改:有更清晰的示例:

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

enter image description here

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

enter image description here

现在我所期待的是每个实例化的新对象应该从它开始&#34;原始&#34;位置(比喻说),xy值应重置并有效重新开始。

1 个答案:

答案 0 :(得分:1)

您在代码的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的位置;它设置GameObject的位置。翻译只会将Vector3添加到您当前的位置。这就是你的调试输出看起来很奇怪的原因; dis_xdis_y不是你的立场;它们是通过调用Translate()来移动GameObject的距离。

要设置GameObject的位置,请改为:

gameobject.transform.position = newPosition;

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