对象坐标未按预期更新
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 秒后按应有的方式销毁,但是对象 x
和 y
的位置根本没有改变,也不是什么我应该期望他们是。让我举个例子:
这些是我在控制台中显示的 x
和 y
坐标。
然而,这些是 Unity 检查器中显示的实际坐标:
同样奇怪的是,这些坐标不会因每个对象而改变,它们实际上会保持不变,即使在对象被销毁后也是如此。谁能解释为什么会这样?也许提供解决方案?
编辑: 更清楚的例子:
每次我实例化我的炮弹对象时,下一个要实例化的对象的 x
和 y
坐标都是从上一个对象引用的。这是我的第一个实例化对象被销毁后的结果。
这里是在实例化第二个对象之后。
现在我期望实例化的每个新对象都应该从它的 "original" 位置开始(比喻地说)并且 x
和 y
值应该重置并重新开始有效。
您在代码的 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的位置;它不设置游戏对象的位置。 Translate 只会将 Vector3 添加到您的当前位置。这就是为什么你的调试输出看起来很奇怪; dis_x
和 dis_y
不是您的位置;它们是您通过调用 Translate()
.
将 GameObject 移动了多远
要设置游戏对象的位置,请执行以下操作:
gameobject.transform.position = newPosition;
...其中 newPosition
是代表游戏对象新位置的 Vector3。
我在脚本中实例化的预制件有问题。我想要做的是模拟炮弹弹丸运动背后的物理原理。我的预制件附有以下脚本:
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
坐标都是从上一个对象引用的。这是我的第一个实例化对象被销毁后的结果。
这里是在实例化第二个对象之后。
现在我期望实例化的每个新对象都应该从它的 "original" 位置开始(比喻地说)并且 x
和 y
值应该重置并重新开始有效。
您在代码的 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的位置;它不设置游戏对象的位置。 Translate 只会将 Vector3 添加到您的当前位置。这就是为什么你的调试输出看起来很奇怪; dis_x
和 dis_y
不是您的位置;它们是您通过调用 Translate()
.
要设置游戏对象的位置,请执行以下操作:
gameobject.transform.position = newPosition;
...其中 newPosition
是代表游戏对象新位置的 Vector3。