1
\$\begingroup\$

I’m developing a 2D top down shooter where the player has a pistol. However, I've noticed that when enemies get too close, the player can't shoot them because the pistol doesn't have a collider.

I want to ensure that the player can shoot enemies even when they are very close without changing the game dynamics too much. Should I add a collider to the pistol, or is there a better way to handle this situation?

What are some effective methods to solve this problem? Any advice or sample code would be greatly appreciated!


The issue is that the fire point is far from the player, as the gun is quite big. I'm not sure what is usually done in this case, as I don't use auto fire and some enemies cause the player damage with collision.

--

First, here is my gun aiming script, which controls how the gun aims at the mouse position. The gun will aim towards the mouse unless the mouse is too close to the player (within a minimum aiming distance). I use Unity's Camera.main to get the camera, then convert the mouse position from screen coordinates to world coordinates. After calculating the direction from the player to the mouse, I use trigonometry to rotate the gun towards that direction.

Additionally, I adjust the gun's scale on the y-axis to flip it, depending on the angle of the aim, so that the gun faces the correct direction when aiming behind the player.

using UnityEngine; public class GunAiming : MonoBehaviour { [SerializeField] private Transform gun; [SerializeField] private float minAimDistance = 1.0f; private Camera theCam; private void Start() { theCam = Camera.main; } void Update() { AimAtMouse(); } public void AimAtMouse() { Vector3 mousePos = Input.mousePosition; mousePos.z = Mathf.Abs(theCam.transform.position.z); Vector3 worldMousePos = theCam.ScreenToWorldPoint(mousePos); worldMousePos.z = 0f; Vector3 direction = worldMousePos - transform.position; if (direction.magnitude < minAimDistance) { return; } float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg; gun.eulerAngles = new Vector3(0, 0, angle); Vector3 localScale = Vector3.one; if (angle > 90 || angle < -90) { localScale.y = -1f; } else { localScale.y = +1f; } gun.localScale = localScale; } } 

I handle shooting in a separate script. When the player clicks the left mouse button (Input.GetMouseButton(0)), it checks if the weapon can shoot (not reloading, game not paused, and cooldown is over). If everything is ready, it fires the gun, triggers the OnShoot event, and updates the last shot time.

 protected override void HandleShooting() { if (Input.GetMouseButton(0) && !isReloading && !LevelManager.instance.isPaused) { if (CanShoot() && Time.time >= lastShotTime + timeBetweenShots) { isShooting = true; OnShoot?.Invoke(); Shoot(); lastShotTime = Time.time; } } else { isShooting = false; } } protected virtual void FireBullet() { WeaponStats currenStats = stats[weaponLevel]; int bulletsToFire = currenStats.bulletsToFire; AudioManager.instance.PlaySFXPitch(5); for (int i = 0; i < bulletsToFire; i++) { PlayerBullet bullet = bulletPool.Get(); bullet.transform.position = firePoint.position + currentFirePointOffset; float angle = (i - (bulletsToFire - 1) / 2.0f) * currenStats.sprayRange; bullet.transform.rotation = firePoint.rotation * Quaternion.Euler(0, 0, angle); bullet.SetBulletSize(currenStats.bulletSize); ApplyStatsToBullet(bullet); } } 

Image of how it looks when an enemy gets too close:

Enemy too close to player

\$\endgroup\$
5
  • 3
    \$\begingroup\$ It's not clear from your question why "the pistol not having a collider" would lead to this. Perhaps the actual problem is that the projectiles spawn a certain distance from the player, so when the enemy is very close, the projectiles spawn behind them? You can reply to this message. \$\endgroup\$ Commented Sep 24, 2024 at 10:59
  • \$\begingroup\$ Yes exactly, the fire point is far from the player, as the gun is quite big. So not sure what is usually done in this cases, as I don't use auto fire and some enemies make the player damage with collision. Thanks for answering!! – \$\endgroup\$ Commented Sep 24, 2024 at 14:38
  • \$\begingroup\$ Giving a collider to the gun can cause some other problems and/ or bugs like the plazer could potentially use the weapon to push himself away from enemies without taking dmg. \$\endgroup\$ Commented Sep 24, 2024 at 16:47
  • \$\begingroup\$ Where is currentFirePointOffset assigned a value? \$\endgroup\$ Commented Sep 25, 2024 at 1:22
  • \$\begingroup\$ I added the currentFirePointOffset as a test because my bullets weren't hitting the exact mouse position, but I've since fixed the issue in a better way and now need to remove the offset. \$\endgroup\$ Commented Sep 25, 2024 at 8:26

1 Answer 1

1
\$\begingroup\$

I would cheat a bit here and spawn the bullets not at the muzzle of the gun but in the back of it. Or in other words, move the firePoint from the muzzle of the gun to the receiver. That way it will have more distance to travel and won't spawn behind the collider of a nearby enemy. If this causes visual problems with the bullet appearing behind the muzzle, I would spawn them with the SpriteRenderer disabled, and enable it after the bullet traveled a certain distance.

Or as an alternative thinking-outside-the-box solution: Declare the bug a feature. When the enemy is too close to shoot it, have the player-character perform a melee attack instead.

\$\endgroup\$
3
  • \$\begingroup\$ Re: melee attack, I was going to suggest something similar. Have the firing routine first check if there's an enemy collider overlapping the weapon (using e.g. an OverlapBox query). If so, damage/knock back that enemy instead of or in addition to firing a projectile at all. Treat it as the enemy getting whacked by the barrel itself / the blast from the muzzle. \$\endgroup\$ Commented Sep 26, 2024 at 15:47
  • \$\begingroup\$ Great, it really works..I moved the firepoint and added a fade-in effect to the bullet using DoTween, and it works perfectly. Additionally, if an enemy touches the player, they get knocked back. I’d love to add a melee attack, but that would complicate things further and don't have much time to finish it. Really appreciate the feedback, I take the idea of declaring bugs features. Thank you both! \$\endgroup\$ Commented Sep 27, 2024 at 17:30
  • \$\begingroup\$ @JavierTriviño If this answer answered your question, please accept it by clicking the checkmark-icon next to it. That way the system will register the question as answered. \$\endgroup\$ Commented Sep 28, 2024 at 11:50

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.