- Home /
Random select from array and spawn
Hi,
I have a very simple game where the player has to fly a helicopter from city to city. The game is in 3d. The helicopter flies over a plane with a map texture applied to it. Each time the player reaches a city, he gets the task to fly to the next city and so on.
I want to have a long list of cities that get chosen at random as the next target city to fly to. The cities are represented as a floating cube above my map. So I think I need to create an array which holds the city name and the respective coordinates of that city on my map, so that I can instantiate a new cube each time the player reaches a city.
This is where my problem starts: I have no idea if it is indeed the best way to place these in an array and how I handle the above. Here's my code with comments on where I am having problems:
[edited my original code based on some of the comments. Same problems exist. Help appreciated!]
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PlayerController : MonoBehaviour
{
public float speed;
public float smooth = 2.0F;
public GUIText countText;
public GUIText targetCity;
private int count;
void Start()
{
List<MyCities> mycities = new List<MyCities>();
mycities.Add( new MyCities("Maastricht", -5, 3, -1 )); // The transform position values of my cities are listed in the inspector as X: -5.436626 etc. but somehow the list only accepts int values?
mycities.Add( new MyCities("Breda", -6, 3, -2));
mycities.Add( new MyCities("Amsterdam", -2, 3, 4));
SetTargetCity ();
// scoring points & display on screen (works)
count = 0;
SetCountText ();
}
// Player Movement (works)
void FixedUpdate ()
{
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
Vector3 moveDirection= new Vector3 (moveHorizontal, 0, moveVertical);
if (moveDirection != Vector3.zero){
Quaternion newRotation = Quaternion.LookRotation(moveDirection * -1);
transform.rotation = Quaternion.Slerp(transform.rotation, newRotation, Time.deltaTime * smooth);
rigidbody.AddForce(movement * speed * Time.deltaTime);
}
}
// Score points by flying into city game object (works), switch off that target city game object (works), get new target city...(no idea)
void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "City") {
other.gameObject.SetActive (false); // I used Setactive from a tutorial, but perhaps better to use destroy?
count = count + 1;
SetCountText ();
SetTargetCity ();
}
}
void SetCountText ()
{
countText.text = "Passengers Picked up: " + count.ToString();
}
// What do I put in this void???
void SetTargetCity ()
{
randomCity = Random.Range[0,mycities.Count]; //this doesn't seem to work
targetCity.text = "Fly to: " + randomCity.name.ToString();
// how do I instantiate a new random city here?
}
}
And the other script MyCities.cs is as follows:
using UnityEngine;
using System.Collections;
public class MyCities
{
public string name;
public float xcor;
public float zcor;
public float ycor;
public MyCities(string newName, float newXcor, float newZcor, float newYcor)
{
name = newName;
xcor = newXcor;
zcor = newZcor;
ycor = newYcor;
}
}
While working some more on the above, I have now created a list of instances of a prefab, each of which represent a city. Same problem remains: how do I select any of the prefabs at random and have the player fly to that city?
It would be easiest to help you if you edited your question to reflect the updated code.
The above code hasn't changed...I just worked on creating the prefabs, but that doesn't solve my problem...I don't know if using prefabs is even the right way to approach this.
void SetTargetCity() should do the following:
1 randomly select from a list of objects that represent cities and their coordinates
2 put a that city object on the right coordinates on the map.
3 Update the targetCity.text with the name of the chosen city.
Hope this clarifies what my problem / question is....
Random.range, List tutorial, Instantiate. Have you read the materials for these and have a specific question?
Yes....to my understanding, Random.range doesn't apply as I know what the x,y coordinates of each city instance is.
$$anonymous$$ore specifically: I want to know how to store a list of cities and their coordinates so that I can randomly pick one in a function called SetTargetCity() and instantiate that specific city as a gameobject in my scene so that the player can fly to it, collide with the object so that the function starts over, picks a new city from my list etc. etc.
Hope I am clear...have read so many examples that do not seem to apply that I am feeling lost. Not sure how to explain my question more clearly than I already have....
Answer by Faradday · Mar 25, 2014 at 03:27 AM
void SetTargetCity ()
{
var randomCity = mycities[Random.Range(0,mycities.Count-1)];
targetCity.text = "Fly to: " + randomCity.name.ToString();
GameObject instancedCity=(GameObject)GameObject.Instantiate(cityPrefab);
instancedCity.transform.position=new Vector3(randomCity.xcor,randomCity.ycor,randomCity.zcor);
}
Try this, it should work. Also, you'll need to make a prefab of your city cube. Then connect it to this script by adding another parameter in it:
public GameObject cityPrefab;
Once linked the prefab to the script, it should work.
About the float coordinates not working, have you added "f" after their values? Like, "-5.436626f"
Thanks so much Faradday. I am however getting some errors in the randomCity function: "the name mycities does not exist in the document" I think this is because I need to do more when I set up the list...don't know what...
I think I am missing something when I declare / populate the list in the beginning of the script:
void Start()
{
List<$$anonymous$$yCity> mycities = new List<$$anonymous$$yCity>();
mycities.Add( new $$anonymous$$yCity("$$anonymous$$aastricht", -5F, 3F, -1F ));
mycities.Add( new $$anonymous$$yCity("Breda", -6F, 3F, -2F));
mycities.Add( new $$anonymous$$yCity("Amsterdam", -2F, 3F, 4F));
I think I need to do something else to the above code, but I don't know what. Also, the class is defined as follows:
using UnityEngine; using System.Collections;
public class $$anonymous$$yCity { public string name; public float xcor; public float zcor; public float ycor;
public $$anonymous$$yCity(string newName, float newXcor, float newZcor, float newYcor)
{
name = newName;
xcor = newXcor;
zcor = newZcor;
ycor = newYcor;
}
}
$$anonymous$$y bad, your class is fine. But you have to declare the list outside of any function in order to make it accessible from anywhere in the script. Something like:
List<$$anonymous$$yCity> mycities = new List<$$anonymous$$yCity>();
void Start()
{
mycities.Add( new $$anonymous$$yCity("$$anonymous$$aastricht", -5F, 3F, -1F ));
mycities.Add( new $$anonymous$$yCity("Breda", -6F, 3F, -2F));
mycities.Add( new $$anonymous$$yCity("Amsterdam", -2F, 3F, 4F));
As a rule of thumb, everything you declare is restricted to a "scope". Declaring a variable inside a function will make that function its scope, and therefore it won't be accessible outside of that function. Ins$$anonymous$$d, declaring it inside your class will make it accessible from anywhere inside that class. If you make it public, you could access it from other classes as well, as long as they're referencing that class.
That did the trick! Thank you so much! This was costing me so many headaches....you saved the day!
Faradday: just checked back in here to let you know that your help was crucial in getting my game up and running! A big thanks for that! As of yesterday, the free and paid versions of my game are in the AppStore. It' called City Chopper if you want to check it out. Thanks man!
Your answer
Follow this Question
Related Questions
Spawning Objects Using An Array. 1 Answer
How to fix some of location have more than 1 object? 2 Answers
Calling random functions 4 Answers