I have stumbled upon an issue that I’ve been messing around with over the passed couple days here and there with no success. I have a player character who shoots an instantiated bullet, when it hits the instantiated enemy it is supposed to play out this code
using UnityEngine;
using System.Collections;
public class BulletsDestroy : MonoBehaviour {
public AudioClip hit_power_fist;
public GameObject explosion;
void OnCollisionEnter2D (Collision2D coll) {
if (coll.gameObject.tag == "Enemy")
AudioSource.PlayClipAtPoint (hit_power_fist, transform.position, .2f);
Instantiate (explosion, coll.transform.position, Quaternion.identity);
Destroy(coll.gameObject);
Destroy (gameObject);
}
}
The bullet always destroys the object but only sometimes plays the audio, create the explosion, and destroy itself.
As a side question, I am trying to make the enemy follow the player, I am using code that needs the player character transform location. This would work if the enemy was already in the game but since the enemy is a prefab and I am instantiating it I can’t seem to drag the PC object into the prefab public gameObject variable in my assets.
About your side question:
Your enemy script needs to have a proper initialization. As soon as instantiated it supposed to player = GameObject.FindWithTag("Player") as GameObject
About main question. You want your bullet to play sound and to destroy itself at the same time? Come on, make up your mind.
Maybe put your sound into explosion object or at least freeze your bullet in place, hide it and give some time to play your sound. Destroy(gameObject, timeInSecondsBeforeItsGone)
Not sure it will solve your problem, just some logic into your event.
So you seem to think the issue is that I am destroying the script before it applies all the lines of codes to the game world. I’ve tried your first suggestion and I changed my script to have both objects destroy and OnDestroy to instantiate the explosion but still no luck. I don’t feel very good about the whole freezing the bullet solution because I think there could be a simpler one. Any idea why it works half the time? Is it just based on how much of the script it reads before it’s destroyed?
Also for the second problem I had, your way works but now I have an issue where when the player dies I get a ton of null exception errors, I tried solving it with this
public float speed;
private GameObject player;
void Start (){
if (GameObject.FindWithTag ("Player")) {
player = GameObject.FindWithTag ("Player") as GameObject;
} else
{
player.tag = "notPlayer";
}
}
void FixedUpdate () {
if (player.tag == "Player") {
float z = Mathf.Atan2 ((player.transform.position.y - transform.position.y), (player.transform.position.x - transform.position.x)) * Mathf.Rad2Deg - 90;
transform.eulerAngles = new Vector3 (0, 0, z);
rigidbody2D.AddForce (gameObject.transform.up * speed);
}
}
}
I think you need to put in an exception for when the player has died and tell it to stop trying to move towards the player. Null exception means the object you’re trying to tell it to move to no longer/doesn’t exist (if my logic is right).
That’ll take another if statement that checks for player death.
I didn’t say that. It was just a suggestion to make design more clean and logical.
Your bullet code seems to be ok. Is there any OnCollisionEnter2D on your enemy objects? If so, can we see it? Are all your enemy objects marked with Enemy tag? If not then maybe your bullet code not working at all and enemy dies because of another script?
I have the prefab setup to have the tag Enemy so I think it should always have that tag. There is only one enemy since this is a practice game for the sake of learning.
Thanks for the enemyFollowPlayer script fix, it works perfectly
Edit: To expand there are exactly 3 scripts on the Enemy prefab. EnemyDestroy which destroys the instantiated object within 3 seconds, the EnemyKillsPlayer which is above, and EnemyFollowPlayer, which is what you helped me with. The bullet has .2. one to destroy itself after 2 seconds and the one I posted in the topic head.
Edit2: I just did some testing with restarting the game and shooting the first enemy that spawns over and over. It seems to have nothing to do with spawn order because the first spawn only destroys the bullet and instantiates half the time.
So your problem wasn’t that it didn’t know the player died but that it didn’t know what the reference to player was? I’m still a bit confused. Trying to understand this.
So I removed the script for the bullet and it still destroys, there must be something else going on, going to continue investigating.
Edit: It was the collision script on the enemy which is intended to collide with the player and destroy them both that had been glitching the code. Now I have to figure out what is wrong with that script.
Edit2: I was having a hard time figuring it out until I rewrote it and realized that the if statement was not checking anything, I am still learning the C# syntax and I didn’t know that if you don’t have curly brackets after if and at the end of the if it won’t take in the code. Problem solved, silly mistake. Thanks for all the help I got.