I was working on a small project to learn more about 3D games and was developing a simple shooting system. However, the bullet moves in a random direction even though I’ve specified where it should go in the code. If anyone could help with this problem, I would be grateful
A video of the bug:
Bullet shoot in random Direction
Code:
Gun script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using static UnityEngine.GraphicsBuffer;
using UnityEngine.Pool;
public class Gun : MonoBehaviour
{
public int DefaultCapacity = 8;
public int MaxMagazineSize = 8;
[SerializeField]
private float _forwardForce, _upForce;
[SerializeField]
private float _fireCooldwon;
[SerializeField]
private Transform _fireePoint, _cam;
[SerializeField]
private Bullet _bullet;
RaycastHit hit;
// throw an exception if we try to return an existing item, already in the pool
private bool _collectionCheck = true;
private IObjectPool<Bullet> _objectPool;
private bool _canFire;
private bool _magazineEmpty = false;
private void Awake()
{
_objectPool = new ObjectPool<Bullet>(CreateProjectil, OnGetFromPool, OnReleaseToPool, OnDestroyPooledObject, _collectionCheck, DefaultCapacity, MaxMagazineSize);
}
void Start()
{
_canFire = true;
}
private void Update()
{
CheckMagazine();
}
public void Attack(InputAction.CallbackContext ctx)
{
if (ctx.performed && _canFire && !_magazineEmpty)
{
FireBullet();
}
}
private void FireBullet()
{
_canFire = false;
Vector3 targetDirection;
targetDirection = _cam.forward;
if (Physics.Raycast(_cam.position, _cam.forward, out hit, 500f))
{
targetDirection = hit.point - _fireePoint.position;
}
Vector3 fireDirection;
fireDirection = targetDirection.normalized * _forwardForce + _cam.up * _upForce;
Bullet projectile = _objectPool.Get();
if(projectile == null )
{
return;
}
projectile.transform.position = _fireePoint.position;
Rigidbody bulletRB = projectile.GetComponent<Rigidbody>();
bulletRB.AddForce(fireDirection, ForceMode.Impulse);
ConsumeBullet(1);
projectile.DeactivateBullet();
Invoke(nameof(FireAgain), _fireCooldwon);
}
private void GetFireDirection()
{
}
private void FireAgain()
{
_canFire = true;
}
private void ConsumeBullet(int amount)
{
DefaultCapacity -= amount;
}
public void ReloadMagazine(InputAction.CallbackContext ctx)
{
if (ctx.performed)
{
DefaultCapacity = MaxMagazineSize;
_magazineEmpty = false;
}
}
private void CheckMagazine()
{
if(DefaultCapacity <= 0)
{
_magazineEmpty = true;
}
}
// invoke when creating an item to populate the object pool
private Bullet CreateProjectil()
{
Bullet bulletInstance = Instantiate(_bullet);
bulletInstance.ObjectPool = _objectPool;
return bulletInstance;
}
// invoke when retrieving the next item from the object pool
private void OnGetFromPool(Bullet pooledObject)
{
pooledObject.gameObject.SetActive(true);
}
// invoke when returning an item from the object pool
private void OnReleaseToPool(Bullet pooledObject)
{
pooledObject.gameObject.SetActive(false);
}
private void OnDestroyPooledObject(Bullet pooledObject)
{
Destroy(pooledObject.gameObject);
}
private void OnDrawGizmos()
{
Gizmos.color = Color.red;
if (Physics.Raycast(_cam.position, _cam.forward, out hit, 500f))
Gizmos.DrawLine(_cam.position, hit.point);
}
}
Bullet Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Pool;
public class Bullet : MonoBehaviour
{
[SerializeField]
private float _deactivationTime = 2f;
private Rigidbody _rb;
private bool _hitTarget = false;
internal IObjectPool<Bullet> ObjectPool;
private void Start()
{
_rb = GetComponent<Rigidbody>();
}
private void OnCollisionEnter(Collision collision)
{
if (_hitTarget)
{
return;
}
else
{
_hitTarget = true;
}
_rb.isKinematic = true;
transform.SetParent(collision.transform);
}
public void DeactivateBullet()
{
StartCoroutine(DeactivateRoutine(_deactivationTime));
}
IEnumerator DeactivateRoutine(float delay)
{
yield return new WaitForSeconds(delay);
ObjectPool.Release(this);
}
}