Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Make 2D Space Ship Move in Facing Direction

Discussion in 'Scripting' started by Mashimaro7, Aug 21, 2020.

  1. Mashimaro7

    Mashimaro7

    Joined:
    Apr 10, 2020
    Posts:
    723
    I know this is a super basic question, but I've looked everywhere and can't figure it out. I heard it should be done by using transform.up, but no matter what I do, the ship goes straight up or straight down.

    Here's my script
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class SpaceShipMove : MonoBehaviour
    6. {
    7.     public float speed, rotSpeed;
    8.     private Rigidbody2D rb;
    9.  
    10.     private void Start()
    11.     {
    12.         rb = GetComponent<Rigidbody2D>();
    13.     }
    14.  
    15.     private void FixedUpdate()
    16.     {
    17.         ForwardThrust();
    18.     }
    19.  
    20.     void ForwardThrust()
    21.     {
    22.         Vector2 input = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
    23.         Vector2 direction = input.normalized;
    24.         Vector2 velocity = direction * speed;
    25.         Vector2 moveAmt = velocity * Time.deltaTime;
    26.         float rotate = Input.GetAxisRaw("HorizontalRotation");
    27.        
    28.  
    29.         rb.AddForce(transform.up * moveAmt);
    30.  
    31.         this.transform.Rotate(0,0,(-rotate * rotSpeed) * Time.deltaTime);
    32.     }
    33. }
    It seems to rotate just fine, but does not move in the direction it's facing...

    Thanks in advance
     
  2. SkrenZz

    SkrenZz

    Joined:
    Apr 11, 2020
    Posts:
    26
    First of all, since the ForwardThrust is called in your FixedUpdate method, use Time.fixedDeltaTime instead of Time.deltaTime.
    Secondly, I am almost cetain that adding force to rigidbody2d doesn't take the object's rotation into consideration. You could calculate the force vector you want to apply according to your object's rotation with trigonometry.
     
  3. CMDR_Garbage

    CMDR_Garbage

    Joined:
    Apr 29, 2019
    Posts:
    22
    have you tried transform.forward yet?
     
  4. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    @Mashimaro7

    What are you actually trying to do ? A top down asteroids like controls or something else?

    I'm asking because you didn't explain this in your question... but you seem to have ForwardThrust which makes me think you want to rotate the ship and then apply local forward relative force.

    "It seems to rotate just fine, but does not move in the direction it's facing..."

    Use vertical axis for thrust and horizontal for rotation. Maybe your thrust force is too small. See this example:
    https://docs.unity3d.com/ScriptReference/Rigidbody2D.AddForce.html
     
  5. Mashimaro7

    Mashimaro7

    Joined:
    Apr 10, 2020
    Posts:
    723
    Sorry, I'm not good at trigonometry, how do you get the direction from the rotation?

    Yes, it loses all capability of movement for some reason? I think transform.forward doesn't work as well in two dimensional space.

    Oh, sorry I didn't specify, yes, I want Astroid-style controls. Oh and, it definitely has enough thrust, it moves vertically. Also, the "HorizontalRotation" is an axis I made myself, because I wanted to use the "Horizontal" axis for horizontal thrust.
     
    Last edited: Aug 21, 2020
  6. Mashimaro7

    Mashimaro7

    Joined:
    Apr 10, 2020
    Posts:
    723
    Well, I watched a video by Sabastian Lague on trigonometry lol, and I made this script,
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class SpaceShipMove : MonoBehaviour
    6. {
    7.     public float speed, rotSpeed;
    8.     private Rigidbody2D rb;
    9.  
    10.     private void Start()
    11.     {
    12.         rb = GetComponent<Rigidbody2D>();
    13.     }
    14.  
    15.     private void FixedUpdate()
    16.     {
    17.         print(Input.GetAxisRaw("Horizontal"));
    18.         ForwardThrust();
    19.     }
    20.  
    21.     void ForwardThrust()
    22.     {
    23.         Vector2 input = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
    24.         print("input is this " + input);
    25.         Vector2 direction = new Vector2(Mathf.Cos((90 - transform.rotation.z) * Mathf.Deg2Rad), Mathf.Sin(90 - transform.rotation.z) * Mathf.Deg2Rad);
    26.         print("direction is this " + direction);
    27.         Vector2 velocity = direction * speed;
    28.         print("velocity is this " + velocity);
    29.         Vector2 moveAmt = velocity * Time.deltaTime;
    30.         float rotate = Input.GetAxisRaw("HorizontalRotation");
    31.  
    32.         print(moveAmt);
    33.         rb.AddForce(moveAmt);
    34.  
    35.         this.transform.Rotate(0,0,(-rotate * rotSpeed) * Time.fixedDeltaTime);
    36.     }
    37. }
    38.  
    The strange thing is, I have the prints because there was a strange bug where it was moving on it's own. Everything is 0, except velocity, which is printing at (0.0,0.8) with speed set to 50, which is very confusing since the direction is coming back as 0. And I think my trigonometry is off, because it still isn't moving in the direction I'm facing...
     
  7. Mashimaro7

    Mashimaro7

    Joined:
    Apr 10, 2020
    Posts:
    723
  8. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    @Mashimaro7

    Did you try what I said? It should have worked just fine, I linked to an example in Unity manual too.
     
  9. Mashimaro7

    Mashimaro7

    Joined:
    Apr 10, 2020
    Posts:
    723
    Well, as I said in my reply, I am using my horizontal axis for horizontal thrust, and a separate axis for rotation. I just tried this,
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class SpaceShipMove : MonoBehaviour
    6. {
    7.     public float speed, rotSpeed;
    8.     private Rigidbody2D rb;
    9.  
    10.     private void Start()
    11.     {
    12.         rb = GetComponent<Rigidbody2D>();
    13.     }
    14.  
    15.     private void FixedUpdate()
    16.     {
    17.         ForwardThrust();
    18.     }
    19.  
    20.     void ForwardThrust()
    21.     {
    22.         Vector2 input = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
    23.         print("input is this " + input);
    24.         //Vector2 direction = new Vector2(Mathf.Cos((90 - transform.rotation.z) * Mathf.Deg2Rad), Mathf.Sin(90 - transform.rotation.z) * Mathf.Deg2Rad);
    25.         Vector2 direction = input.normalized;
    26.         print("direction is this " + direction);
    27.         Vector2 velocity = direction * speed;
    28.         print("velocity is this " + velocity);
    29.         Vector2 moveAmt = velocity * Time.deltaTime;
    30.         float rotate = Input.GetAxisRaw("HorizontalRotation");
    31.  
    32.         print(moveAmt);
    33.         rb.AddForce(moveAmt, ForceMode2D.Impulse);
    34.  
    35.         this.transform.Rotate(0,0,(-rotate * rotSpeed) * Time.fixedDeltaTime);
    36.     }
    37. }
    38.  
    But it still only moves up and down in world space, and not relative to the direction it's facing.
     
  10. duanegra

    duanegra

    Joined:
    Aug 28, 2018
    Posts:
    10
    Yeh, that's a tough one. It's easy to make a character rotate to follow a target, but not what your talking about. The best explanation that I have found is here:

    This includes a Github repo with about five scripts for different movement behaviors. One of them I think covers what you are looking for.

    All the best.