What I'm after in my game is when a collision happens with the player and a planet, for the player to disappear, leaving behind an explosion effect in the form of a particle system. Just afterwards (maybe half a second) I want the "game over" scene to appear in its place. Here's what I have so far:
void OnCollisionEnter2D (Collision2D col) {
if (col.gameObject.tag == "enemyPlanet") {
Instantiate (explosion, thingToMove.transform.position, thingToMove.transform.rotation);
ui.gameOverActivated ();
Destroy (gameObject);
am.rocketBang.Play();
Application.LoadLevel ("gameOverScene2");
}
}
The problem I have is that the particles appear but don't move as they should like an explosion. I guess that's either because the game over scene is loading or because its position is the player (thingToMove) which is being destroyed.
I tried this:
public void Awake() {
DontDestroyOnLoad (transform.gameObject);
}
But the same thing happens. If it's because the player is being destroyed, how would I make it be in the place of the player at the time of it being destroyed?
I hope this makes sense and thanks in advance.
You can use the Invoke method to call the game over after a specified delay.
void OnCollisionEnter2D (Collision2D col) {
if (col.gameObject.tag == "enemyPlanet") {
Instantiate (explosion, thingToMove.transform.position, thingToMove.transform.rotation);
ui.gameOverActivated ();
am.rocketBang.Play();
Invoke( "over", 2.0f );
}
}
void over(){
Destroy (gameObject);
Application.LoadLevel ("gameOverScene2");
}
Related
I have been doing a tutorial for network games using Unity but I am having trouble with the bullet, whenever I include the private void OnCollision thing, the bullet will not initialise if I press space but if I remove it the bullets will be there but I am trying to avoid the arrays of the bullet (clone) when shooting so I want to destroy the bullet. I used the code
//private void OnCollisionEnter(Collision collision)
//{
// Destroy(gameObject);
//}
In my bullet script that I have created, I have had to comment out the lines as whenever I use this and play the game the space button which shoots the bullets don't work at all.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bullet : MonoBehaviour
{
Rigidbody rigidbody;
// Start is called before the first frame update
void Awake()
{
rigidbody = GetComponent<Rigidbody>();
}
public void InitializeBullet(Vector3 originalDirection)
{
transform.forward = originalDirection;
rigidbody.velocity = transform.forward * 18f;
}
//private void OnCollisionEnter(Collision collision)
//{
// Destroy(gameObject);
//}
}
This is probably happening due to OnCollisionEnter function gets triggered when the gameobject collides with something. When you instantiate the bullet it probably collides with the player character itself as that also has a collider, thus instantly destroying itself.
A simple solution would be to check the tag of the collided gameobject to make sure that the bullet collided with something that we want it to. So after setting the enemy prefab to have it's own tag your collision code would look like this:
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "Enemy") //I choosed enemy as the custom tag
{
Destroy(gameObject);
}
}
I figured out what went wrong as #66Gramms talked about the bullet colliding with the player character I had another game object called bullet position where I was suppose to put it in front of the player character but instead I didn't do that, the player and bullet were together colliding smh. So the code I used
private void OnCollisionEnter(Collision collision)
{
Destroy(gameObject);
}
Actually works
So I am taking a class in basic game development and am currently working on a game with Unity. My game worked perfectly up until now when I updated my unity version. In order for the player to actually take damage I have a method that can only be reached if explicitly called by a script. Somehow the ground, that has no script attached, damages my player.
I have posted the code below.
This one is part of the player script
3 references
public void Hurt(int dmg, string yep)
{
HP -= dmg;
Debug.Log($"took {dmg} damage from{yep}. You now have {HP} HP left");
if (HP <= 0)
{
SceneManagement.Death();
}
}
This one is part of the script attatched to my flame object
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag != "FlameTurret" && collision.gameObject.tag != "flame")
{
player.GetComponent<PlayerController>().Hurt(damage, collision.gameObject.tag);
Destroy(this.gameObject);
}
}
This one is attatched to a projectile fired by the enemy
if (collision.gameObject.CompareTag("Player"))
{
if (!called)
{
collision.gameObject.GetComponent<PlayerController>().Hurt(damage, collision.gameObject.tag);
called = true;
}
}
This one is attatched to an enemy
if (collision.gameObject.CompareTag("Player"))
{
if (!called)
{
collision.gameObject.GetComponent<PlayerController>().Hurt(damage, collision.gameObject.tag);
called = true;
}
Destroy(this.gameObject);
}
Console output
Nothing with the tag "Ground" has a script and nothing else than the methods i've posted are supposed to reference my Hurt() method but the ground still damages my player. Any help would be greatly appreciated!
Your problem seems to be that this function here
private void OnCollisionEnter2D(Collision2D collision)
Will be run whenever any collider (game object with a collider component attached - the game object does not need to have any scripts attached to it) intersects with your player
This code here
if (collision.gameObject.tag != "FlameTurret" && collision.gameObject.tag != "flame")
Will pass so long as the object that collides does not have the tag of "FlameTurret" or "flame", which I assume your ground does not.
It seems to me a little odd that everything in your game will damage your player except for flames... is this an error?
Either way a simple fix would be to tag your ground with something like environment and then add under your OnCollisionEnter2D() have a check along the lines of
if (collision.gameObject.tag == "environment"){
return; // do nothing
}
Would like to know if it is possible to destroy an object if not in collision with anything?
When I start the game I generate a grid randomly, on each GridSquare I've made a collider2D. In the editor, I add some objects on this grid manually, with a collider2D too and a rigidbody2D to detect the collision.
I know how to destroy the object if in a collision, what I want is "when the game start, if this object is not in collision with anything, then destroy it"
I've tried to tell unity "if in collision with grid square then destroy object (just for testing), else destroy object"
void OnTriggerEnter2D(Collider2D collision)
{
if (collision.name == "GridSquare")
{
Destroy(gameObject);
}
else {
Destroy(gameObject);
}
}
So actually it destroys well the object when it is on a GridSquare, and it should destroy object if it is not in collision with GridSquare too but apparently not...
private var collisionCount = 0;
void OnCollisionEnter () {
collisionCount++
}
void OnCollisionExit () {
collisionCount--;
}
void checkForCollision(){
if(0 == collisionCount) Destroy(gameObject);
}
If the gameObject is not colliding, OnTriggerEnter2D method wont be activated for that specific gameObject. Bear in mind that method only triggers on collision event.
For that case you might have in your gameObjects a boolean _isColliding which you can change with the OnTriggerEnter2D method to check the ones that are colliding, setting that to true.
bool _isColliding = false;
void OnTriggerEnter2D(Collider2D collision)
{
_isColliding = true;
}
Then you loop through all of the gameObjects and destroy only the ones that have the _isColliding == false.
Hope that helps!
I am new to Unity and C#, I am trying to add a 'wait time' to my death script. So when my Player dies it shows a particle animation and then resets the level, however, at the moment my particles are playing but the level doesn't reset.
public GameObject particles;
public Player_Movement player;
void OnCollisionEnter2D(Collision2D Col)
{
if (Col.collider.tag == "Enemy")
{
Instantiate(particles, transform.position, Quaternion.identity);
Destroy(gameObject);
StartCoroutine("RestartGameCo");
}
}
public IEnumerator RestartGameCo()
{
yield return new WaitForSeconds(0.5f);
SceneManager.LoadScene("Level1");
}
Destroy(gameObject);
StartCoroutine("RestartGameCo");
Your code is fine, but you destroy the gameobject that has this script on it. Which also destroys the script, and stops all the coroutines. So it will never be called.
A solution is to make the object invisible in some way, like disabling the mesh renderer and collider instead of destroying it.
You are actually destroying the gameobject itself before even running the co-routine. It means that the co-routine "RestartGameCo" won't even run. One way to debug these kind of things is using Debug.log messages.
Code:
void OnCollisionEnter2D(Collision2D Col)
{
if (Col.collider.tag == "Enemy")
{
Instantiate(particles, transform.position, Quaternion.identity);
StartCoroutine("RestartGameCo");
}
}
public IEnumerator RestartGameCo()
{
yield return new WaitForSeconds(0.5f);
SceneManager.LoadScene("Level1");
}
Let me know if it helps.
I know a couple options about that. Here's one.
By using the Thread, it will pause your application for the amount of time of your desire. To do so, you need to add using System.Threading; to your the current cs file you are editing. Now simply change your code to that:
void OnCollisionEnter2D(Collision2D Col)
{
Thread.Sleep(5000) // 5000 in milliseconds
if (Col.collider.tag == "Enemy")
{
Instantiate(particles, transform.position, Quaternion.identity);
Destroy(gameObject);
StartCoroutine("RestartGameCo");
}
}
public IEnumerator RestartGameCo()
{
Thread.Sleep(5000)
yield return new WaitForSeconds(0.5f);
SceneManager.LoadScene("Level1");
}
I'm making a 2D sidescrolling game in Unity, and when the player shoots an obstacle, I want the obstacle animation to play and then destroy itself. I got it to destroy itself, but the animation won't play. Any suggestions?
protected Animation obsanim;
// Use this for initialization
void Start () {
obsanim = GetComponent<Animation> ();
}
// Update is called once per frame
void Update () {
}
void OnCollisionEnter2D(Collision2D col)
{
if (col.gameObject.tag == "circle")
{
obsanim.Play ("circobs");
Destroy (gameObject, 1.0f);
}
}
}
Thank you for any help!
Sounds good to me, assuming of course that the animation doesn't last more than 1 second. You could use animation["circobs"].length to figure out when you need to destroy.
Maybe the animation you're playing is in a lower layer than the current one?