I need to destroy an object, in my case is "Player2" witch is in the same scene as "Player1" and then after Player1 position.x is past "baraj".position.x reapear. Basically how can i make a temporarly destroy method.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class switchCameras2 : MonoBehaviour
{
public GameObject baraj;
public GameObject CameraOne;
public GameObject CameraTwo;
public GameObject Player1;
public GameObject Player2;
public void Start()
{
CameraOne.SetActive(true);
CameraTwo.SetActive(false);
}
void Update()
{
if (GameObject.Find("Player1").transform.position.x > GameObject.Find("baraj").transform.position.x)
{
CameraTwo.SetActive(true);
CameraOne.SetActive(false);
}
if (GameObject.Find("Player1").transform.position.x < GameObject.Find("baraj").transform.position.x)
{
Destroy(Player2);
}
if (GameObject.Find("Player1").transform.position.x > GameObject.Find("baraj").transform.position.x)
{
Destroy(Player1);
}
}
}
If you want to Destroy it then you should make a new one with Instantiate method. If you don't want to Destroy it, one alternative is to deactivate it with SetActive like this Player1.SetActive(false); and then enable it like this Player1.SetActive(true);
Try creating a new GameObject variable called "U". And then right before destroying or in the start do U = player2.gameObject;
Now let's say you destroyed it and want to spawn. To do that we do
player2 = U.gameObject;
Instantiate(player2);
That will spawn player 2.
But as mentioned in the other answer .SetActive(false); would make things easier. Anyway if you still want to use destroy then that is how to do that. Good luck
Related
I am working on a 3d basketball game in unity.
It has a score and a timer. After a certain time my scene loads and starts from the beginning. Every time I throw the ball, I have to spawn it.
It has a spawn button and a shoot button. But I don't want to use the spawn button. So I want to spawn the ball automatically.
How should I do it? I am giving my spawn button code and throw button code bellow.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpawnButton: MonoBehaviour
{
public GameObject ball;
public GameObject BallPosition;
public void Spawn()
{
ball.transform.position = BallPosition.transform.position;
var ballPosition = ball.transform.position;
ball.GetComponent<Rigidbody>().useGravity = false;
ball.GetComponent<Rigidbody>().velocity = Vector3.zero;
ball.transform.position = ballPosition;
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ThrowButton: MonoBehaviour
{
static Animator anim;
public GameObject ball;
public float ballThrowingForce = 5f;
internal bool holdingBall;
void Start()
{
anim = GetComponent<Animator>();
ball.GetComponent<Rigidbody>().useGravity = false;
}
public void Throw()
{
anim.SetTrigger("isThrowing");
StartCoroutine(Test());
}
IEnumerator Test()
{
yield return new WaitForSeconds(1.5f);
ball.GetComponent<Rigidbody>().useGravity = true;
//ball.GetComponent<Rigidbody>().AddForce(transform.up * ballThrowingForce);
ball.GetComponent<Rigidbody>().AddForce(0, 380.0f, ballThrowingForce);
}
}
To spawn a ball you should create a prefab and instantiate it. Example:
private class Spawner : MonoBehaviour
{
public GameObject prefab;
public GameObject Spawn() => Instantiate(prefab);
}
So that your throw code should spawn a ball and if you want destroy an older one.
The above answer by Iv Misticos mentioned the use of Instantiate which is a great way to spawn a new ball.
before you spawn a new ball, you need to specify when it must spawn.
Either you can
use a Invoke("SpawnNewBallMethod",3) //after this piece of code is executed, it waits for 3 seconds and executes the method you mention in it which can have the code to instantiate.
Or After the first ball's work is done, you can destroy it(Destroy(ball)) or set active to false - Then check the state (if it exists(null check?) or gameObject.active==true) and accordingly instantiate a new ball (if it is setactive(false) don't forget to destroy it later).
Although gameObject.active is obsolete, it will serve the purpose without complicating things.
In my opinion, Invoke is better than a IEnumerator here as Invoke will not stop the execution flow and continue with the other things while the timer is running.
I try to create a shop system where you can buy a character to play with. When I buy a character in the Shop Scene, the bool value in the Inventory script is set to true. When I switch to the Level1 Scene, my character is not spawned. I suppose there is a bug in my GameManager script but I can not find it. Can you please help me? I do not know any more.
GameManager script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour
{
public GameObject Joli;
public GameObject Ninn;
public GameObject Spaci;
public GameObject Woodie;
public GameObject Plumbt;
public GameObject canvasObject;
public Inventory myInventory;
// Start is called before the first frame update
void Start()
{
myInventory = GameObject.FindObjectOfType<Inventory>();
if (myInventory.GetNinn() == true)
{
GameObject Ninnnew = Instantiate(Ninn, Ninn.transform.position, Quaternion.identity) as GameObject;
Ninnnew.transform.SetParent(canvasObject.transform, false);
}
if (myInventory.GetSpaci() == true)
{
GameObject Spacinew = Instantiate(Spaci, Spaci.transform.position, Quaternion.identity) as GameObject;
Spacinew.transform.SetParent(canvasObject.transform, false);
}
}
}
There is currently not enough information / code in your question, but when you change scene, your objects are destroyed by default, and new ones are isntantiated, effectively resetting any values that are set in them.
You need to prevent your Inventory or any object holding data you need to keep that it should not be destroyed when switching scenes, by using DontDestroyOnLoad for instance :
https://docs.unity3d.com/ScriptReference/Object.DontDestroyOnLoad.html
I'm making some sort of a Evolution simualtor game. I have a script that is supposed to destroy the GameObject it's attached to when a creature's CapsuleCollider Triggers the OnTriggerEnter().
I have a problem that even tho the Creature's collider isn't even close to the Food, it still destroys the GameObject.
My script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FoodEat : MonoBehaviour
{
public GameObject FoodGO;
public Rigidbody FoodRB;
private void OnTriggerEnter(Collider Creature)
{
Destroy(FoodGO);
}
void Start()
{
FoodRB = GetComponent<Rigidbody>();
FoodGO = FoodRB.gameObject;
}
void Update()
{
Rigidbody[] allRigidBodies = (Rigidbody[])FindObjectsOfType(typeof(Rigidbody));
foreach (Rigidbody body in allRigidBodies)
{
if (body.gameObject.layer == 10)
{
OnTriggerEnter(body.gameObject.GetComponent<CapsuleCollider>());
}
}
}
}
OnTriggerEnter is a monobehaviour lifecycle method. You should not call it from your own code; it will automatically be called when it detects collisions.
Furthermore, the logic in your code right now seems to be incorrect, it is...
"Every frame, loop through all rigidbodies in the scene and if 1 is found on layer 10, destroy the FoodGO"
Simply remove your entire Update method and put an if in your Collision method, and it should work:
[RequireComponent(typeof(Rigidbody), typeof(Collider))]
public class FoodEat : MonoBehaviour
{
private void OnTriggerEnter(collider other)
{
Debug.Log(other.gameObject.name + " on layer " + other.gameObject.layer);
if (other.gameObject.layer == 10)
Destroy(this.gameObject);
}
}
A few noteworthy edits of your code:
I removed FoodGO, since it's the GameObject this script is attached to, you can access it by just writing gameObject or this.gameObject.
I remove the Rigidbody reference since it is not used anymore, and thus the entire Start() method.
Since this code requires a Rigidbody and a Collider to work, I added a [RequireComponent] attribute in the top, which will make Unity tell you if you forgot to add those components on the object you attach this script to.
I added a Debug.Log that prints the name & the layer on the creature that collides with the food, so you can debug and make sure it is working as expected
I am just trying to activate game over screen when the Player's activate is 'false'. There is no animation, just the
There are 3 objects that need to be active and i added the script to those 3 objects but the screen does not appear.
How can i fix?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameOverManager : MonoBehaviour
{
public GameObject _player;
void Start()
{
_player = GameObject.FindGameObjectWithTag("Player");
}
void Update()
{
if (_player.activeInHierarchy == false)
{
gameObject.SetActive(true);
}
else
{
gameObject.SetActive(false);
}
}
}
My suspicion is the following. Whenever a Gameobject is not enabled, its code does not run. Test this by adding a Debug.Log("test") message.
If no message appears you can be certain that this check is never evaluated. To work around this simply add a script that is bound to an active gameObject. Creat a new empty gameobject in the scene. And add something like this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameOverManager : MonoBehaviour
{
public GameObject _player;
public GameObject _endscreen;
void Update()
{
if (_player.activeInHierarchy == false)
{
_endscreen.SetActive(true);
}
else
{
_endscreen.SetActive(false);
}
}
}
Assign the Variables in the Inspector by dragging the object to the empty fields. Never use GameObject.Find Methods.
If you need any further help tell me :)
What you're currently doing is to find a single GameObject and checking whether that is active or not.
It would make more sense, and be more optimized, if each player object adds himself to a list of all players when he spawns. You can then loop over that list instead to check all players.
An even better way would be if you only call that "GameOver" check after a player has died. So when you call whichever method kills him.
Based on Franz Answer, I did some modification in the code. You won't need any if else statement if you use a shortcut.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameOverManager : MonoBehaviour
{
public GameObject _player;
public GameObject _endscreen;
void Update()
{
_endscreen.SetActive(!_player.activeInHierarchy);
}
}
I'm going through the worse struggle right now. I'm trying to create a game with pitfalls that if the players fall through, they respawn and the game counts their death. I'm completely at wit's end and don't know where to even start with this. The game is 3D
using UnityEngine;
using System.Collections;
public class Respawn : MonoBehaviour {
public Transform spawnPoint;
public float minHeightForDeath;
public GameObject player;
void Start () {
}
// Update is called once per frame
void Update () {
if (player.transform.position.y < minHeightForDeath) {
player.transform.position = spawnPoint;
}
}
}
Use a collider on a plane/cube/whatever works for you, and set it to be a trigger. So when they pass through the trigger collider, it can record them and do what you want with it.
Use the OnTriggerEnter method script
void OnTriggerEnter(Collider other)
{
other.transform.position = spawnPoint.position;
}
You are not putting any data in the "minHeightForDeath" float. Unless you do it in the editor.
Other than that, have you put the script on the player gameObject? And have you set what you have to in the editor?