简体   繁体   中英

How can I make 2d object constantly moving in one direction, but when given horizontal input change direction but not change speed?

My apologies ahead as I am a pure noob to Unity libraries and Unity itself.

I am creating a simple 2d game, where a 2d object needs to be constantly moving in a facing direction, but when applied horizontal input (eg A, D) it needs to change the vector of movement and not change speed.

The object has a property Rididbody2d

This is what I came up to so far:

{ 
      [SerializeField]
      private float speed;

      [SerializeField]
      private float rotationSpeed;
      
    // Start is called before the first frame update  

    void Start()
    {       

    }


    // Update is called once per frame
     void Update ()
     {      
           
           float horizontalInput = Input.GetAxis("Horizontal");
           float verticalInput = Input.GetAxis("Vertical");

            

            Vector2 movementDirection = new Vector2(horizontalInput, verticalInput);
            float inputMagnitude = Mathf.Clamp01(movementDirection.magnitude);
            movementDirection.Normalize();

 
            transform.Translate(movementDirection * speed * inputMagnitude * Time.deltaTime, Space.World);

            if (movementDirection != Vector2.zero) {
                  Quaternion toRotation = Quaternion.LookRotation(Vector3.forward, movementDirection);
                  transform.rotation = Quaternion.RotateTowards(transform.rotation, toRotation, rotationSpeed * Time.deltaTime);
            }

            
     }
}

My idea is that during the update we should get whether the input was registered or not and if it was then the current vector multiply (?) by an angle that has been received (if pressed for 0.1 sec -> 0deg+1deg if pressed for 2 sec -> 0deg + say 90 deg eg).

HOWEVER! Following the tutorials, I managed to get this thing moving only when keys are pressed. I googled my mind off and found actually nothing helpful. Manual was reread many times. Please help me!

PS English is not my native language, sorry for making mistakes!

as soon as physics are involved you do NOT want to do anything via transform at all but rather via the rigidbody component and also not in Update but in FixedUpdate .. otherwise you get all kind of strange behavior and break he physics/collision detection!

It sounds to me like what you would want to do would be:

[SerializeField] private float speed;
[SerializeField] private float rotationSpeed;

// reference this in the Inspector if possible
[SerializeField] private Rigidbody2D rigidbody;

// keep track of the target rotation
// for Rigidbody2D this is a simple float for the rotation angle
private float angle = 0;

private void Awake()
{
    // as fallback get the Rigidboy2D on runtime
    if(!rigidbody) rigidbody = GetComponent<Rigidbody2D>();
}

private void Update ()
{      
    // Still get user input in Update to not miss a frame

    // evtl you would need to swap the sign according to your needs
    angle += Time.deltaTime * rotationSpeed * Input.GetAxis("Horizontal");
}

private void FixedUpdate()
{
    // rotate the Rigidbody applying the configured interpolation
    rb.MoveRotation(angle);

    // assuming if the object is not rotated you want to go right
    // otherwise simply change this vector
    rb.velocity = rb.GetRelativeVector(Vector3.right).normalized * speed;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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