0
\$\begingroup\$

I am trying to make a top-down shooter game with similar combat to the Binding of Isaac:

  • when I press the up key the shot goes up
  • when I press the right key the shot goes to the right

I have all the rest of the code such as the point where the projectile is instantiating and the if statement to check for the button press I just want to know where I should put the vector 2 to allow me to set the direction and what to write into the vector 2

private void Update()
{

    if (Input.GetKeyDown("up")) 
    {
        if (Time.time >= shotTime) 

        {
            Instantiate(projectile, shotPoint);
            shotTime = Time.time + timeBetweenShots;

        }
    }

} 

This is my Projectile script (at least the parts that I think would be useful)

void Update()
{
    transform.Translate(Vector2.up * speed * Time.deltaTime);
}

I realized that if I change the Vector2.up to make it say Vector2.down it would now shoot down But I need that to be able to change depending on which direction I am shooting.

\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

First, if you don't always want every projectile to move up, you should make the shot direction a variable:

public class Projectile : MonoBehaviour {
    public Vector2 direction;
    public float speed;

    void Update() {
        transform.Translate(direction * speed * Time.deltaTime);
    }
} 

Then you can make a firing method to spawn a projectile going in a particular direction:

// Assign this in the Inspector to hold your projectile instance.
public Projectile projectilePrefab;

void Shoot(Vector2 direction) {
    Projectile shot = Instantiate<Projectile>(projectilePrefab, shotPoint);
    shot.direction = direction;
    shotTime = Time.time + timeBetweenShots;
}

This lets us simplify the firing routine to something like...

void Update() {

    // This is called a guard clause. By flipping our condition and exiting early,
    // we don't have as many nested levels of if indenting, making it easier to read.
    if(Time.time < shotTime)
       return;

    if (Input.GetKeyDown("Up")) {
       Shoot(Vector2.up);
    }
    else if (Input.GetKeyDown("Right)) {
       Shoot(Vector2.right);
    } 
    else if (Input.GetKeyDown("Down)) {
       Shoot(Vector2.down);
    }
    else if (Input.GetKeyDown("Left)) {
       Shoot(Vector2.left);
    }
}

The else if clauses here ensure we only fire one shot in cases when two keys were pressed in the same frame, giving priority clockwise from "up". Note how packaging up the shooting work into the Shoot method keeps this concise and avoids duplicating code.


Longer term, I'd advise not moving your projectile shot yourself in Update but instead using a Rigidbody2D component on your bullet and setting its speed & direction via the body's velocity property. This keeps the movement of the projectile under the control of the physics system, helping you get more consistent behaviour (and sometimes better performance).

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Commenting to say that last part is vital. You'll run into more bugs than you can count if you're moving the transform position yourself, and trying to do collision later. You should 100% use rigidbody. \$\endgroup\$
    – gjh33
    Mar 25, 2019 at 13:22
0
\$\begingroup\$

It is really hard to understand what exactly you want.

If you want a local Vector2 you can use to translate to north west east south:

Vector2 direction = Vector2.zero;

void Update()
{
    bool up = Input.GetKey(KeyCode.UpArrow);
    bool down = Input.GetKey(KeyCode.DownArrow);
    bool left = Input.GetKey(KeyCode.LeftArrow);
    bool right = Input.GetKey(KeyCode.RightArrow);

    if(up) direction = Vector2.up;
    else if(left) direction = Vector2.left;
    else if(right) direction = Vector2.right;
    else if(down) direction = Vector2.down;
    else direction = Vector2.zero;

    if(direction != Vector2.zero)
        transform.Translate(direction * speed * Time.deltaTime);
}

Keep in mind that multiple keys can be pressed at once and this doesn't account for that and although the displayed logic works, the behaviour is weird, so you need to build your input logic around what you need for game! It is meant only as a display.

\$\endgroup\$

You must log in to answer this question.

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