简体   繁体   English

如何立即逆转重力?

[英]How to reverse gravity immediately?

I'm making a 2D game.我正在制作一个2D游戏。 I have a Cube Object falling down from the top of the screen, and I have pipes which the cube should pass by reversing gravity.我有一个立方体对象从屏幕顶部掉下来,我有立方体应该通过反转重力通过的管道。

Well my object is falling down from the top of the screen.好吧,我的物体正在从屏幕顶部掉下来。 I tap on the screen to reverse gravity but it's not going immediately up: it takes time to change the gravity orientation.我点击屏幕来反转重力,但它不会立即上升:改变重力方向需要时间。 When i tap the screen my object continues falling and then goes up.当我点击屏幕时,我的物体继续下落然后上升。 My movement is forming the shape of a U when I tap the screen.当我点击屏幕时,我的动作正在形成U形。 The same thing happens when it goes up: I tap it to go down and in that case my movement forms the shape of a .当它上升时也会发生同样的事情:我点击它下降,在这种情况下,我的运动形成了的形状。

What I want to achieve is that when I tap the screen my object's movement has instant response.我想要实现的是,当我点击屏幕时,我的对象的运动有即时响应。

In addition, I want some sort of attenuation, damping, or smoothing.此外,我想要某种衰减、阻尼或平滑。

I've tried these examples without success:我试过这些例子没有成功:

http://docs.unity3d.com/ScriptReference/Vector2.Lerp.html http://docs.unity3d.com/ScriptReference/Vector2.Lerp.html

http://docs.unity3d.com/Documentation/ScriptReference/Vector3.SmoothDamp.html http://docs.unity3d.com/Documentation/ScriptReference/Vector3.SmoothDamp.html

This is my code:这是我的代码:

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);
}

} This script is attached to the falling cube.此脚本附加到下降的立方体。

When affected by a constant force (in your code, gravity), an object will move in a parabola.当受到恒定力(在您的代码中,重力)影响时,对象将沿抛物线运动。 You're observing a parabola: that U shape.您正在观察抛物线: U形。 To avoid the parabola and get instant response (a V shape), don't use forces.为避免抛物线并获得即时响应( V形),请勿使用力。 Replace the gravityScale code with something like:用类似的东西替换gravityScale代码:

Vector2 velocity = player.velocity;
velocity.y = -velocity.y;
player.velocity = velocity;

This inverts the velocity's y component, making the player move upwards.这会反转速度的 y 分量,使玩家向上移动。


You also mentioned you want to smooth this out.你还提到你想解决这个问题。 I suggest adding another variable: the target velocity.我建议添加另一个变量:目标速度。

To implement this, add Vector2 targetVelocity to your component.要实现这一点,请将Vector2 targetVelocity添加到您的组件中。 Then, during each FixedUpdate you can interpolate from the current velocity towards the target velocity to gradually change speed.然后,在每次FixedUpdate期间,您可以从当前速度向目标速度进行插值以逐渐改变速度。 Replace this line in your current code:替换当前代码中的这一行:

player.velocity = new Vector2(moveSpeed, player.velocity.y);

With this:有了这个:

player.velocity = Vector2.Lerp(player.velocity, targetVelocity, 0.01f);

This will slowly change the velocity to be the same as the target velocity, smoothing out the movement.这将缓慢地将速度更改为与目标速度相同,从而平滑运动。 0.01f is the place between the old velocity and the new velocity that the player's velocity is set to. 0.01f是旧速度和玩家速度设置的新速度之间的位置。 Choose a larger number to interpolate more quickly, and a smaller number to change direction more slowly.选择较大的数字可以更快地进行插值,选择较小的数字可以更慢地改变方向。

Then, instead of changing velocity when the screen is tapped, change targetVelocity .然后,不要在点击屏幕时更改velocity ,而是更改targetVelocity Make sure that the x component of targetVelocity is equal to moveSpeed , or the object won't move horizontally at all!确保targetVelocityx分量等于moveSpeed ,否则对象根本不会水平移动!


Combining these two changes, the Start and FixedUpdate methods should look similar to this:结合这两个更改, StartFixedUpdate方法应如下所示:

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);
}

Note that you shouldn't use Input in FixedUpdate , because inputs are updated every frame and FixedUpdate may run multiple times per frame.请注意,您不应在FixedUpdate使用Input ,因为输入每帧FixedUpdate更新,而FixedUpdate可能每帧运行多次。 This could cause the input to be read twice, especially if the frame rate gets slower and the fixed update is more likely to need to run multiple times per frame.这可能会导致输入被读取两次,尤其是当帧速率变慢并且固定更新更可能需要每帧运行多次时。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM