我遇到了预制件的问题,我在我的脚本中进行了实例化。我试图做的是模拟炮弹弹丸运动背后的物理学。我的预制件附有以下脚本:
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
坐标。这是我被破坏后第一个实例化对象的结果。
在这里他们是在实例化第二个对象之后。
现在我所期待的是每个实例化的新对象应该从它开始&#34;原始&#34;位置(比喻说),x
和y
值应重置并有效重新开始。
答案 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_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的位置;它不设置GameObject的位置。翻译只会将Vector3添加到您当前的位置。这就是你的调试输出看起来很奇怪的原因; dis_x
和dis_y
不是你的立场;它们是通过调用Translate()
来移动GameObject的距离。
要设置GameObject的位置,请改为:
gameobject.transform.position = newPosition;
...其中newPosition
是一个代表游戏对象新位置的Vector3。