1
\$\begingroup\$

I've created a script that allows my player to move using UI button, however my player's movement isn't very smooth or flowing, instead it's very clunky and somewhat looks like my player is teleporting. I tried following tutorials on YouTube, however I was having problem with accessing the 'Unity Standard Assets' as for some reason it wasn't there. I read up for information about people re-importing it into their projects only to have it mess up parts of their games. Overall I was wondering if there any one can help me fix my problem! Thank you :)

My script:

public float moveSpeed;

void Update () {
    if (moveRight == true) { // Here I have tried methods like Addforce and velocity, but for some reason it wasn't working!!
        GetComponent<Rigidbody2D>().AddForce (transform.right * maxSpeed);
    } else if (moveRight == false) {
        GetComponent<Rigidbody2D>().AddForce (transform.right * maxSpeed);
    }
}

public void MoveLeft() {
   transform.position -= transform.forward * Time.deltaTime * moveSpeed;

  // moveRight = false;
}


public void MoveRight() {
   transform.position += transform.forward * Time.deltaTime * moveSpeed;

 // moveRight = true;

}
\$\endgroup\$
2
  • \$\begingroup\$ @TheMattbat999 Nope. I have a code snippet which does turning quite well (I don't have access to it right now) and I'm pretty sure it'd do movement quite well as well. If I can get someone to boot up my PC I'll post that snippet here, if not, I'll take a look tonight (if this is still not answered by then) \$\endgroup\$ Oct 26, 2017 at 7:16
  • \$\begingroup\$ Thank you @ John Hamilton for replying, your insight would be most helpful! :) \$\endgroup\$ Oct 26, 2017 at 8:28

3 Answers 3

1
\$\begingroup\$

Here's my version:

These values decide how fast the increase or decrease will happen and what the base values are (so that I don't lose track of them or have to change them one by one)

public float angle = .1f; //public so that I can modify it from the Unity UI
float angleStart = .05f;
float timerStart = 0f;
float timer = 0;
float timerIncrease = 0.001f;

This is the partial update function, the rest is the button functions.

Update()
{
    if (Input.GetKey(KeyCode.LeftArrow))
    {
        TurnLeft();
    }
    if (Input.GetKey(KeyCode.RightArrow))
    {
        TurnRight();
    }
    if (Input.GetKeyUp(KeyCode.UpArrow) || Input.GetKeyUp(KeyCode.DownArrow)
        || Input.GetKeyUp(KeyCode.LeftArrow) || Input.GetKeyUp(KeyCode.RightArrow))
    {
        angle = angleStart; //reset values so that the next time buttons are
        timer = timerStart; //pressed, they won't be at their max increase values
    }
}

These are the functions that are actually doing all the calculations, of course function names will differ and what they do will also differ in your version.

public void TurnRight()
{
    if (timer < 0.1)
        timer = timer + timerIncrease;
    transform.Rotate(0, 0, -angle); //only this part is different between right and left
    if (angle < 5)
        angle = angle + timer;
}

public void TurnLeft()
{
    if (timer < 0.1) //guarantees that timer won't go too high and make janky movement
        timer = timer + timerIncrease;
    transform.Rotate(0, 0, angle);
    if (angle < 5) //guarantees that the angle increase won't go overboard and make stupid turns
        angle = angle + timer;
}

Changing transform.Rotate() to something else that uses the angle variable will give you smooth movement. Of course, my suggestion would be to just re-write these and use as necessary.

One example would be to change TurnLeft() to MoveLeft() (I'm assuming go left means go towards minus on the X axis for this example):

public void MoveLeft()
{
    if (timer < 0.1) 
        timer = timer + timerIncrease;
    if (speed < 5) 
        speed = speed + timer;
    transform.position = new Vector3(transform.position.x - speed, transform.position.y, transform.position.z);
}

Of course, if you want to use AddForce() you can figure that out pretty easily from these examples. I'm not going to give an example of that as I don't really have means to test that code.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Thank you for your help, it worked and it just what i'm looking for!!!! I really appreciate your help! :) \$\endgroup\$ Oct 26, 2017 at 15:27
  • \$\begingroup\$ Sorry to ask this to late, but I was wondering if you knew a way to limit the distance of: transform.position = new Vector3(transform.position.x - speed, transform.position.y, transform.position.z); Any insight? Thank you again for your help! :) @John Hamilton \$\endgroup\$ Oct 27, 2017 at 20:28
  • \$\begingroup\$ @JesscaStone You can use Mathf.Clamp to limit the values individually, or use an if check whenever the character tries to move. As in if(transform.position.x-speed > limitvalue) {transform.position = new Vector3(transform.position.x - speed, transform.position.y, transform.position.z);}else{transform.position = new Vector3(limitvalue, transform.position.y, transform.position.z);} \$\endgroup\$ Oct 30, 2017 at 5:44
1
\$\begingroup\$

This post is extremely relevant. Basiclly, you need to add event triggers to the buttons, then add the following script to the buttons:

using UnityEngine.UI;   // add to 
//the top

private bool moveLeft;
private bool moveRight;

void Update()
{
    if(moveLeft && !moveRight)
     rigidbody2D.AddForce 
(Vector3.left * forwardSpeed);

 if(moveRight && !moveLeft)
     rigidbody2D.AddForce (Vector2.right * forwardSpeed);
}

public void MoveMeLeft()
{
    moveLeft = true;
}

public void StopMeLeft()
{
    moveLeft = false;
}

// do the same for right

Fair warning: I didn't write this code, so I am not sure if it works properly, though it looks like it will work.

\$\endgroup\$
4
  • \$\begingroup\$ Thank you fro replying, it worked! However, now moving to fast and far! Is there a way to limit the amount of addforce on my player's movement, like for example the player will stop every few distance and the user will have to press the button every few times the player stops! Thank you once again :) \$\endgroup\$ Oct 26, 2017 at 8:38
  • \$\begingroup\$ You could try dividing the force like (Vector2.right * Time.deltaTime /2) to reduce speed some and reduce the amount of force exerted by the script. \$\endgroup\$ Oct 26, 2017 at 9:56
  • \$\begingroup\$ Tried that, but I have now found a solution to my problem thanks to John Hamilton. Thank you for your contribution and help, I really appreciate it! \$\endgroup\$ Oct 26, 2017 at 15:28
  • \$\begingroup\$ Your welcome, @JesscaStone! \$\endgroup\$ Oct 26, 2017 at 16:14
1
\$\begingroup\$

We use two Event triggers and Delegate for one is Left side button and second is Right side button.

public class EventManager : MonoBehaviour
{
    public delegate void OnMoveLeft ();
    public static event OnMoveLeft onMoveLeft;
    public static void RaiseOnMoveLeft ()
    {
        if (onMoveLeft != null)
            onMoveLeft ();
    }

    public delegate void OnMoveRight ();
    public static event OnMoveRight onMoveRight;
    public static void RaiseOnMoveRight ()
    {
        if (onMoveRight != null)
            onMoveRight ();
    }
}

When UI button clicked, same time event must raise either Left Side or Right Side.

public class GamePlayView : MonoBehaviour
{
    public void OnLeft(){
        EventManager.RaiseOnMoveLeft();
    }

    public void OnRight(){
        EventManager.RaiseOnMoveRight();
    }
}

Player Script We have to use Event Register and Deregister for Both Event triggers. When Button click that time according to that Event handlers method are called. And player performed.

public class Player : MonoBehaviour
{
    public float forwardSpeed;
    private Rigidbody2D rigidbody;

    void Awake(){
        rigidbody = GetComponent<Rigidbody>();
    }

    void OnEnable(){
        EventManager.onMoveLeft += EventManager_onMoveLeft;
        EventManager.onMoveRight += EventManager_onMoveRight;
    }

    void OnDisable(){
        EventManager.onMoveLeft -= EventManager_onMoveLeft;
        EventManager.onMoveRight -= EventManager_onMoveRight;
    }

    void EventManager_onMoveLeft ()
    {
        rigidbody.AddForce(-Vector3.right * forwardSpeed);
    }

    void EventManager_onMoveRight ()
    {
        rigidbody.AddForce(Vector3.right * forwardSpeed);
    }
}
\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .