Change other script's variable and destroy GameObject Unity c# - c#

In my platform game I have just added some checkpoints, so that if the player dies doesn't necessarily spawn at the beginning of the track.
ghfdghdggfhfg
using UnityEngine;
public class CheckPoints : MonoBehaviour
{
[SerializeField] private Grounded game;
void Update()
{
transform.Rotate(0, 0, 5);
}
private void OnTriggerEnter() {
game.updatedCheckPointPosition = transform.position;
Destroy(this);
}
}
What I unsuccessfully tried to do is to set the public float variable of the Grounded script to the current position of the CheckPoint itself, which should be destroyed after doing that.
Any information or help on how to do this is really appreciated.

From Destroy
The object obj will be destroyed now or if a time is specified t seconds from now.
If obj is a Component it will remove the component from the GameObject and destroy it. [But keep the rest of the GameObject intact!]
If obj is a GameObject it will destroy the GameObject, all its components and all transform children of the GameObject.
this refers to the according component instance. What you want is rather
Destroy(gameObject);
OnTriggerEnter requires a parameter of type Collider in order to work
private void OnTriggerEnter(Collider other)
{
game.updatedCheckPointPosition = transform.position;
Destroy(this);
}
Note however that this way round the player has to be a trigger while the checkpoint a non-trigger! I would actually rather do it the other way round and make the chackpoint a trigger and rather let the player object check for OnTriggerEnter.

Related

How to avoid getting out of position when colliding with another GameObject?

In my Unity game I have some moving objects. There are some collectables ( triggers ) and whenever a moving object enters its trigger the collectable should
Replace itself with a moving object
Destroy itself
Unfortunately the current moving object collides with the new spawned moving object so it will be out of position ( very little ). I would like to avoid that, so one piece connects smoothly to the other one.
For reproduction purposes:
Moving
Create a cube GameObject
Add a Rigidbody component but disable the usage of gravity
Attach the following script to it
.
public class MoveForwardBehaviour : MonoBehaviour
{
private void FixedUpdate()
{
GetComponent<Rigidbody>().velocity = Vector3.forward; // just for testing purposes
}
}
Make this GameObject a prefab
Collectable
Create a cube GameObject
Add a Rigidbody component but disable the usage of gravity
Enable the collider trigger and modify the following values
Attach the following script to it
.
public class Collectable : MonoBehaviour
{
[SerializeField] private GameObject movingPrefab;
private void OnTriggerEnter(Collider other)
{
GetComponent<Collider>().enabled = false;
Instantiate(movingPrefab, transform.position, transform.rotation);
Destroy(gameObject);
}
}
Assign the moving prefab to the script
Make this GameObject a prefab
Now setup a sample scene like so
and start the game. After creating a new moving prefab you can see that the initial moving prefab is not in position anymore
I think this is because of the collision with the new instantiated prefab. Do you have any suggestions how to avoid this?

Respawn AI after destroy

I'm new, and I've got hard time to respawn my AI (right now he just a cube that follow my player) after he been destroy. I believe its because the script sits on the object that get destroyed. but what I need to do to respawn it?
(although I'm sure my respawn code is not good :\ (It's mobile-android project) )
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyTesting : MonoBehaviour
{
[SerializeField]
public GameObject player;
public GameObject enemy;
private Rigidbody body;
Vector3 accelerationDir;
// Use this for initialization
void Start()
{
body = GetComponent<Rigidbody>();
}
private void Update()
{
accelerationDir = Input.acceleration;
if (accelerationDir.sqrMagnitude>=5)
{
EnemyDead();
}
}
void EnemyDead()
{
Destroy(enemy);
Invoke("Respawn", 5);
}
void Respawn()
{
enemy = (GameObject)Instantiate(enemy);
enemy.transform.position = transform.position;
}
// Update is called once per frame
void FixedUpdate()
{
Vector3 toTarget = player.transform.position - transform.position;
float speed = 1.5f;
transform.Translate(toTarget * speed * Time.deltaTime);
}
}
Thanks very much!
I am supposing that your enemy GameObject is inside the scene holding your EnemyTesting MonoBehaviour instance (correct me if I'm wrong).
If this is the case, you cannot instantiate a gameObject that is destroyed.
As #derHugo pointed out, you should not use Destroy and Instantiate for your use case. It would be better to set inactive the enemy GameObject, move it to the position that you want, an (re)set it active. It will look like the enemy respawned.
If you want to dig the subject later, look at the object pooling game optimization pattern.
Otherwise, if you still want to use Instantiate for respawning, I would create a prefab of your enemy GameObject. The enemy GameObject referenced in the EnemyTesting field (in the Inspector view), would be your prefab from the project hierarchy instead of a GameObject inside the scene.
This way, you would be able to instantiate an enemy GameObject as many times as you want (and use it in other scenes!). Don't forget to hold a reference to the instantiated enemy GameObject so you can know which one you want to destroy. It would looke like this :
enemy = Instantiate(enemyPrefab, transform.position, transform.rotation);
You can replace transform with the transform of your choice, for example the transform of an empty enemyRespawnPoint GameObject in your Scene.
Do you see any error in the console ?

Unity2D cloned gameobject doesnt detect the tags of other gameobjects

I am trying to make a projectile that spawns and when it hits the player he gets destroyed. I have to mention that the projectile would be spawned with the "Instantiate" command making it a "cloned gameobject". In the script I wrote that if the projectile would hit another gameobject with the tag "player" the gameobject it hits would get destroyed but after running the code and the projectile hit the player he didn't get destroyed. I checked and the tag does say "player". I threw in a debug command into the code and managed to find out that the tag doesn't get detected. The script for the projectile spawner and the projectile itself are separate so I'm going to only show the projectile script since it is the problematic script. I have to mention that the script doesn't generate any errors and that the simulation runs fine except for the things I have mentioned above.
public class Bulletboi : MonoBehaviour
{
public float speed;
private Transform player;
private Vector2 target;
public GameObject Elven;
void Start()
{
player = GameObject.FindGameObjectWithTag("player").transform;
target = new Vector2(player.position.x, player.position.y);
}
void Update()
{
transform.position = Vector2.MoveTowards(transform.position, target, speed * Time.deltaTime);
if(transform.position.x == target.x && transform.position.y == target.y)
{
DestroyProjectile();
}
}
void OnEnterTrigger2D(Collision2D other)
{
if (other.gameObject.tag.Equals("player"))
{
Debug.Log("bbbb");
DestroyProjectile();
Destroy(other.gameObject);
}
}
void DestroyProjectile()
{
Destroy(gameObject);
}
}
Never mind I decided to change the script a little bit and I put it on the player and made it detect the tag of the projectile and now it works.

Unity3D: Having player light torches using ParticleSystem and OnCollisionEnter?

I'm trying to get my player to light torches in a scene, but not quite sure how to do this.
I have a torch prefab that has a particle system. Each time the player's torch collides into an unlit torch, I would like that torch to start burning.
I have been trying to follow the docs but have not been able to understand (https://docs.unity3d.com/ScriptReference/ParticleSystem.html, https://docs.unity3d.com/ScriptReference/ParticleSystem.Play.html).
Also have this question posted here: https://answers.unity.com/questions/1491419/having-player-light-torches-using-particle-system.html
My current code is below. I have each torch object tagged as torch, and my player tagged as Player. All particle systems, except the player's torch, have 'Play on Awake' off and prewarm on.
Any advice or tips?
Thanks!
/*
* Attach this script to all the torches. It will be used to start the fire
using OnCollision?/OnTrigger? See which is better
* Start with the particle effect/light being off, get all the components
* Turn the torches on when the player's torch collides with them
* 1.) Must make sure each torch object has a collider
* */
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class StartFire : MonoBehaviour
{
public GameObject torch;
public ParticleSystem fireParticleSystem;
bool lightOn;
void Start()
{
lightOn = false; //Start with the light off
fireParticleSystem = GetComponent<ParticleSystem>(); //get Particle System
torch = GetComponent<GameObject>(); //get Torch
}
/*
* if player's torch hits this torch (that is not lit)
* Turn on the fire
* Set the light being on to true
* */
private void OnCollisionEnter(Collision collision)
{
if(this.gameObject.tag==("torch") && collision.gameObject.tag==("Player") && lightOn==false)
{
fireParticleSystem.Play(); //start the particle system
lightOn = true;
}
}
}
1.Create your ParticleSystem and change the tag of its GameObject to "torch".
2.Attach BoxCollider to the SphereCollider to that GameObject with the ParticleSystem.
3.Mark the IsTrigger of the collider created from #2 to be true because it doen't make sense to collide with a touch. It seems like you just want to detect when the player is touching it.
4.The touch script should attached to the player instead of the touch. Use OnTriggerEnter to handle the detection and detect when player touches the touch-light then use GetComponent to get the ParticleSystem and play it. Stop the particle in OnTriggerExit.
If you actually want player to collide and be stopped by the touch then ignore #2 and also use OnCollisionEnter and OnCollisionExit instead of OnTriggerEnter and OnTriggerExit.
Attach to the Player:
public class ParticlePlayer : MonoBehaviour
{
void OnTriggerEnter(Collider other)
{
//Make sure player is touching a touch
if (other.CompareTag("torch"))
{
//Get ParticleSystem from the Gameobject the player collided with
ParticleSystem ps = other.GetComponent<ParticleSystem>();
//Play Particle
ps.Play();
}
}
void OnTriggerExit(Collider other)
{
//Make sure player is touching a touch
if (other.CompareTag("torch"))
{
//Get ParticleSystem from the Gameobject the player collided with
ParticleSystem ps = other.GetComponent<ParticleSystem>();
//Stop Particle
ps.Stop();
}
}
}
I've used the following code in some of my projects:
private ParticleSystem _particleSystem;
private ParticleSystem.EmissionModule _emissionModule;
private void Awake()
{
_particleSystem = GetComponent<ParticleSystem>();
_emissionModule = _particleSystem.emission;
_emissionModule.enabled = false;
}
private void OnCollisionEnter(Collision collision)
{
_emissionModule.enabled = true;
_particleSystem.Play();
}
I believe you're missing the emission module.

Using the LookAt() function in Unity

So I have an assignment that I have to do for school where an enemy shoots at the player in a gun type game. I have read about the LookAt() function in the Unity tutorials and used it to my knowledge of it. However it doesn't seem to be working. The following code is what I have so far:
public class EnemyControl : MonoBehaviour {
private Rigidbody rb;
public GameObject Bullet_Emitter2;
public GameObject EnemyBullet;
public float speedOfBullet;
private int score;
public Text countText;
public Text winText;
private GameObject Temporart_Bullet_Handler2;
public Transform player;
public Transform enemy;
void Start()
{
rb = GetComponent<Rigidbody>();
score = 0;
}
private void Update()
{
enemy.LookAt(player);
}
// Update is called once per frame
void FixedUpdate () {
int fire = Random.Range(0, 100);
if(fire == 0 || fire == 1 || fire == 5)
{
Temporart_Bullet_Handler2 = Instantiate(EnemyBullet, Bullet_Emitter2.transform.position, Bullet_Emitter2.transform.rotation) as GameObject;
Temporart_Bullet_Handler2.transform.Rotate(Vector3.right * 90);
Rigidbody Temporary_Rigid_Body;
Temporary_Rigid_Body = Temporart_Bullet_Handler2.GetComponent<Rigidbody>();
Temporary_Rigid_Body.AddForce(transform.up * speedOfBullet);
Destroy(Temporart_Bullet_Handler2, 20.0f);
}
}
}
The problem is my enemy now just looks at the ground instead of me and then just shoots downwards. Is there a way I can fix this? I have attached an image of what it looks like to a player playing the game?
Before putting in the LookAt() function my spaceman would just be stationary and fire bullets in a straight line but I need the AI to track the player instead of stationary. Is there another way to do this without using LookAt() or am I using this function wrong?
Thanks for the help in advance?
I would post this in comments but I can't yet because of low reputation
As Serlite pointed out, LookAt() only faces the GameObject's trasnform.forward (which is desired to be (0, 0, 1) when the object is not rotated) towards the target passed as argument.
To 'fix' this simply add an empty GameObject to your Hirarchy and set your AI object as its child
Empty GameObject
- AI GameObject (with your script)
Now you can set a global rotation for your object (Rotate the parent) in a way that the AI's forwards faces z+.

Categories