This is my code
void Update ()
{
if (Input.touchCount > 0 && Input.GetTouch (0).phase == TouchPhase.Began)
{
if ( Physics.Raycast(ray, out hit, 1000f ) )
{
for(int i=0; i< hit.collider.transform.childCount; i++)
{
var child = hit.collider.transform.GetChild(i).gameObject;
if(child != null)
child.SetActive(true);
}
hit.collider.gameObject.GetComponent<SpriteRenderer>().enabled = false;
//Debug.Log(hit.transform.gameObject.name);
}
}
}
This code sits on my camera in my scene. What it does is allows me to touch a game object and destroy. The first object I touch is a 2D sprite and I've turn off its sprite renderer and turn on its childs, sprite renderer.
However, I need a way to destroy the game object once this is done. I'm truly at a loss as to how I can achieve this.
Destroy (gameObject, 5);will destroy in 5 seconds.
Also you can use in the OnMouseDown() and spare all the for loop and raycast stuff in update
If you do want the OnMouseDown() you would of course need the script on the object prefab and not the camera though.
Related
Hello I know that I have the code right. I want to destroy the material when my player goes on them. I don't know why I can't destroy them. I have put only to my materials box collider with X= 1 Y=1 Z=1.I don't understand why I can't destroy them. The material I gave it also as a tag. Instead of my player destroy those material he pass through them..I have a RigidBody on the player.
void OnCollisionEnter ( Collision collision )
{
if ( collision.gameObject.tag == "material" )
{
Destroy ( collision.gameObject );
}
}
You need to debug collisions
try this function and screenshot both results and material gameobject :
void OnCollisionEnter(Collision collision)
{
Debug.Log("all collisions :" + collision.gameObject.name);
if (collision.gameObject.CompareTag("material"))
{
Debug.Log("Material collision :" + collision.gameObject.name);
Destroy(collision.gameObject);
}
}
}
I am working on a simple game where the goal is to help a Player catch specific objects with a tag "Present".
After taking care of the models, animations I am now working on the collisions and counting UI.
For the collisions, on my Player Controller (I am using the ThirdPersonUserController from the player Unity Standard Assets - which simplified the whole animation process), I added the following functions:
void OnCollisionEnter(Collision other)
{
if (other.gameObject.tag == "Present")
{
Destroy(gameObject);
count = count - 1;
SetCountText();
}
}
void SetCountText()
{
countText.text = "Count: " + count.ToString();
if (count == 0)
{
winText.text = "Thanks to you the Christmas will be memorable!";
}
}
However, like this, when the Player hits an object with the tag "Present", even though the counting is working properly, the player disappears.
I have tried to change the OnCollisionEnter to an OnTriggerEnter, like this:
void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag("Present"))
{
Destroy(gameObject);
count = count - 1;
SetCountText();
}
}
However when the Player hits the objects with the tag "Present", they don't disappear.
My Player has a Capsule Collider and a Rigidbody.
The objects with the tag "Present" have a Box Collider and a Rigidbody.
Any guidance on how to make my Player stay in scene while removing the other objetcs and reducing the count is appreciated.
Few things. You are destroying the incorrect game object:
void OnCollisionEnter(Collision other)
{
if (other.gameObject.tag == "Present")
{
Destroy(gameObject); // this is destroying the current gameobject i.e. the player
count = count - 1;
SetCountText();
}
}
Update to:
void OnCollisionEnter(Collision other)
{
if (other.gameObject.CompareTag("Present"))
{
Destroy(other.gameObject); // this is destroying the other gameobject
count = count - 1;
SetCountText();
}
}
Always use CompareTag() which is optimized for performance.
Setting the Collider IsTrigger property will then make use of the OnTriggerEnter events and not the OnCollisionEnter anymore.
On the first physics update where the collision is detected, the
OnCollisionEnter function is called. During updates where contact is
maintained, OnCollisionStay is called and finally, OnCollisionExit
indicates that contact has been broken. Trigger colliders call the
analogous OnTriggerEnter, OnTriggerStay and OnTriggerExit functions.
See the docs
Your present object is using a non-trigger collider, so you should use OnCollisionEnter. The CompareTag call you tried in OnTriggerEnter is preferable. You should use that.
Also, you are currently trying to destroy the gameobject that the ThirdPersonUserController is attached to (gameObject). Instead, destroy the gameobject of the colliding collider (other.gameObject) with Destroy(other.gameObject);:
void OnCollisionEnter(Collision other)
{
if (other.gameObject.CompareTag("Present"))
{
Destroy(other.gameObject);
count = count - 1;
SetCountText();
}
}
So I'm making a game where you evade enemies and trigger certain powerups that has various effects on the enemies. One of them is a bomb that explodes 4 seconds after the player collides with it, destroying all enemies within its radius as it explodes.
I think I've got everything figured out except the actual destroying of the enemy. I feel like the solution is so obvious but I just never learned the method. At this point the bomb object is destroyed upon explosion instead of the enemies, which I expected to happen, because Destroy(other.gameObject) just doesn't work in this context! What do I do??
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
{
Debug.Log("player");
StartCoroutine(BombCountdownRoutine());
}
}
IEnumerator BombCountdownRoutine()
{
bombAudio.PlayOneShot(bombSound, 0.8f);
yield return new WaitForSeconds(4);
Collider[] hitColliders = Physics.OverlapSphere(transform.position, 10);
for (int i = 0; i < hitColliders.Length; i++)
{
if (hitColliders[i].gameObject.tag == "Enemy")
{
Destroy(gameObject);
}
}
}
I got a script like this to create a raycast from maincamera and hit the enemy.
void FixedUpdate(){
if (fire) {
fire = false;
RaycastHit hit;
if (Physics.Raycast (fpsCam.transform.position, fpsCam.transform.forward, out hit, range)){
if (Enemy.distance < 80) {
if (hit.collider.tag == "body") {
Debug.Log ("Bullet in the body.");
Enemy.bodyshot = true; //Changing other script variable.
} else if (hit.collider.tag == "head") {
Debug.Log ("Bullet in the head.");
Enemy.headshot = true; //Changing other script variable.
}
}
}
}
}
Enemy Script in Update;
if (headshot) { //headshot variable is static to reach from other script.
anim.SetTrigger ("isDying");
speed = 0;
death = true;
}
if (bodyshot) { //bodyshot variable is static to reach from other script.
anim.SetTrigger ("isSore");
}
So, when I shoot an enemy, all enemies are dying at the same time. Because these scripts are attached to all enemies. I need to change bodyshot and headshot variables without using static. What can I do to separate them ?
When it comes to raycast, you only need the raycast script attached to an empty GameObject. It does not have to be attached to each individual Object that you want to perform the raycast on.
The only time you have to attach script to a GameObject you want to detect clicks on is when using the Unity EventSystem to detect clicks on the objects.
So, remove this script from other GameObjects and just attach it to one GameObject.
Note:
If you want to access or do something to the GameObject that the ray just hit, the GameObject is stored in the hit variable.
RaycastHit hit;...
Destroy(hit.collider.gameObject);
You can also access scripts attached to the Object hit:
hit.collider.gameObject.GetComponent<YourComponent>().doSomething();
Instead of checking to see what the tag of the collider is, you can first check to make sure the collider is one of the colliders attached to your object, and then check the tag for body location. For example:
public Collider[] coll;
void Start() {
coll = GetComponents<Collider>();
}
void FixedUpdate(){
if (fire) {
fire = false;
RaycastHit hit;
if (Physics.Raycast (fpsCam.transform.position, fpsCam.transform.forward, out hit, range)){
if (Enemy.distance < 80) {
if (hit.collider == coll[0] || hit.collider == coll[1]) {
if (hit.collider.tag == "head"){
or to simplify you can make coll[0] the head and [1] the body and ignore checking for a tag.
edit: As Programmer mentioned, this is not an efficient way to do this since you will be casting a ray for every object that has this script and you really only want to be casting a single ray.
I have created a simple 2D touch game in Unity and I have spikes spawning at the top of the scene every 3 seconds and when the spikes fall the player will tap the spikes before they hit the characters below, however, when I test the game, when I tap the spike (game object) it destroys all of the spikes (game objects) in the scene. Here is the code:
public GameObject spike;
public float spawnTime1 = 1f;
// Use this for initialization
void Start () {
InvokeRepeating ("SpawnSpike", spawnTime1, spawnTime1);
}
// Update is called once per frame
void Update () {
for (var i = 0; i < Input.touchCount; ++i) {
if (Input.GetTouch(i).phase == TouchPhase.Began) {
Destroy (gameObject);
}
}
}
void SpawnSpike () {
var newSpike = GameObject.Instantiate (spike);
newSpike.transform.position = new Vector3 (Random.Range(-3, 3), 11f, 0f);
It looks like you're destroying this game-manager-like script itself when you run
void Update () {
for (var i = 0; i < Input.touchCount; ++i) {
if (Input.GetTouch(i).phase == TouchPhase.Began) {
Destroy (gameObject);
}
}
}
The line Destroy (gameObject); is destroying its own game-object, which I'm guessing is parented to the spikes that are instantiated(?); hence destroying all the spikes at once.
I suggest using raycasts to find out if any spike is tapped on and/or which spike is tapped on, and then destroying only the game-object of that spike. Here's a good reference. I also suggest looking for tutorials regarding the same if you're still finding it hard to understand.
I hope that helps!
UPDATE:
Here's some sample code to get you going:
if (Input.GetTouch(i).phase == TouchPhase.Began) {
Vector3 pos = Camera.main.ScreenToWorldPoint (Input.GetTouch(i).position);
RaycastHit2D hit = Physics2D.Raycast(pos, Vector2.zero);
if (hit != null && hit.gameObject.CompareTag("spike") && hit.collider != null) {
Debug.Log ("I'm tapping "+hit.gameObject.name);
Destroy(hit.gameObject);
}
}
This specific code would require that your spike prefab (template) has the tag "spike". I also suggest you place this code in some kind of a global "game-manager" script's Update() (rather than in the Spike script), so that you don't over-process the touches.