- Home /
The question is answered, right answer was accepted
gameObject.SetActive(false) doesn't work with bullet movement
Hello everyone, I'm a beginner and the answer to this is probably easy and I'm being dumb. Anyway, I'm moving my bullet with AddForce on the start method to move it when it's spawned.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bullet : MonoBehaviour
{
public Rigidbody rb;
public GameObject impactEffect;
public float speed = 1000F;
public int damage = 5;
public static int bulletDamage;
private ObjectPool objectPool;
void Start()
{
bulletDamage = damage;
objectPool = FindObjectOfType<ObjectPool>();
rb = GetComponent<Rigidbody>();
rb.AddForce(transform.forward * speed * 100 * Time.deltaTime);
}
private void Update()
{
}
}
But if I add this to it at the bottom:
public void OnTriggerEnter(Collider collider)
{
GameObject newEffect = objectPool.GetObject(impactEffect);
newEffect.transform.position = transform.position;
newEffect.transform.rotation = transform.rotation;
gameObject.SetActive(false);
}
It doesn't work. The thing above the SetActive is just something that spawns an impact effect when it hits a trigger and that works, the problem is that when I add it my bullet doesn't move the way I want it to.
The game I'm working on is a Tower Defence game and the bullet is coming out of a turret and it shoots straight to the enemy if I don't add the SetActive, but If I do add it the bullet just hits the ground in one spot.
I'll give the turret code in case that's relevant:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Turret : MonoBehaviour
{
[Header("Target Tag")]
// Public
public string alienTag = "Alien";
[Header("Rotation")]
// Public
public Transform rotationPoint;
public float rotationSpeed = 10F;
[Header("Shooting")]
// Public
public LayerMask layerMask;
public GameObject bulletPrefab;
public string bulletTag;
public Transform firePoint;
public float range = 50F;
[Header("Ammo & Bullet Parameters")]
// Public
public float fireRate = 1F;
public int maxAmmo = 15;
public float reloadTime = 5F;
// Private
private int currentAmmo;
private bool isReloading = false;
// Private variables
private ObjectPool objectPool;
private Transform target;
private float fireCountDown = 0F;
void Start()
{
objectPool = FindObjectOfType<ObjectPool>();
currentAmmo = maxAmmo;
InvokeRepeating("UpdateTarget", 0F, 0.5F);
}
private void OnEnable()
{
isReloading = false;
}
void UpdateTarget()
{
GameObject[] aliens = GameObject.FindGameObjectsWithTag(alienTag);
float shortestDistance = Mathf.Infinity;
GameObject nearestAlien = null;
foreach (GameObject alien in aliens)
{
float distanceToAlien = Vector3.Distance(transform.position, alien.transform.position);
if(distanceToAlien < shortestDistance)
{
shortestDistance = distanceToAlien;
nearestAlien = alien;
}
}
if(nearestAlien != null && shortestDistance <= range)
{
target = nearestAlien.transform;
} else
{
target = null;
}
}
void Update()
{
Ray ray = new Ray(firePoint.position, firePoint.forward);
RaycastHit hit;
if(Physics.Raycast(ray, out hit, range, layerMask))
{
Debug.DrawLine(firePoint.position, hit.point, Color.green);
Debug.Log("Target found");
if (fireCountDown <= 0F)
{
Shoot();
fireCountDown = 1F / fireRate;
}
fireCountDown -= Time.deltaTime;
}
else
{
Debug.DrawLine(firePoint.position, hit.point + ray.direction, Color.red);
}
if (isReloading)
{
return;
}
if(currentAmmo <= 0)
{
StartCoroutine(Reload());
return;
}
if(target == null)
{
return;
}
Vector3 targetDir = target.position - rotationPoint.position;
Quaternion lookRotation = Quaternion.LookRotation(targetDir);
rotationPoint.rotation = Quaternion.Lerp(rotationPoint.rotation, lookRotation, Time.deltaTime * rotationSpeed);
}
public void Shoot()
{
currentAmmo--;
Debug.Log("Shoot");
GameObject newBullet = objectPool.GetObject(bulletPrefab);
newBullet.transform.position = firePoint.transform.position;
newBullet.transform.rotation = firePoint.transform.rotation;
}
IEnumerator Reload()
{
isReloading = true;
Debug.Log("Reloading...");
yield return new WaitForSeconds(reloadTime);
currentAmmo = maxAmmo;
isReloading = false;
}
public void OnTriggerEnter(Collider collider)
{
if(collider.CompareTag("Bullet"))
{
}
}
private void OnDrawGizmos()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, range);
}
}
Any help is appreciated.
Answer by privatecontractor · Feb 05 at 06:25 PM
Hi @Minigeek0105,
Check few things:
(1) You need to be sure that RigidBody Component attached to your Bullet GameObject is not marked as "isKinematic"... so physica could affect it in normal way.
(2) Cut off empty void Update() form Bullet script. As long as selected ForceMode selected in RigidBody.AddForce is not continuous added force we not need Update / fixedUpdate...
(3) on Bullet script add:
public void ShootBullet(Vector3 _endOfMuzzlePosition, Quaternion _innitialRotation)
{
this.transform.positon = _endOfMuzzlePosition;
this.transform.rotation = _innitialRotation;
//if using pool system, here reaactivate all of atached components, awake RigidBody, turn on MeshRenders, Turn on ParticleSystem, and start emitting etc...
rb.AddForce(transform.forward * speed * 100, ForceMode.Impulse); //as you see no need to Time.deltaTime which is used only in Update/FixedUpdate.
}
then you could call it directly after grabbing Bullet from Pool.... also consider no need for having pool of GameObjects, you could have use Pool of Bullets, so you will be able to acces directly void ShootBullet().
(4) this 'public void OnTriggerEnter(Collider collider)' void is about what will hapend when your Bullet hit something, don't hav anything to do with bullet movement.
@privatecontractor Hey thanks for replying! I've tried to implement the code you've given me but the way my objectPool doesn't allow me to set it as an array of Bullet scripts cause the objectPool is used by other things that need it to be an array of GameObjects.
Yes I am aware that OnTriggerEnter shouldn't affect the movement of the bullet but it is for some reason, well actually the OnTriggerEnter isn't affecting it, but the SetActive(false) is totally breaking it. Here's a video to show what I mean.
Hi @Minigeek0105,
so as i watched your video few times - even get back to monitor instead of smartphone: Now issue is that Alien's aren't destroyed after received hit if gameObject.SetActive(false);, and bullet fly constantly till end of know world, right?
believe we could make two ways to try to solve this:
1 way delay before gameObject.SetActive(false); so instead of calling: gameObject.SetActive(false); try to add:
WaitForSecondsRealtime m_waitForSecondsRealtime = new WaitForSecondsRealtime(.1f);
IEnumerator DisableBulletAfterHitingAlien()
{
yield return m_waitForSecondsRealtime;
gameObject.SetActive(false);
}
And then, just call
StartCoorutine(DisableBulletAfterHitingAlien());
Maybe this will be enough, alternate:
2 way just tell me is this "Alien 01" (02/03..) detecting collision with bullet on his own?
If yes try to change this in script, for version on which bullet will check with what collide, firstly will try to check TAG, then will tryGetComponent.... and if success will hurt it/destroy it....
public void OnTriggerEnter(Collider collider)
{
if (collider.CompareTag("Enemy"))
{
collider.gameObject.TryGetComponent<SomeComponentOnAlineOnWhichYouWillCall_ToDamage_OrToDestroy>().Damage(1);
}
GameObject newEffect = objectPool.GetObject(impactEffect);
newEffect.transform.position = transform.position;
newEffect.transform.rotation = transform.rotation;
gameObject.SetActive(false);
}
So you will be sure, that bullet is setting to false, after calling Damage/Destroy on Alien...
the way my objectPool doesn't allow me to set it as an array of Bullet scripts cause the objectPool is used by other things that need it to be an array of GameObjects.
ok, you got this, .... you have many object pooled (believe I see that you also pooling particlesystem) nice that you thinking about GC. GJ, let me know did it help.
Hey sorry for leaving for a while. So I've decided to not use object pooling at least for the moment because I had many problems and the tutorials that I found aren't really helping me that much.
So the bullet movement is working which is good and I'll see what I can do about the object pooling in the future. Thanks for all the help!