如何立即反转重力?
How to reverse gravity immediately?
我正在制作 2D 游戏。我有一个立方体对象从屏幕顶部掉落,我有立方体应该通过反转重力通过的管道。
嗯,我的物体从屏幕顶部掉落。我点击屏幕以反转重力,但它不会立即上升:改变重力方向需要时间。当我点击屏幕时,我的物体继续下落然后上升。当我点击屏幕时,我的动作正在形成 U
的形状。当它上升时会发生同样的事情:我点击它下降,在这种情况下我的运动形成 ∩
.
的形状
我想要实现的是,当我点击屏幕时,我的对象的移动有即时响应。
此外,我想要某种衰减、阻尼或平滑。
我试过这些例子但没有成功:
http://docs.unity3d.com/ScriptReference/Vector2.Lerp.html
http://docs.unity3d.com/Documentation/ScriptReference/Vector3.SmoothDamp.html
这是我的代码:
public class PlayerControls : MonoBehaviour
{
public GameObject playerObject = null;
Rigidbody2D player;
public float moveSpeed;
public float up;
Vector2 targetVelocity;
void Start()
{
player = playerObject.GetComponent<Rigidbody2D>();
// Set the initial target velocity y component to the desired up velocity.
targetVelocity.y = up;
}
void Update()
{
for (int i = 0; i < Input.touchCount; i++)
{
Touch touch = Input.GetTouch(i);
if (touch.phase == TouchPhase.Ended && touch.tapCount == 1)
{
// Flip the target velocity y component.
targetVelocity.y = -targetVelocity.y;
}
}
}
void FixedUpdate()
{
// Ensure if moveSpeed changes, the target velocity does too.
targetVelocity.x = moveSpeed;
// Change the player's velocity to be closer to the target.
player.velocity = Vector2.Lerp(player.velocity, targetVelocity, 0.01f);
}
}
此脚本附在掉落的立方体上。
当受到恒定力(在您的代码中为重力)影响时,物体将沿抛物线运动。您正在观察抛物线:U
形状。为避免抛物线并获得即时响应(V
形状),请勿使用力。将 gravityScale
代码替换为:
Vector2 velocity = player.velocity;
velocity.y = -velocity.y;
player.velocity = velocity;
这会反转速度的 y 分量,使玩家向上移动。
你还提到你想解决这个问题。我建议添加另一个变量:目标速度。
要实现这一点,请将 Vector2 targetVelocity
添加到您的组件中。然后,在每个 FixedUpdate
期间,您可以从当前速度向目标速度进行插值以逐渐改变速度。将此行替换为您当前的代码:
player.velocity = new Vector2(moveSpeed, player.velocity.y);
有了这个:
player.velocity = Vector2.Lerp(player.velocity, targetVelocity, 0.01f);
这将慢慢改变速度,使其与目标速度相同,从而平滑移动。 0.01f
是玩家速度设置为旧速度和新速度之间的位置。选择较大的数字插值速度较快,较小的数字方向变化较慢。
然后,在点击屏幕时不再更改 velocity
,而是更改 targetVelocity
。确保 targetVelocity
的 x
分量等于 moveSpeed
,否则对象根本不会水平移动!
结合这两个变化,Start
和 FixedUpdate
方法应该类似于:
void Start()
{
player = playerObject.GetComponent<Rigidbody2D>();
// Set the initial target velocity y component to the desired up velocity.
targetVelocity.y = up;
}
void Update()
{
for (int i = 0; i < Input.touchCount; i++)
{
Touch touch = Input.GetTouch(i);
if (touch.phase == TouchPhase.Ended && touch.tapCount == 1)
{
// Flip the target velocity y component.
targetVelocity.y = -targetVelocity.y;
}
}
}
void FixedUpdate()
{
// Ensure if moveSpeed changes, the target velocity does too.
targetVelocity.x = moveSpeed;
// Change the player's velocity to be closer to the target.
player.velocity = Vector2.Lerp(player.velocity, targetVelocity, 0.01f);
}
请注意,您不应在 FixedUpdate
中使用 Input
,因为输入每帧都会更新,而 FixedUpdate
可能每帧 运行 多次。这可能会导致输入被读取两次,尤其是在帧速率变慢并且固定更新更有可能需要每帧 运行 多次的情况下。
我正在制作 2D 游戏。我有一个立方体对象从屏幕顶部掉落,我有立方体应该通过反转重力通过的管道。
嗯,我的物体从屏幕顶部掉落。我点击屏幕以反转重力,但它不会立即上升:改变重力方向需要时间。当我点击屏幕时,我的物体继续下落然后上升。当我点击屏幕时,我的动作正在形成 U
的形状。当它上升时会发生同样的事情:我点击它下降,在这种情况下我的运动形成 ∩
.
我想要实现的是,当我点击屏幕时,我的对象的移动有即时响应。
此外,我想要某种衰减、阻尼或平滑。
我试过这些例子但没有成功:
http://docs.unity3d.com/ScriptReference/Vector2.Lerp.html
http://docs.unity3d.com/Documentation/ScriptReference/Vector3.SmoothDamp.html
这是我的代码:
public class PlayerControls : MonoBehaviour
{
public GameObject playerObject = null;
Rigidbody2D player;
public float moveSpeed;
public float up;
Vector2 targetVelocity;
void Start()
{
player = playerObject.GetComponent<Rigidbody2D>();
// Set the initial target velocity y component to the desired up velocity.
targetVelocity.y = up;
}
void Update()
{
for (int i = 0; i < Input.touchCount; i++)
{
Touch touch = Input.GetTouch(i);
if (touch.phase == TouchPhase.Ended && touch.tapCount == 1)
{
// Flip the target velocity y component.
targetVelocity.y = -targetVelocity.y;
}
}
}
void FixedUpdate()
{
// Ensure if moveSpeed changes, the target velocity does too.
targetVelocity.x = moveSpeed;
// Change the player's velocity to be closer to the target.
player.velocity = Vector2.Lerp(player.velocity, targetVelocity, 0.01f);
}
} 此脚本附在掉落的立方体上。
当受到恒定力(在您的代码中为重力)影响时,物体将沿抛物线运动。您正在观察抛物线:U
形状。为避免抛物线并获得即时响应(V
形状),请勿使用力。将 gravityScale
代码替换为:
Vector2 velocity = player.velocity;
velocity.y = -velocity.y;
player.velocity = velocity;
这会反转速度的 y 分量,使玩家向上移动。
你还提到你想解决这个问题。我建议添加另一个变量:目标速度。
要实现这一点,请将 Vector2 targetVelocity
添加到您的组件中。然后,在每个 FixedUpdate
期间,您可以从当前速度向目标速度进行插值以逐渐改变速度。将此行替换为您当前的代码:
player.velocity = new Vector2(moveSpeed, player.velocity.y);
有了这个:
player.velocity = Vector2.Lerp(player.velocity, targetVelocity, 0.01f);
这将慢慢改变速度,使其与目标速度相同,从而平滑移动。 0.01f
是玩家速度设置为旧速度和新速度之间的位置。选择较大的数字插值速度较快,较小的数字方向变化较慢。
然后,在点击屏幕时不再更改 velocity
,而是更改 targetVelocity
。确保 targetVelocity
的 x
分量等于 moveSpeed
,否则对象根本不会水平移动!
结合这两个变化,Start
和 FixedUpdate
方法应该类似于:
void Start()
{
player = playerObject.GetComponent<Rigidbody2D>();
// Set the initial target velocity y component to the desired up velocity.
targetVelocity.y = up;
}
void Update()
{
for (int i = 0; i < Input.touchCount; i++)
{
Touch touch = Input.GetTouch(i);
if (touch.phase == TouchPhase.Ended && touch.tapCount == 1)
{
// Flip the target velocity y component.
targetVelocity.y = -targetVelocity.y;
}
}
}
void FixedUpdate()
{
// Ensure if moveSpeed changes, the target velocity does too.
targetVelocity.x = moveSpeed;
// Change the player's velocity to be closer to the target.
player.velocity = Vector2.Lerp(player.velocity, targetVelocity, 0.01f);
}
请注意,您不应在 FixedUpdate
中使用 Input
,因为输入每帧都会更新,而 FixedUpdate
可能每帧 运行 多次。这可能会导致输入被读取两次,尤其是在帧速率变慢并且固定更新更有可能需要每帧 运行 多次的情况下。