- Home /
Shooting in direction of the character movement
Hello,
I am fairly new to Unity, I have a question regarding shooting bullets in the direction that the sprite is moving. I have looked at the following 2 tutorials:
https://www.youtube.com/watch?v=8uD2ATIot0A
https://www.youtube.com/watch?v=1mw1ufZq1N4&t=111s
while both come close to a solution, I can't seem to figure out the best way to achieve the desired effect. Both of the tutorial above use either a cursor to aim and shoot or directional keys to rotate the sprite.
I need the sprite to be able to move in 8 directions with animations using the arrows keys and using the Fire1 button to shoot a bullet. I do not know how to get the bullet to travel in the direction the sprite is moving at the time it is fired.
Any help or directions is much appreciated.
Thanks
Answer by Magso · Nov 23, 2019 at 01:53 AM
It depends on how you are moving the bullets. Using Translate()
or AddForce(transform.up)
the bullet can be instantiated to the same rotation as the player. Using AddForce(Vector2)
the bullet needs the global values depending on which way the player is facing. e.g.
if(player.GetComponent<SpriteRenderer>().sprite.texture == facingRightTexture)
{
bullet.GetComponent<bulletScript>().addForceVector2Variable = Vector2.right * speed;
}
and on the bullet
GetComponent<Rigidbody2D>().AddForce(addForceVector2Variable, ForceMode2D.Impulse);
@$$anonymous$$agso Thank you for replying so quick.
Here are the functions I am using to move the character
void ProcessInputs()
{
movementDirection = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
movementSpeed = $$anonymous$$athf.Clamp(movementDirection.magnitude, 0.0f, 1.0f);
movementDirection.Normalize();
}
void $$anonymous$$ove()
{
player.velocity = movementDirection * movementSpeed * speed;
}
I am using animations to give the appearance of the character changing direction. The problem is I need the bullet to travel in the direction the character is facing. Like I mentioned above the tutorials are using rotation or a pointer to make the projectile travel in the direction of the rotated GameObject (sprite). I was thinking of using a child Object and rotating that in the direction of the inputs/character but I can't seem to get that working either.
Here is the script that I used from one of the tutorials above.
public float bulletSpeed = 8.0f;
// Update is called once per frame
void Update()
{
Vector3 pos = transform.position;
Vector3 velocity = new Vector3(0, bulletSpeed * Time.deltaTime, 0);
pos += transform.rotation * velocity;
transform.position = pos;
}
Any help is appreciated.
You need a way to check the direction the player is facing, in this case probably the sprite's texture. You can change Vector3 velocity = new Vector3(0, bulletSpeed * Time.deltaTime, 0) to AddForce(transform.up, Force$$anonymous$$ode2D.Impulse) and set the rotation to 0, 45, 90, etc by checking the sprite texture. Here's another e.g. I probably should've put in my original answer.
void FixedUpdate()
{
GetComponent<Rigidbody2D>().AddForce(transform.up, Force$$anonymous$$ode2D.Impulse);
if(player.GetComponent<SpriteRenderer>().sprite.texture == facingRightTexture)
{
transform.eulerAngles.z = 90;
}
}
Answer by vbjack72 · Nov 25, 2019 at 06:36 PM
Hello @Magso
Based on your feedback, I used the animator to get the direction of the character. using that direction I was able to apply the correct rotation and offset to the bullet object to get the desired effect. Below is the code that I am using to do this.
private void Update()
{
cooldownTimer -= Time.deltaTime;
if (Input.GetButton("Fire1") && cooldownTimer <= 0)
{
// Debug.Log("Pew!");
// Shoot the gun
cooldownTimer = fireDelay;
int shotRotDeg = 180;
int aniHor = (int)Math.Round(animator.GetFloat("Horizontal"));
int aniVer = (int)Math.Round(animator.GetFloat("Vertical"));
float offsetX = -0.14f;
float offsetY = -0.4f;
// Down 0, -1
if (aniHor == 0 && aniVer == -1)
{
shotRotDeg = 180;
offsetX = -0.14f;
offsetY = -0.4f;
}
// DownRight 1, -1
else if (aniHor == 1 && aniVer == -1){
shotRotDeg = 225;
offsetX = 0.55f;
offsetY = -0.1f;
}
// Right 1, 0
else if (aniHor == 1 && aniVer == 0)
{
shotRotDeg = 270;
offsetX = 0.55f;
offsetY = 0.12f;
}
// UpRight 1, 1
else if (aniHor == 1 && aniVer == 1)
{
shotRotDeg = 315;
offsetX = 0.4f;
offsetY = 0.5f;
}
// Up 0, 1
else if (aniHor == 0 && aniVer == 1)
{
shotRotDeg = 0;
offsetX = 0.25f;
offsetY = 0.5f;
}
// UpLeft -1, 1
else if (aniHor == -1 && aniVer == 1)
{
shotRotDeg = 45;
offsetX = -0.4f;
offsetY = 0.5f;
}
// Left -1, 0
else if (aniHor == -1 && aniVer == 0)
{
shotRotDeg = 90;
offsetX = -0.55f;
offsetY = 0.12f;
}
// DownLeft -1, -1
else if(aniHor == -1 && aniVer == -1)
{
shotRotDeg = 135;
offsetX = -0.55f;
offsetY = -0.1f;
}
// Vector2 shootingDirection = gun.transform.localPosition;
Vector3 offset = new Vector3(offsetX, offsetY, 0);
// shootingDirection.Normalize();
shootingDirectionX = animator.GetFloat("Horizontal"); //shootingDirection.x;
shootingDirectionY = animator.GetFloat("Vertical"); // shootingDirection.y;
GameObject bullet = Instantiate(bulletPrefab, player.transform.position + offset, Quaternion.identity);
bullet.transform.Rotate(0, 0, shotRotDeg); // Mathf.Atan2(shootingDirection.y, shootingDirection.x) * Mathf.Rad2Deg);
}
I am not sure if this is the best way to go about this, but for now it is working and I can start looking in to other parts of the game. Thank you so much for your help and guidance, it really helped me out.