I’ve added bullet impacts into my fps game but I’ve encountered a bug. Because of bullet spread that I have on my gun, sometimes the bullet impacts go over the edge.
How do I fix this?
heres my shooting code:
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using System.Collections;
public class Gun : MonoBehaviour
{
[Header("Choose Gun")]
public bool isRifle;
public bool isPistol;
public bool isSniper;
[Header("Score")]
public ScoreCounter scoreCounter;
public float _shotsFired;
public float _shotsHit;
[Header("Damage and Stuff")]
public Image hitmarkerImage;
public float hitmarkerWait;
public float damage = 10f;
public float range = 100f;
public float spreadFactor;
public float aimedSpreadFactor;
float spreadFactorStore;
[Header("Cooldowns, Ammo, Reloading")]
public float gunCooldown;
public int maxAmmo;
public float reloadTime;
public GameObject reloadText;
int currentAmmo;
float cooldown;
bool isReloading = false;
bool canShoot;
[Header("Aiming References")]
public Transform rifle;
public Transform pistolHolder;
public Transform sniperHolder;
public Transform rifleAimPos;
public Transform pistolAimPos;
public Transform sniperAimPos;
public Transform rifleStore;
public Transform pistolHolderStore;
public Transform sniperHolderStore;
bool isAiming;
public GameObject sniperModel;
[Header("Miscellaneous")]
public ParticleSystem hitImpact;
public Animator animator;
public TMP_Text ammoCount;
public PlayerLook playerLook;
public Camera fpsCam;
public Color CLEARWHITE = new Color(1, 1, 1, 0);
public Recoil recoilManager;
public GameObject bulletHole;
void Start()
{
hitmarkerImage.color = CLEARWHITE;
currentAmmo = maxAmmo;
spreadFactorStore = spreadFactor;
}
void OnEnable()
{
isReloading = false;
animator.SetBool("Reloading", false);
}
void Update()
{
BasicSetup();
ChooseGun();
Aim();
HitmarkerSetup();
ammoCount.text = currentAmmo + "/" + maxAmmo;
}
IEnumerator Reload()
{
isReloading = true;
Debug.Log("Reloading");
hitmarkerImage.color = CLEARWHITE;
animator.SetBool("Reloading", true);
yield return new WaitForSeconds(reloadTime - .1f);
animator.SetBool("Reloading", false);
yield return new WaitForSeconds(.1f);
currentAmmo = maxAmmo;
isReloading = false;
}
void Shoot()
{
scoreCounter.shotsFired += 1;
currentAmmo = currentAmmo - 1;
RaycastHit hit;
Vector3 shootDirection = fpsCam.transform.forward;
shootDirection = shootDirection + fpsCam.transform.TransformDirection
(new Vector3(Random.Range(-spreadFactor, spreadFactor), Random.Range(-spreadFactor, spreadFactor)));
//shootDirection.x += Random.Range(-spreadFactor, spreadFactor);
//shootDirection.y += Random.Range(-spreadFactor, spreadFactor);
if(Physics.Raycast(fpsCam.transform.position, shootDirection, out hit, range))
{
Debug.Log("You hit " + hit.transform.name);
hitmarkerImage.color = Color.white;
ParticleSystem hitImpactPrefab = Instantiate(hitImpact, hit.transform.position, hit.transform.rotation);
GameObject bH = Instantiate(bulletHole, hit.point + new Vector3(0f, 0f, -0.032f), Quaternion.LookRotation(-hit.normal));
bH.transform.SetParent(hit.transform);
Destroy(bH, 5f);
Destroy(hitImpactPrefab.gameObject, 1f);
scoreCounter.shotsHit += 1;
}
}
void ChooseGun()
{
if(isRifle)
{
if(Input.GetButton("Fire1"))
{
if(cooldown <= 0)
{
if(canShoot)
{
cooldown = gunCooldown;
Shoot();
recoilManager.Fire();
}
}
}
}
if(isSniper)
{
if(Input.GetButtonDown("Fire1"))
{
if(cooldown <= 0)
{
if(canShoot)
{
cooldown = gunCooldown;
Shoot();
Debug.Log("Playing sniper animation");
animator.SetBool("SniperShot", true);
}
}
}
}
if(isPistol)
{
if(Input.GetButtonDown("Fire1"))
{
if(cooldown <= 0)
{
if(canShoot)
{
cooldown = gunCooldown;
Shoot();
animator.SetBool("PistolShot", true);
}
}
}
}
}
void BasicSetup()
{
if((currentAmmo > 0) && !isReloading)
canShoot = true;
if(isReloading)
{
reloadText.SetActive(true);
return;
}
if(cooldown > 0)
{
canShoot = false;
cooldown -= Time.deltaTime;
if(isPistol)
animator.SetBool("PistolShot", false);
if(isSniper)
animator.SetBool("SniperShot", false);
canShoot = true;
}
if(currentAmmo <= 0)
{
StartCoroutine(Reload());
return;
}
if(Input.GetKeyDown(KeyCode.R) && currentAmmo < maxAmmo)
{
StartCoroutine(Reload());
}
if(!isReloading && !isAiming)
{
rifle.position = Vector3.Lerp(rifle.position, rifleStore.position, 2.5f * Time.deltaTime);
pistolHolder.position = Vector3.Lerp(pistolHolder.position, pistolHolderStore.position, 2.5f * Time.deltaTime);
sniperHolder.position = Vector3.Lerp(sniperHolder.position, sniperHolderStore.position, 2.5f * Time.deltaTime);
}
if(!isReloading && isAiming)
{
rifle.position = Vector3.Lerp(rifle.position, rifleAimPos.position, 2.5f * Time.deltaTime);
pistolHolder.position = Vector3.Lerp(pistolHolder.position, pistolAimPos.position, 2.5f * Time.deltaTime);
sniperHolder.position = Vector3.Lerp(sniperHolder.position, sniperAimPos.position, 2.5f * Time.deltaTime);
}
if(isReloading)
reloadText.SetActive(true);
if(!isReloading)
{
reloadText.SetActive(false);
}
}
void HitmarkerSetup()
{
if(hitmarkerWait > 0)
{
hitmarkerWait -= Time.deltaTime;
}
else if(hitmarkerImage.color.a > 0)
{
hitmarkerImage.color = Color.Lerp(hitmarkerImage.color, CLEARWHITE, Time.deltaTime * 10f);
}
}
void Aim()
{
if(Input.GetMouseButtonDown(1))
{
if(isReloading)
AimOut();
AimIn();
}
else if(Input.GetMouseButtonUp(1))
{
AimOut();
}
}
void AimIn()
{
spreadFactor = aimedSpreadFactor;
if(isSniper)
{
fpsCam.fieldOfView = 30f;
playerLook.mouseSensitivity = 30f;
sniperModel.SetActive(false);
sniperHolder.position = sniperAimPos.position;
if(isReloading)
{
fpsCam.fieldOfView = 70f;
playerLook.mouseSensitivity = 100f;
rifle.position = rifleStore.position;
pistolHolder.position = pistolHolderStore.position;
sniperModel.SetActive(true);
sniperHolder.position = sniperHolderStore.position;
isAiming = false;
}
}
else
{
fpsCam.fieldOfView = 55f;
playerLook.mouseSensitivity = 50f;
rifle.position = rifleAimPos.position;
pistolHolder.position = pistolAimPos.position;
}
isAiming = true;
}
void AimOut()
{
spreadFactor = spreadFactorStore;
fpsCam.fieldOfView = 70f;
playerLook.mouseSensitivity = 100f;
rifle.position = rifleStore.position;
pistolHolder.position = pistolHolderStore.position;
sniperModel.SetActive(true);
sniperHolder.position = sniperHolderStore.position;
isAiming = false;
}
}
Its really annoying. Ive shortened the colliders of the target so it wont go over while aiming but the bullet spread still makes this annoying bug