- Home /
Move player backwards when firing a gun. Unity 2D. Top Down
I'm creating a top down, 2D shooter and I want my player to be knocked or moved back slightly whenever they fire their shotgun to make it feel more powerful. I have no real idea on how to do this however as I am quite new to unity and c#.
I currently have wasd movement working and space to shoot (although it currently only shoots right. Another problem for another time)
Happy to provide any scripts you might need.
Thank you!
How do you move the player around? Do you apply a force to its RigidBody component, or do you simply increase the coordinates in the transform?
If you use a RB, you can simply add a small force in the negative transform.forward direction every time the player shoots.
Yeah the player moves by adding force to its Rigidb2d.
How do you define which way it forward for transform.forward?
You can get the direction from the gun, if it is correctly added you can do something like
playerRB2d.ApplyForce(-shotgun.transform.forward);
But check the actual direction of your gun in the scene view before you do this. Otherwise it might push your player into another direction
Answer by tormentoarmagedoom · Jan 14, 2019 at 03:11 PM
Good day.
You should be able to do this script by your own.
The script should do the "push" action at the same time the bullet is created.
To push the player, you just need to move it. You ahve some different ways.
-Maybe easiest way is to use transform.Translate(vector).
-Or more accurate way, to know how it moves, is simply change its transform.position directly
-Or more realistic result is use physics (if your player have a rigidbody Component), by adding a force in the opposite direction, by busing GetComponent().AddForce
You will need to know how to use at least one of these if you prettend to continue developing. As you can imagine, moving things arround the space is a very basic thig you will need to do soooo many times.
There are thousands of manuals and tutorials about this. Go Learn!
Good luck!
I used the AddForce method, and the idea was to basically take the mouse position and store it in a variable lookDir, then to make an addforce with -lookDir but it turned out very wonky and it didn't work very well, there's the recoil and most of the time it goes to the right direction but sometimes it doesn't and sometimes the recoil is too strong. Here's the code:
using System.Collections; using UnityEngine;
public class PlayerShoot : MonoBehaviour { [Header("Gun Pointing")] public float offset; public bool isFacingLeft; public Vector2 lookDir;
[Header("Gun Shoot")]
public float timeBeforeShooting;
public float reloadTime;
public float timer;
public float recoilForce;
public int maxAmountBullet = 8;
public int bulletsAmount;
public GameObject bullet;
public Transform shootPoint;
public Rigidbody2D rb;
[Header("Reload")]
public bool canShoot;
public bool isReloading;
private void Start()
{
bulletsAmount = maxAmountBullet;
}
private void Update()
{
GunDirection();
timer += Time.deltaTime;
if(bulletsAmount == 0)
{
canShoot = false;
}
else if(bulletsAmount > 0 && !isReloading)
{
canShoot = true;
}
if (Input.GetButtonDown("Fire1") && canShoot && bulletsAmount > 0 && timer > timeBeforeShooting)
{
Shoot();
bulletsAmount--;
timer = 0;
}
if(Input.GetKeyDown(KeyCode.R) && !isReloading && bulletsAmount < maxAmountBullet)
{
StartCoroutine(Reload());
}
}
private void GunDirection()
{
Vector3 difference = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
float rotZ = Mathf.Atan2(difference.y, difference.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(0f, 0f, rotZ + offset);
//Direction of the mouse
lookDir = Camera.main.ScreenToWorldPoint(Input.mousePosition);
if (rotZ > 90 || rotZ < -90)
{
isFacingLeft = true;
}
else
{
isFacingLeft = false;
}
if (isFacingLeft)
{
gameObject.GetComponent<SpriteRenderer>().flipY = true;
}
else
{
gameObject.GetComponent<SpriteRenderer>().flipY = false;
}
}
private void Shoot()
{
Instantiate(bullet, shootPoint.position, transform.rotation);
rb.AddForce(-lookDir * recoilForce, ForceMode2D.Impulse);
}
private IEnumerator Reload()
{
canShoot = false;
isReloading = true;
yield return new WaitForSeconds(reloadTime);
bulletsAmount = maxAmountBullet;
canShoot = true;
isReloading = false;
}
}