The script should let the player shoot bullets either manual or automatic by pressing the mouse left button for single shot and right mouse button for automatic fire.
The problems :
-
In my scene i have one object tagged with “Fire Point” but in the method GatherAllChilds it’s finding two objects and in fact it’s the same object tagged with “Fire Point” he is adding the object to the List firePoints.
-
It should not adding twice the “Fire Point” object but even if it does adding it twice why they are both have a different positions ? shouldn’t they have the same position ? I used a break point and when the variable ‘i’ is 5 it’s adding the “Fire Point” twice in a row same number 5 object and yet they are in a different positions.
The result is when the player is shooting there is two places the bullets are coming from instead one.
The script Instantiate two clones of the bullet prefab in the method LaunchProjectile lines 70 to 73.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Shooting : MonoBehaviour
{
[Header("Main")]
public Rigidbody bulletPrefab;
public float launchForce = 700f;
public bool automaticFire = false;
public float bulletDestructionTime;
[Space(5)]
[Header("Slow Down")]
public float maxDrag;
public float bulletSpeed;
public bool bulletsSlowDown = false;
public bool overAllSlowdown = false;
[Range(0, 1f)]
public float slowdownAll = 1f;
private List<Transform> firePoints = new List<Transform>();
private Animator anim;
private void Start()
{
GatherAllChilds(transform);
anim = GetComponent<Animator>();
}
public void Update()
{
if (overAllSlowdown == true)
{
Time.timeScale = slowdownAll;
}
if (firePoints.Count > 0 && anim != null)
{
for (int i = 0; i < firePoints.Count; i++)
{
if (Input.GetButtonDown("Fire1") && automaticFire == false && IKControl.handRaised)
{
LaunchProjectile(firePoints[i]);
}
else if (Input.GetButtonDown("Fire1") && automaticFire == true)
{
automaticFire = false;
}
else
{
if (Input.GetButtonDown("Fire2") && IKControl.handRaised)
{
automaticFire = true;
}
if (automaticFire == true && IKControl.handRaised)
{
LaunchProjectile(firePoints[i]);
}
}
}
}
}
private void LaunchProjectile(Transform firePoint)
{
Rigidbody projectileInstance = Instantiate(
bulletPrefab,
firePoint.position,
firePoint.rotation);
projectileInstance.AddForce(new Vector3(0, 0, 1) * launchForce);
if (bulletsSlowDown == true)
{
if (projectileInstance != null)
{
StartCoroutine(AddDrag(maxDrag, bulletSpeed, projectileInstance));
}
}
if ((automaticFire == true || automaticFire == false) && bulletsSlowDown == false)
{
projectileInstance.gameObject.AddComponent<BulletDestruction>().destructionTime = bulletDestructionTime;
projectileInstance.gameObject.GetComponent<BulletDestruction>().Init();
}
}
IEnumerator AddDrag(float maxDrag, float bulletSpeed, Rigidbody rb)
{
if (rb != null)
{
float current_drag = 0;
while (current_drag < maxDrag)
{
current_drag += Time.deltaTime * bulletSpeed;
rb.drag = current_drag;
yield return null;
}
rb.velocity = Vector3.zero;
rb.angularVelocity = Vector3.zero;
rb.drag = 0;
rb.gameObject.AddComponent<BulletDestruction>().destructionTime = bulletDestructionTime;
rb.gameObject.GetComponent<BulletDestruction>().Init();
}
}
private void GatherAllChilds(Transform parent)
{
for (int i = 0; i < parent.childCount; i++)
{
if (parent.GetChild(i).name == "Player")
{
anim = parent.GetChild(i).GetComponent<Animator>();
}
if (parent.GetChild(i).tag == "Fire Point")
{
firePoints.Add(parent.GetChild(i));
}
GatherAllChilds(parent.GetChild(i));
}
}
}
And the class BulletDestruction
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BulletDestruction : MonoBehaviour
{
public float destructionTime;
// Start is called before the first frame update
public void Init()
{
StartCoroutine(DestroyBullet());
}
IEnumerator DestroyBullet()
{
yield return new WaitForSeconds(destructionTime);
Destroy(gameObject);
}
}
Screenshot image showing the Fire Point object found twice with different positions