Top Down Projectiles
As part of my major work, i am trying to create a top down shooting game. The game i am trying to create was originally created in scratch (i know, sorry.) (Original game here so you can see something similar to what i am trying to do: https://scratch.mit.edu/projects/17929257/)
Psuedocode: (Sort of)
When key space pressed
create a clone of object "projectile"
point clone of "projectile" at mouse pointer
move projectile in the direction it is facing at speed X
When clone of projectile is touching object Y
delete it.
I cant find a tutorial that actually shows me how to do this. An example code or a link to a tutorial that shows just how to do the shooting will be appreciated.
Note the project is in unity 2d.
Thanks!
Answer by DoWeLikeTurtles · Dec 10, 2018 at 04:40 PM
Hello! Two years too late, but I struggled with this for well over 20 hours as a new coder so I'm sure this might be helpful for someone out there! First things first, the script and directions below are my own so if there's a way to improve them (since I am new to c# and unity) then feel free to point that out! Ok! Now, the meat! First script you will put on your player character to instantiate (or spawn for all intensive purposes) the projectile with correct rotation and positioning and I can explain what all of it is so the new kids will be more able to later! I added an attack time counter bc i thought it'd be useful!
public GameObject bullet;
public float attackTime;
private float attackTimeCounter;
private bool attacking;
// Use this for initialization
void Start()
{
}
void Update()
{
//this is a simple bool to check if the attacktimecounter is at 0 or less yet! you can safely remove this part if you want no timer!
if (!attacking)
{
//you can change this to whatever key you want it to be and if you want to have to click each time you want to shoot, you can change it to GetKeyDown or GetKeyUp!
if (Input.GetKey(KeyCode.Mouse0))
{
attacking = true;
attackTimeCounter = attackTime;
Vector2 target = Camera.main.ScreenToWorldPoint(new Vector2(Input.mousePosition.x, Input.mousePosition.y));
Vector2 myPos = new Vector2(transform.position.x, transform.position.y);
Vector2 direction = target - myPos;
direction.Normalize();
Quaternion rotation = Quaternion.Euler(0, 0, Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg + -90f);
GameObject projectile = (GameObject)Instantiate(bullet, myPos, rotation);
}
}
//this is the attack time counter which you can set in unity
if (attackTimeCounter >= 0)
{
attackTimeCounter -= Time.deltaTime;
}
if (attackTimeCounter < 0)
{
attacking = false;
}
}
Secondly, you'll want to make a Bullet prefab! Create a new 2d sprite with a rigidbody2d and a collider of sorts (what type I guess depends on the shape of your projectile!) Make sure the rigidbody2d gravity is set to "0" and the collider is set to "is trigger" then create a new script called BulletMove! (Why that? idk, it fits well) And in this script will be the following:
public float timeToDestroy;
public float amount;
private Rigidbody2D myRigidBody;
//beautiful work of art by me
private bool isMoving;
void Start()
{
myRigidBody = GetComponent<Rigidbody2D>();
}
// Use this for initialization
void Update()
{
if (Input.GetKey(KeyCode.Mouse0))
{
//this is a simple bool to check if the bullet is in motion! simply put, once given motion, the bool will be set to true prohibiting another shot to alter the position of the previous bullet! if you want to learn, go ahead and remove this part and see what happens!
if (!isMoving)
{
Vector3 sp = Camera.main.WorldToScreenPoint(transform.position);
Vector3 direction = (Input.mousePosition - sp).normalized;
myRigidBody.velocity = direction * amount;
//problem solver bool right here! took me lots of hours to get it figured out!
isMoving = true;
}
}
//destroy this object over time set by you in unity
timeToDestroy -= Time.deltaTime;
if (timeToDestroy <= 0)
{
Destroy(gameObject);
}
}
// this is what makes the bullet disappear when it encounters a collider with the tag of Enemy or collider! The capitalization is important when making triggers!
private void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.tag == "Enemy")
{
Destroy(this.gameObject);
}
if (other.gameObject.tag == "collider")
{
Destroy(this.gameObject);
}
}
Next, you'll want to add the sprite to your prefabs and delete the one on the map you just made! But it will be saved in prefabs! Now, on your players bullet creation script you will want to drag and drop the bullet prefab onto the box to the right of "bullet" so it knows what to spawn each time! then you'll of course want to set your attack time right under that (I use 0.40 but I guess its up to how you wanna do it!) then go on over to your bullet prefab and set up your TimeToDestroy (this is in seconds, not distance) and your projectiles movespeed (located to the right of "Amount" and that should make you able to fire in the direction of the mouse! Now, in order to get the "disappears on collision" part working you'll have to set up the tags with colliders all by yourself! Thanks for joining in!
-Turtles
make sure to upvote so others can see later! That way newer creators wont have to struggle so much!
Now that I look at it, you can remove most of a line of code to not get errors!
GameObject projectile = (GameObject)Instantiate(bullet, myPos, rotation);
should look like
Instantiate(bullet, myPos, rotation);
using the previous version just clutters the code!