Im trying to make it so that when i trigger a trigger in Unity, it doesnt remove the trigger, but it does remove what the trigger is attached to. but i cant seem to figure out how to do it.
void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag("pickup"))
{
audio.Play(); //Play it
other.gameObject.SetActive(false);
count = count + 1;
SetCountText();
}
}
This is an example of what im trying to do, but imagine it trying to set something else to inactive.
When you deactivate the game object, the attached collider will be deactivated too. If you want to deactivate a game object and let the collider exist you need to distinct between those two, i.e. have two game objects: one just for the collider and one for the actual object. now you can remove the actual object while the collider can continue to function.
The implementation depends on how you are handling the trigger.
case 1:
OnTriggerEnter is written in a script attached to the game object which static collider (ground) is attached to.
static collider is a collider without a rigidbody.
add a child to this game object and put the visuals in it (i.e. renderer or audio source).
add public GameObject Child; to the script.
set the reference of the child via unity inspector window.
deactivate the child instead of collider's gameobject in OnTriggerEnter method: Child.SetActive(false);
case 2:
OnTriggerEnter is written in a script attached to another game object which also has a dynamic collider (ball) and a rigidbody.
dynamic collider is a collider with a rigidbody.
add a child to the game object which the static collider is attached to
add a script to the game object (MyScript)
add public GameObject Child; to the script.
set the reference of the child via unity inspector window.
deactivate the child instead of collider's gameobject in OnTriggerEnter method: (other as MyScript).Child.SetActive(false);
When you deactivate an object with gameObject.SetActive(false); you automatically deactivate every component on you object (Renderer, Triggers, Scripts, ...)
There is two options to achieve what you want to do:
Use another object as a trigger (a Plane or a Cube and deactivate your object from this new object)
Or as suggested by #madjlzz you can deactivate your Renderer and RigidBody
Related
Help, im using unity 2020.3.15f2, OnCollisionEnter is not working.
I have 2 gameObjects, both with not trigger SphereColliders and not Kinematic RigidBodies.
My RigidBodies doesn´t have gravity on, but they have constants (don´t move on z, and don´t rotate on x or y)
Im shure they collide because both gameobjects interact colliding, but when i call the script that contains the OnCollisionEnter (that just call a Debug.Log("Collision")) i don´t see anything on console.
void OnCollisionEnter(Collision col){
Debug.Log("Collision"); //i don´t see anything on console
}
This is my SphereCollider and RigidBody setup for both GameObjects:
And the script is on the parent of those GameObjects, like this:
This is the Scene Hierarcy
And this is the "Element" Hierarchy (note: i edit it to mantain the names of my gameobjects in secret its my boss desition)
As you can see here the "Element" its the one who have the script with the OnCollisionEnter
I Solve by thinking: How my scene is setted?, I see that the gameObjects that contain the Collider and the RigidBody, are child of the gameObject with the OnCollisionEnter script.
Aparently, OnCollisionEnter only works with the gameObject itself, if the script is attached to a parent or to a child of the gameObject, it´ll not work.
So with that, i just need to make a Collision Detection Script on the gameObjects with the Colliders, and entangle it with the parent´s script to do... the thinks the gameObject should do when collide.
Thanks all for your feedback and help, special thanks for #derHugo and #Ruzhim who are the people who help me to detect that problem.
Solution: make shure the script with the OnCollisionEnter is on the gameObject that have the Collider and the RigidBody, not the parent, not the child.
How do I instantiate multiple instances of the FloatingText that destroys itself in 1 second?
I'm using this script to instantiate a floating text.
if (Input.GetKey("w")) {
GameObject floatingText = Instantiate(floatingTextPrefab, position, Quaternion.identity, transform);
}
In the FloatingTextPrefab, I added a component script called DestroyTimer. So tht text disappears in 1 second.
void Start()
{
Destroy(gameObject, 1f);
}
Now whenever I press the key, it says
MissingReferenceException: The object of type 'GameObject' has been destroyed but you are still trying to access it.
Why is it deleting the prefab, instead of itself as an instance?
I'm trying to follow this but he doesn't encounter the same problem.
https://youtu.be/LjNsDVYXfrk?t=364
If your prefab is also in the 3D scene, it will execute the destroy itself whenever it's visible.
It means that your prefab already destroy itself before you pressing "W".
Below is the suggested way to do it.
if (Input.GetKey("w"))
{
GameObject floatingText = Instantiate(floatingTextPrefab, position, Quaternion.identity, transform);
Destroy(floatingText, 1f);
}
and please remove the destroy function within your prefab:
void Start()
{
//Destroy(gameObject, 1f);
}
Edit:
If you want to use your original setup.
Two options:
option 1: saving it as prefab, and assign the prefab from asset folder.
option 2: always disabling the prefab by default, only enabling the instantiated object.
I think I figured it out. I need to delete the FloatingTextPrefab in the scene, only leave it in the assets. And in the components menu associate the one from Assets instead of the one in the scene.
I am trying to add same components to different game objects in a scene in Unity. To make it faster I am trying to write a script that will do this for a list of game objects like (enemy1, enemy2, enemy3...).
I know that adding a script named Enemy I will do:
gameObject.AddComponent<Enemy>();
But the problem is once I stop the play mode the component is gone. Is there a way to achieve this?
You can directly select all the game objects (the list of enemies you mentioned) from the Hierarchy by holding ctrl and then add in the inspector the script Enemy to all of them.
However, if you want to use a script to do it, which can be executed outisde of the Play Mode you need to add ExecuteInEditMode before the script, like this:
[ExecuteInEditMode]
public class TriggerEdit : MonoBehaviour
{
// List of GameObjects
String[] enemyList = {"enemy1", "enemy2", "enemy3"};
void OnEnable()
{
foreach(String enemy in enemyList){
go = GameObject.Find(enemy);
go.AddComponent<Enemy>();
}
}
}
Then you need to add that script to any game object in your scene. Everytime you want to trigger the script you just need to disable and enable the script TriggerEdit in the editor:
One problem with this approach is that everytime you enable the script, it will add a new component, independently if there is already a compoment of type Enemy in the game object, so you may end up with a lot of Enemy components. Something you can try then is to clean all Enemy components in the scene before adding anything else new. For example:
object[] enemiesToDelete = GameObject.FindObjectsOfType<Enemy>();
foreach(UnityEngine.Object enemyComponent in enemiesToDelete)
{
DestroyImmediate(enemyComponent);
}
I have problem with add dynamically tag to gameObejcts , when I Instantiate an enemy I add enemy tag using this:
GameObject temp = (GameObject)Instantiate(enemy, spwanPosition, spwanRotation);
temp.gameObject.tag = "Enemy";
I read this from : Is it possible create a tag programmatically
but when I try to Destroy this object with specific explosion There is no object with Enemy tag:
void OnTriggerEnter(Collider other)
{
if (other.tag == "Boundary")
{
return;
}
if (other.tag == "Enemy")
{
Debug.Log("enemy"); # Never printed in console
Instantiate(enemyExplosion, other.transform.position, other.transform.rotation);
}
Instantiate(explosion, this.transform.position, this.transform.rotation);
Destroy(other.gameObject);
Destroy(this.gameObject);
How can I add a tag dynamically to a gameObject that Instantiate multiple times?
Edit
This is the Picture from Instantiated enemy Object in Paused game , It is so wired , it has Enemy tag , But why this didn't work?
The problem is when in run-time Enemy tag is assigned to objects but when I check if(other.tag == "Enemy") this dosen't work!
The link that you posted is about creating tags dynamically, you don't need this and I don't see why anyone would need to do this.
I presume you have a tag named Enemy in the tag manager?
You are instantiating an enemy prefab, which means you don't need enemy.tag = "Enemy". Just set the enemy prefab tag to Enemy in the inspector.
This will instantiate the new enemies with the same values as the prefab.
As for the trigger not working, I am not sure, make sure you have met all the specifications for the enemy calling the OnTriggerEnter().
Taken from http://answers.unity3d.com/questions/753481/ontriggerenter-not-working-tried-everything-c.html
OnTriggerEnter, at least one of them has to have the Is Trigger property checked and at least one of them has to have a Rigid Body. If neither of your objects is a Trigger, you can use OnCollisionEnter instead.
Once that's all set, you should check the Layers (not Tags) on your objects. To edit which Layers collide with each other, you can look at Edit -> Project Settings -> Physics.
I read this from : Is it possible create a tag programmatically
It is NOT possible to create a tag during run-time. You can change the tag of a GameObject to an existing one but you CANNOT create a new one.
So before you assign a tag named Enemy or Boundary, make sure that you have already created such tag in the Editor first. It is also case-sensitive.
I have problem with add dynamically tag to gameObejcts , when I
Instantiate an enemy I add enemy tag using this:
Instantiate(enemy, spwanPosition, spwanRotation);
enemy.tag = "Enemy";
How can I add a tag dynamically to a gameObject that Instantiate
multiple times?
That's wrong. What you are doing now is changing the tag of the original GameObject NOT the Instantiated GameObject. To change the tag of the Instantiated GameObject, store a reference of the Instantiated GameObject and then modify the tag. The code below is what you are looking for.
GameObject tempGOB= (GameObject)Instantiate(enemy, spwanPosition, spwanRotation);
tempGOB.tag = "Enemy"; //Change the tag of the Instantiated GameObject instead of the enemy(original object)
I suspect that your problem is not the tag, but the collision. Does your enemy object have a collider? Does a simple collision test succeed?
Edit (forget about this):
Actually your problem might be that you shouldn't use other.tag but other.gameObject.tag.
About a month into making my first game, I have realized that I am very confused when it comes to attaching gameobjects as classes to another game object's script. That's a mouthful so here's my issue.
My Game.cs attached to Game (gameobject) has
public Player player;
My Player.cs is attached to a Player (gameobject) prefab
Why can I drag a Player gameobject, that has a player script, into the Game gameobject's "player" field? How does that make sense? It should be
public GameObject player;
Then I would drag my prefab gameobject "Player".
The reason why this confuses me is, If i Instantiate "player", am I instantiating a gameobject? It seems not, because I cannot do this:
GameObject newPlayer = Instantiate(player, new Vector3(1,1,1), Quaternion.identity) as GameObject;
newPlayer.transform.SetParent(GameObject.Find("Level"));
If I do I will get the error the newPlayer is null.
A script is actually a Component object like any other object (most of the time).
It is technically not too easy to drag a Component object from an inspector onto another slot in another inspector. Probably thats why they made this "shorthand", when you can drag the actual GameObject instead from the hierarchy.
If the dragged GameObject has a matching component to a slot, it counts as you have dragged the Component itself.
You cannot instantiate a script Component using Object.Instantiate, you'll always instantiate a GameObject this way, see the docs. If you need the script, simply get the component from the brand new instance.
It can be confusing indeed, I personally prefer naming convention something like:
public GameObject playerObject;
public Player player;
Unity. by default, will cast any gameobject into the possible component, for example, if you have a Transform in your script and pass a gameobject (as a lot of tutorials do), it will automatically cast to the transform of given gameobject.
The main problem with that is simply that if you try to attach an object without Player script, it will probably crash in one way or another if you don't check the value.
Anyway, while you are working with your own scene and are sure the player gameobject has the necessary script, it won't be a problem in any way
Oh, about the last part, attaching components is common for already instantiated objects, to instantiate from a component you should get the parent game object of that script, and it would not make sense as you could easily attach the prefab directly
I don't remember now exactly how, sorry