I have an object that when clicked it is destroyed and spawns randomly somewhere else on a timer. I'm trying to make it so instead of random spots it shows up at fixed locations.
I also want them to randomly spawn at those fixed locations on a timed interval, one at a time.(so if it appears in one location for lets say 5 seconds, it will be destroyed and the next one will appear in a different location.)
I attempted to do fixed spawn locations, but the void spawner doesn't want to work.
I get a "The object of type "GameObject" has been destroyed but you are still trying to access it".
I can fix this by commenting out the On_TouchStart destroy line, but I need it.
Here is my code:
using UnityEngine;
using System.Collections;
public class Spawner : MonoBehaviour {
public float AppearTime = 0f;
public Transform[] teleport;
public GameObject[] prefab;
void Spawner(){
int tele_num = Random.Range(0,5);
int prefab_num = Random.Range(0,3);
if (prefab !=null){
Instantiate(prefab[prefab_num], teleport[tele_num].position, teleport[tele_num].rotation );
}
}
void StartTime()
{
StartCoroutine(DoTime());
}
void OnEnable(){
EasyTouch.On_TouchStart += On_TouchStart;
}
IEnumerator DoTime()
{
yield return new WaitForSeconds(AppearTime);
Spawner();
}
void On_TouchStart (Gesture gesture){
if (gesture.pickObject != null){
Destroy(gesture.pickObject);
StartTime();
}
}
If anyone could lead me on the right track I'd appreciate it.
Thanks.
I figured it out. Turns out the prefabs I were using were incorrect, so I needed to swap them out for ones that did.
Thanks to the ones who helped.
Related
I am trying to get my 3-D Tic-Tac-Toe game project to work, I have game objects which are named cells that are instantitated I press OnMouseDown() click it makes a cell object spawn in its grid space. I don't want to use UI with the basic prefabs I created. Is there a way to get my game objects instantiated and once it reaches a certain number as a winning condition? I have considered using pathfinding but I am not certain if that would be the correct approach. I have looked every where to find a solution that is unique to my problem but could not find a solution. Perhaps, I am asking the wrong questions but I am desperate so that is why I came her to see if I could get input on how to approach this issue.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.SceneManagement;
public class Cell : MonoBehaviour
{
public GameObject cell;
public GameObject negCell;
public GameObject alter;
public Transform transPos;
[SerializeField]
private bool isTapped = false;
private int counted;
public int gameObjectCount;
void Start()
{
gameObjectCount = GameObject.FindGameObjectsWithTag("Cell1").Length;
}
void Update()
{
}
public void OnMouseDown(int counted) //click and point to create and deestroy objects
{
counted = gameObjectCount;
isTapped = true;
transPos = alter.transform;
Instantiate(cell, transform.position, Quaternion.identity);
StartCoroutine(WaitForObject());
Debug.Log("Alter Destroyed!");
gameObjectCount++;
DestroyGameObject();
return;
}
IEnumerator WaitForObject()
{
if (isTapped == true)
{
Instantiate(negCell, -transform.position, Quaternion.identity);
isTapped = false;
}
yield return new WaitForSeconds(3f);
DestroyGameObject();
}
void DestroyGameObject()
{
if(gameObject == alter)
{
DestroyImmediate(alter, true);
}
else
{
DestroyImmediate(cell, true);
}
}
}
There are two easy ways to achieve this.
The first one would be to add a static member in your class, let's say :
private static int _instanceCounter = 0;
This will act as a class instances counter.
All you have to do is to increment this variable every time you instantiate a new game object.
Finally, base your win condition on the number of instances of the class you want.
You can also decrement this variable if for some reason at a moment you call the Destroy method on a specific game object.
The other way would be to use the FindObjectsOfType method from Unity which returns an array of all instances in your current scene.
By accessing the length of this array, you'll have the number of instances.
However, this only count for the current number of instances when this method is called. Note that you can also include the inactive game objects from the scene (those which are in grey within your hierarchy panel).
You now have two ways to do it, depending on how you want to achieve your win condition, i.e. the total of game objects instantiated OR a specific number of game objects at a given time.
I am trying to practice creating a clone of Galaga following the same ruleset as the original. I am currently stuck trying to attempt a limit on the amount of cloned prefabs that can be in the scene at any one time, in the same way that Galaga's projectiles are limited to 2 on screen at any time. I want to make it so the player can shoot up to two projectiles, which destroy after 2 seconds or when they collide (this part is functioning), followed by not being able to shoot if two projectile clones are active and not yet destroyed in the hierarchy (Not working as I can instantiate projectiles over the limit of 2).
I have combed through Google for about 3 hours with no solutions that have worked for me, at least in the ways that I had attempted to implement them.
Thank y'all so much for the help!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class playerController : MonoBehaviour
{
public float moveSpeed = 1.0f;
public playerProjectile projectile;
public Transform launchOffset;
public int maxBullets = 0;
private GameObject cloneProjectile;
public Rigidbody2D player;
// Start is called before the first frame update
void Start()
{
player = this.GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
MovePlayer();
PlayerShoot();
}
public void MovePlayer()
{
player.velocity = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical")) * moveSpeed;
}
public void PlayerShoot()
{
if (Input.GetKeyDown(KeyCode.Z))
{
var cloneProjectile = Instantiate(projectile, launchOffset.position, launchOffset.rotation);
maxBullets++;
if (maxBullets >= 3)
{
Destroy(cloneProjectile, 0.1f);
maxBullets --;
return;
}
}
}
}
You could change the logic up a bit. An instance of the playerController class is active as long as the game is active, so it will know and retain the value of 'maxBullets' until you die or exit the program.
So instead, every time you click "z", the first thing you should do is run the check. If the current amount of live projectiles equals the maximum, have the logic 'return' and exit out of the method.
I have two issues, when I delete Game Objects with the box tag, it doesn't delete multiple even when I write the line multiple times.
I also found out that when I copy the box prefab with Instantiate, the box collider is disabled even though the prefab has it enabled.
I am fairly new to C# and I don't feel like my code is optimized well, so if anyone could also help with that, I'd greatly appreciate it.
using System.Collections.Generic;
using UnityEngine;
public class RestartLevel : MonoBehaviour
{
float currentLevel = 1f;
public GameObject boxPrefab;
public GameObject firstBox;
Vector3 a = new Vector3(5, 5, 5);
void Update()
{
if (Input.GetButtonDown("Reset"))
{
if (currentLevel == 1f)
{
Destroy(GameObject.FindWithTag("box"));
Destroy(GameObject.FindWithTag("box"));
Destroy(GameObject.FindWithTag("box"));
GameObject newBox = Instantiate(boxPrefab);
newBox.transform.position = a;
}
}
}
}
Code is almost fine. But Destroy() will destroy at the end of the frame.
So your code ...
Destroy(GameObject.FindWithTag("box"));
Destroy(GameObject.FindWithTag("box"));
Destroy(GameObject.FindWithTag("box"));
... will find the SAME object 3 times in the frame. Therefore only one is deleted.
How to solve? Use FindGameObjectsWithTag or delete across multiple frames.
GameObject[] destroyObject;
destroyObject = GameObject.FindGameObjectsWithTag(destroyTag);
foreach (GameObject oneObject in destroyObject)
Destroy (oneObject);
I am creating an endless jumping game. I have created a lot of obstacles to spawn randomly for time and for spaces, but now I want to make the obstacles spawn not in the same place as the previous ones, because they are spawning but sometimes they can spawn on the top of the other or near the others or even inside them, so please help me!
code:
using UnityEngine;
using System.Collections;
public class SpawnObstacles : MonoBehaviour {
public GameObject[] Obstacle;
public float MINTObstacle;
public float MAXTObstacle;
public bool spawning = false;
public Transform pos;
void Update()
{
if (!spawning)
{
StartCoroutine("SpawnObstacle");
}
}
IEnumerator SpawnObstacle()
{
spawning = true;
yield return new WaitForSeconds(Random.Range(MINTObstacle, MAXTObstacle));
Vector2 finalposition = new Vector2(Random.Range(3,7), Random.Range(pos.position.y - 6f, pos.position.y - 6f));
Instantiate(Obstacle[Random.Range(0, Obstacle.Length)], finalposition, Quaternion.identity);
spawning = false;
}
}
I think what you want is some kind of bounding box around each obstacle that represents the "padding" that you want around that obstacle, where no other can be placed. You might use a primitive collider for this purpose.
When you create a new obstacle at a random position, you could check to see if its "padding" collides with another obstacle's "padding", and if so, re-calculate the random position.
One issue I foresee if if you have a very crowded space, this check might have to be re-done many many times before a valid location is found. You may want to limit the number of checks it can do, and if it doesn't find a valid spot it just doesn't spawn the object after 20 tries or so.
so i have an old code for a "Connect4" game it was written years ago, now i am having a big problem getting it results and rebuild them for a unity3D project.
the problem is that every gameObject (i've managed to instanciate in the scene) is, meant to be destroyed and reinstantiated every frame (and i have the feeling that is really more that a frame time); wanting to get the color of each gameobject in time seem to be really challenging, i am supposed now to not enter the code created i am only supposed to get the information from what i get as graphical results.
so now i have a board of boxes having a grid disposition that changes colors according to the player turns (red for the cp and yellow for the plyer).
i created a fixed boxes having colliders and wanted to get the game objects colliding with it everyframe but i failed .
PS: i tested this code and every solution i found in this community hope to find somehelp, thank you.
using UnityEngine;
using System.Collections;
public class SelectorCode : MonoBehaviour
{
public Collision other;
public GameObject GO;
void OnTriggerEnter(Collider other)
{
GO = other.gameObject;
}
void OnTriggerStay(Collider other)
{
GO = other.gameObject;
}
void OnTriggerExit(Collider other)
{
GO = other.gameObject;
}
void Update()
{
GO = this.other.gameObject;
}
}
First make sure the object to which the SelectorCode component is attached has a trigger collider (property "Is Trigger" is checked).
Next you'll get an error in the Updatemethod with GO = this.other.gameObject; since other is never assigned. I think you should remove that line.
Finally, in OnTriggerExit you put in GO the object that is leaving your collider, that doesn't make sense, you should probably assign GO to null at this point :
void OnTriggerExit(Collider other)
{
if (other.gameObject == GO)
{
GO = null;
}
}