I need to do a "retry" option when the player finishes the game.For doing this I thought to reset the lists of Monsters and other objects that moved at the first playing or which have been "killed".for example I have a list like that:
//the enemy1 class is already done
// in Game1 I declare it
List<enemy1> enem1 = new List<enemy1>();
//Initialize method
List<enemy1> enem1 = new List<enemy1>();
//LoadContent
foreach (enemy1 enemy in enem1)
{
enemy.Load(Content);
}
enem1.Add(new enemy1(Content.Load<Texture2D>("enemy"), new Vector2(5900, 12600)));
//Update
foreach (enemy1 enemy in enem1)
{
enemy.Update(gameTime);
}
//after being shooted the enemies disappear and i remove them
//if the monsters are shooted the bool "visible" goes from false to true
for (int i = enem1.Count - 1; i >= 0; --i)
{
if (enem1[i].visible == true)
enem1.RemoveAt(i);
}
//Draw
foreach (enemy1 enemy in enem1)
{
if(enemy.visble==false)
{
enemy.Draw(spriteBatch, gameTime);
}
}
//So my problem is to restart the game.
if(lost==true)
{
//here I have to put the code that restore the list
//I tried:
foreach (enemy1 enemy in enem1)
{
enemy.visible=false;
}
}
}
}
they should be drawn again but if I removed them they won't be drawn anymore.If I don't remove them ,instead, the enemies are in different places (because they follow me).
Any suggestions to restore or reinitialize the list??
I'm not sure if I understood your question right but...
When restarting the game you could just empty the list
enem1.Clear();
and then refill it like you do at the first start of the game:
enem1.Add(new enemy1(....));
Related
First of all, i created a GIF to show what is currently happen.
GIF with my current problem
and
Awhat I want
I have a List of GameObject which add the bodyParts temp and Instantiate it in the correct time and position.
Now this is working like expected, but i want this new bodyParts below another object instead of above.
As you can see the Head is "under" the new body parts, but it should always on Top and every new part should spawn under the next. (only should looks like! I dont want to change the Z position.)
i tried :
bodyParts.transform.SetAsFirstSibling();
to change the Hierarchy, but this do nothing. I also can drag and drop the Clones to a other position in Hierarchy but they just stay at the same position (above another).
Is this possible and what should i have to do?
Here some of my Code which makes the process:
private void CreateBodyParts()
{
if (snakeBody.Count == 0)
{
GameObject temp1 = Instantiate(bodyParts[0], transform.position, transform.rotation, transform);
if (!temp1.GetComponent<MarkerManager>())
temp1.AddComponent<MarkerManager>();
if (!temp1.GetComponent<Rigidbody2D>())
{
temp1.AddComponent<Rigidbody2D>();
temp1.GetComponent<Rigidbody2D>().gravityScale = 0;
}
snakeBody.Add(temp1);
bodyParts.RemoveAt(0);
}
MarkerManager markM = snakeBody[snakeBody.Count - 1].GetComponent<MarkerManager>();
if (countUp == 0)
{
markM.ClearMarkerList();
}
countUp += Time.deltaTime;
if (countUp >= distanceBetween)
{
GameObject temp = Instantiate(bodyParts[0], markM.markerList[0].position, markM.markerList[0].rotation, transform);
if (!temp.GetComponent<MarkerManager>())
temp.AddComponent<MarkerManager>();
if (!temp.GetComponent<Rigidbody2D>())
{
temp.AddComponent<Rigidbody2D>();
temp.GetComponent<Rigidbody2D>().gravityScale = 0;
}
snakeBody.Add(temp);
bodyParts.RemoveAt(0);
temp.GetComponent<MarkerManager>().ClearMarkerList();
countUp = 0;
}
}
Finally i found the working Solution.
It has nothing to do with which hierarchy order GameObjects spawn in.
Just the Layer and the LayerOrder are responsible for it.
So I give my parent object a specific layer name (manually in the inspector under "Additional Settings" or programmatically)
I chose the programmatic way...
Any newly spawned GameObject that is Child would get a lower number
yourGameObject.GetComponent<Renderer>().sortingLayerID = SortingLayer.NameToID("Player");
yourGameObject.GetComponent<Renderer>().sortingOrder = -snakeBody.Count;
Extremely new to unity and c# after switching across from Python. Once all the balls are scored in my game I want all the 'blockers' (prefabs that I have instantiated) to be removed from the screen and a new set to be spawned randomly on screen in random positions. The blocker prefabs spawn randomly when all balls are scored, however, the old prefabs, besides the one which deletes each time, stay on screen rather than deleting. I have tried looping through the blockers in the code below to delete and I think this is where the issue is as only one game object deletes at this stage:
if (SpawnManager.tempclonecount == 0 )
{
for (int i = 0; i < SpawnManager.blockeramounts; i++)
{
Destroy(gameObject);
}
SpawnManager.tempclonecount = 1;
}
SpawnManager is an empty object which I have used to spawn objects onto the screen, tempclonecount is a variable stating when the old game objects should be removed from the game. This part of the code works well. blockeramounts is the number of prefabs initially on screen and I hoped to loop through the number of prefabs would delete all of the prefabs. It only deletes one. How do I change this?
Here is the code for creating the blockers in spawn manager also, if helpful:
void Update()
{
int blockeramount = Random.Range(2, 7);
blockeramounts = blockeramount;
for (int i = 0; i < blockeramount; i++)
{
int blockerindex = Random.Range(0, blockerPrefabs.Length);
Instantiate(blockerPrefabs[blockerindex], new Vector3(Random.Range(-30, 30), 0, Random.Range(-30, 30)), blockerPrefabs[blockerindex].transform.rotation);
}
}
While reading your description of the problem I got a bit confused by some of the terms you used. That's all fine since you are new to Unity and still learning. What i managed to figure out is that you have a SpawnManager script attached to an empty game object which instantiates your blocker prefabs. Then in another script you are getting the SpawnManager refernce and checking if you should destroy the current ones and instantiate a new set.
First of all what i would do is, after instantiating an object, to store it in an array or a list
...
public List<GameObject> blockers = new List<GameObject>();
...
void Start()
{
...
}
void Update()
{
int blockeramount = Random.Range(2, 7);
blockeramounts = blockeramount;
for (int i = 0; i < blockeramount; i++)
{
int blockerindex = Random.Range(0, blockerPrefabs.Length);
var blocker = Instantiate(blockerPrefabs[blockerindex], new Vector3(Random.Range(-30, 30), 0, Random.Range(-30, 30)), blockerPrefabs[blockerindex].transform.rotation);
blockers.Add(blocker);
}
}
After which i would add a new method which does the check to see how many remaining blockers there are. This method should go inside SpawnManager.
public void CheckAndDeleteBlockers()
{
if (tempclonecount == 0 )
{
foreach(var blocker in blockers)
{
blockers.Remove(blocker);
Destroy(blocker);
}
}
}
And you should call it from the other script with:
...
public SpawnManager spawnManager;
...
void Start()
{
spawnManager = FindOjectOfType<SpawnManager>();
}
//for example
void Update()
{
spawnManager.CheckAndDeleteBlockers();
}
I understand the way you are trying to do this, but let's say that this isn't the correct way. I would suggest that you look up what object pooling is.
NOTE: The creator of the pooling tutorial that I mentioned above is a great source for Unity and C# beginners, so I would recommend that you watch some of his other videos. Good luck in learning Unity.
What I believe is causing your issue, is that your are only specifying one gameObject to be destroyed. You need to call Destroy() on each blocker you instantiated.
Hope my advice helps.
So, firstly, my scene is made out of 9 empty objects each one having spikes that have animation to pop out of the floor. I am making a game where you should avoid spikes and other projectiles. I tested this first with sprite renderer and changing colors, it worked perfectly. But when I want to activate animations using trigger (animations start from empty game state and go to their animations, then after it finishes they return to normal). I've looked trough every thing I could think of and I could not solve this. It always starts animations for 4-6 different animations and start them at the same time, but for some reason: AFTER FIRST SHOWING, every single time after first time spikes appear, 2/3 out of 4/6 always show late but start at same time. Weirdly first time it always works greatly. Any thoughts on what may cause this?
void Update()
{
if (spikeTimer > 0)
spikeTimer -= Time.deltaTime;
if (spikeTimer<0)
{
Function();
spikeTimer = spikeCooldown;
}
}
public void Function()
{
int x = Random.Range(4, 6);
List<int> included = new List<int>();
while (included.Count < x)
{
int y = Random.Range(1, 10);
if (!included.Contains(y))
{
included.Add(y);
}
}
foreach (int i in included)
{
print("aktiviran je broj" + i);
Spikes[i - 1].GetComponent<Spike>().ActivateSpike();
}
}
Now this is the ActivateSpike method that all Spikes in the scene contain
public void ActivateSpike()
{
SpriteRenderer sr = gameObject.GetComponent<SpriteRenderer>();
if (sr.color != Color.black)
{
sr.color = Color.black;
}
else
sr.color = Color.red;
/* Animator animator = gameObject.GetComponent<Animator>();
animator.SetTrigger("Activate");*/
}
You can see that I tried changing the sprite to square and changing its color, and it works perfectly...
I am making find a difference game. I made a ray that hits an image with collider and changes certain text property. Problem is that where ever i touch the screen it detects a ray, and changes the text. How can i solve that, i also unchecked Raycast Target for all other objects on screen.
public List<GameObject> hiddenObjects;
public Text test;
public Text click;
GameObject[] objekti;
private RaycastHit2D result;
// Start is called before the first frame update
void Start()
{
//This is for a list that will fill with GameObjects
objects= GameObject.FindGameObjectsWithTag("Slike");
hiddenObjects = new List<GameObject>();
for (int i = 0; i < objects.Length; i++)
{
hiddenObjects.Add(objects[i]);
}
}
// Update is called once per frame
void Update()
{
if (Input.touchCount > 0)
{
Vector2 camRay = Camera.main.ScreenToWorldPoint(Input.GetTouch(0).position);
result = Physics2D.Raycast(camRay, (Input.GetTouch(0).position));
if (result.collider.gameObject)
{
click.text = "CLICK";
}
//This is supposed to delete 1 object at time as it is clicked on
for (int j = 0; j < hiddenObjects.Count; j++)
{
if (hiddenObjects[j] = null)
{
hiddenObjects.RemoveAt(j);
}
}
//Simple if statement if list is empty, print "Win"
if (hiddenObjects.Count == 0)
{
test.text = "WIN";
}
}
}
From the information you have provided. I think in those code:
if (result.collider.gameObject)
{
click.text = "CLICK";
}
You need to identify the object that has been hit either by the name property or by comparing a tag.
Let's do it by name for simplicity.
In the left hand side menu in Unity A.K.A "Hierarchy" let's say the GameObject is called "ObjectToDetectHitOn" you would change the above code to:
if (result.collider.gameObject.name.Equals("ObjectToDetectHitOn"))
{
click.text = "CLICK";
}
This will not work if you Instantiate gameobject in code because they will then have (Clone) added to the end of the name. In this scenario you would have to use the .Contains() method of the String class.
The preferred method would be to actually add a tag to the GameObject, let's say you created a tag with the name "ObjectToDetectRay" and use the code like this:
if (result.collider.gameObject.CompareTag("ObjectToDetectRay"))
{
click.text = "CLICK";
}
Let me know if this doesn't work or if it is unclear and I will try to explain further.
Okay, so I'm making a 2D platform game and I'm coming to the finishing stages. I've got the bullets firing, and my AI working etc. However I'm having an issue where when I try and see if the bullet's bounding box is colliding with the enemies, then it should kill the enemies. However they don't collide - I have to checked by console.writeline to see if the boundingbox for the spell is getting updating, which it is, and the same for the enemy. the code for the collision is this:
foreach (EnemyClass enemy in enemies)
{
for (int i = 0; i < spells.Count; i++)
{
if (enemy.collisionBox.Intersects(spells[i].boundingBox))
{
Console.WriteLine("Collision");
enemy.enemyHP -= spells[i].damageToDeal;
spells.ElementAt(i).isVisible = false;
}
if (enemy.enemyHP == 0)
{
enemy.isAlive = false;
}
}
}
This is the Update function that is in the spell class:
public void Update(GraphicsDevice graphics)
{
boundingBox = new Rectangle((int)position.X, (int)position.Y, 15, 15);
}
Fixed it - thanks for peoples help. It was a problem with the y-coordinate of the spells bounding box - I never thought to check it since collision in my game is all based around the x coordinate