【问题标题】:Object coordinates not updating as expected对象坐标未按预期更新
【发布时间】:2015-03-21 02:48:34
【问题描述】:

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

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 秒后被销毁,但是对象 x 和 y 的位置根本没有改变,也不是我所期望的.举个例子吧:

这些是x 和y 坐标,我应该期望它们在控制台中显示。

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

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

编辑:更清晰的例子:

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

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

现在我期望实例化的每个新对象都应从其“原始”位置(形象地说)开始,x 和 y 值应重置并有效地重新开始。

【问题讨论】:

  • 使用Translate,您将根据给定的数量更改x 和y,而不是将它们设置为x 和y。与实际的x 和y 位置相比,它们的数量相对较少,所以您可能没有注意到游戏窗口中的差异?
  • 谢谢,但是为什么在每个实例化的新对象上引用相同的x 和y 位置?就像我实例化一个对象一样,下一个对象将引用被销毁后前一个对象留下的x 和y 线。
  • 理想情况下,我想要的是每个实例化的新对象都从引用的“原始”线开始
  • 它们都在同一个地方被实例化的原因很简单——你告诉Instantiate在FirePoint.position创建它们,它永远不会改变。
  • 嗯,是的,这就是我想要的,问题是每个 x 和 y 绳子都是从最后一个实例化的对象中引用的。我不认为我解释得很好。我将尝试用更清晰的示例更新 OP。

标签: c# unity3d game-physics


【解决方案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_x 和dis_y 始终具有较大的值,您的应用程序打开的时间越长。所以,当你生成一个新的预制件时,d_x 和 d_y 值已经在一个位置,好像它正在使用最后一个预制件的位置。

相反,如果您想计算一个给定速度的对象的新位置,您通常希望使用 deltaTime 来代替。例如:

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

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

其次,gameObject.transform.Translate() 平移 GameObject 的位置;它确实不设置游戏对象的位置。翻译只会将 Vector3 添加到您当前的位置。这就是为什么您的调试输出看起来如此奇怪的原因; dis_x 和 dis_y 不是你的职位;它们是您通过调用Translate() 移动游戏对象的距离。

要设置游戏对象的位置,请改为:

gameobject.transform.position = newPosition;

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

【讨论】:

  • 谢谢,这实际上让我了解了我正在使用的时间。我通过创建一个名为elapsed_time 的单独变量并传递它而不是Time.timeSinceLevelLoad 并在每次更新运行时使用Time.fixedDeltaTime 更新它找到了一个解决方案。它现在完全按预期运行!
猜你喜欢
  • 1970-01-01
  • 2019-07-15
  • 2021-11-22
  • 2018-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多