4
\$\begingroup\$

I made a 2D game with Unity, and I am trying to create a platform that will move from left to right continuously, but I don't know how to make the platform move a greater distance then -1 to 1 units because I use the Mathf.Sin function. I can only control the speed of the platform.

Here is my code:

private Vector2 startPosition;
private int speed;

void Start () 
{
    startPosition = transform.position;
    speed = 3;
}

void Update() 
{
    transform.position = 
        new Vector2(startPosition.x + Mathf.Sin(Time.time * speed), transform.position.y);
}

Here is what the code actually does:

An animation of my moving platform

How can I control the distance that the platform can move to each side? For now, it can only move 1 unit to each side.

\$\endgroup\$
  • \$\begingroup\$ You should add a bit more of what you need, e.g. do you want to change the speed, what's going to be the distance, etc. Why do you use Sine? \$\endgroup\$ – Alexandre Vaillancourt Aug 30 '16 at 23:01
  • \$\begingroup\$ @AlexandreVaillancourt I'm using Sine to make the platform move more smoothly at each turn. Basicly I am trying to make the platform move at more distance then (-1,1) lets say (-5,5). btw, is it possible to upload .gif to here so I can show you want I mean? \$\endgroup\$ – LiziPizi Aug 30 '16 at 23:05
  • \$\begingroup\$ You're more that welcome to upload a gif or an animated gif. The more info you give, the more chances you have to get a better answer suited for your needs. \$\endgroup\$ – Alexandre Vaillancourt Aug 30 '16 at 23:20
  • \$\begingroup\$ @AlexandreVaillancourt Can you please help me? \$\endgroup\$ – LiziPizi Aug 30 '16 at 23:32
  • 1
    \$\begingroup\$ If your sine method returns values between [-1, 1], and you want your thing to go from [-5, 5], multiply the value returned by the sine method by 5. This will probably not give you exactly what you want but it's a start :P \$\endgroup\$ – Alexandre Vaillancourt Aug 30 '16 at 23:56
4
\$\begingroup\$

As it is, your code gives your platform a movement distance of 2 units; 1 unit in either direction of its starting position. To allow further movement, all you need to do is effectively multiply the current movement value.

/// <summary>The objects initial position.</summary>
private Vector2 startPosition;
/// <summary>The objects updated position for the next frame.</summary>
private Vector2 newPosition;

/// <summary>The speed at which the object moves.</summary>
[SerializeField] private int speed = 3;
/// <summary>The maximum distance the object may move in either y direction.</summary>
[SerializeField] private int maxDistance = 1;

void Start()
{
    startPosition = transform.position;
    newPosition = transform.position;
}

void Update()
{
    newPosition.x = startPosition.x + (maxDistance * Mathf.Sin(Time.time * speed));
    transform.position = newPosition;
}

By multiplying your movement algorithm of Mathf.Sin(Time.time * speed) by a distance value of maxDistance, you effectivley tell your platform to allow movement of maxDistance units in either direction. The above example gives behavior identical to your current movement; 1 unit of distance in either direction, reversing its direction at -1 and 1. With maxDistance = 50, for example, the platform will move between -50 and 50.

Be aware that as maxDistance increases, you will likely want a lower speed. speed effectively controls how much time it takes to complete an entire movement arc, in this context, not the rate in which it moves in that arc. With maxDistance = 1 and speed = 3, the platform moves between -1 and 1 over 3 seconds. With maxDistance = 10 and speed = 3, the platform moves between -10 and 10 over 3 seconds. Due to the much greater distance, the platform will move a lot faster to cover the ground in the same amount of time. To give the same general speed, you would want something more like maxDistance = 10 and speed = 30. I would personally rename speed to maxTime, though I have not done so in the above example.

I will address the semantic alterations I have made, to avoid confusion:

  • The addition of newPosition gives you a local Vector2 to hold your derived "next position" co-ordinate. We can then work out the updated newPosition.y value on the fly, and do not have to worry about newPosition.x before passing it into transform.position, as this value should not change in the current context.
  • Serializing speed and maxDistance with [SerializeField] serialises these values for the Unity Inspector. As a result, they have retained their private protection, but you can still change them on the fly from the Inspector.
  • Initialising speed and maxDistance inline with the variable declaration simply prevents any Inspector-altered value from resetting when you hit play, and call Start(). You may wish to have these in Start(), just remember that these values will then override any values you have provided through the Inspector. For testing purposes, you can still change the values in the Inspector during a play-test to see the effects in-game.

As it stands, you also want to remember that this deliberately constrains movement to a specific value in either direction. That means that this would not work accurately if you wanted less symmetrical movement; for example, it would not work accurately if you wanted your platform to move 20 units to the left, but only allow 10 units of movement in the opposite direction. It could only be constrained to +-10 or +-20. There are more advanced implementations you could look at to reach this sort of functionality, if needed, though they appear out of scope for the context of this question.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.