Spawning Meteors at random locations and setting appropriate velocity

So I’ve put together some code with the aim to spawn a randomly selected Meteor at a randomly selected location, and based upon the x and y co-ordinates, set the velocity to either be positive or negative.

The problem that I’m encountering is that the CalculateSpawn & CalculateDirection functions have to return values that are not void and I’m not entirely sure how I would go about doing so.

Thanks in advance!

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MeteorSpawner : MonoBehaviour {

    public float width = 18f;
    public float height = 10f;

	private float leftBoundary;
	private float rightBoundary;
	private float topBoundary;
	private float bottomBoundary;
	private float leftSpawn;
	private float rightSpawn;
	private float topSpawn;
	private float bottomSpawn;

    public float meteorSpeedX;
	public float meteorSpeedY;

	public Vector2 meteorSpawn;

	public GameObject meteorBigOne;
	public GameObject meteorBigTwo;
	public GameObject meteorBigThree;
	public GameObject meteorBigFour;
	public GameObject meteorMedOne;
	public GameObject meteorMedTwo;
	public GameObject meteorSmallOne;
	public GameObject meteorSmallTwo;

	public float timeRemaining = 20f;
	public float startTime = 20f;

	int randomMeteor;
	int randomSpawn;

	public void OnDrawGizmos()
    {
	    Gizmos.DrawWireCube(transform.position, new Vector3(width,height,0));
	}

    public void CalculateSpawn()
    {
    	leftBoundary = transform.position.x - (width / 2);
		rightBoundary = transform.position.x + (width / 2);
		topBoundary = transform.position.y + (height / 2);
		bottomBoundary = transform.position.y - (height / 2);
    	leftSpawn = leftBoundary - 3;
		rightSpawn = rightBoundary + 3;
		topSpawn = topBoundary + 3;
    	bottomSpawn = bottomBoundary - 3;

    	randomSpawn = Random.Range(1,4);
    	//spawn left
    	if(randomSpawn == 1){
			Vector2 meteorSpawn = new Vector2(Random.Range(leftBoundary,leftSpawn),Random.Range(topSpawn,bottomSpawn));
    	}
    	//spawn right
		if(randomSpawn == 2){
			Vector2 meteorSpawn = new Vector2(Random.Range(rightBoundary,rightSpawn),Random.Range(topSpawn,bottomSpawn));
    	}
    	//spawn bottom
		if(randomSpawn == 3){
			Vector2 meteorSpawn = new Vector2(Random.Range(leftSpawn,rightSpawn),Random.Range(bottomBoundary,bottomSpawn));
    	}
    	//spawn top
		if(randomSpawn == 4){
			Vector2 meteorSpawn = new Vector2(Random.Range(leftSpawn,rightSpawn),Random.Range(topBoundary,topSpawn));
    	}

    }

	public void CalculateDirection()
    {
			if(meteorSpawn.x < transform.position.x)
			{
			meteorSpeedX += meteorSpeedX;
			}

			else if(meteorSpawn.x > transform.position.x)
			{
			meteorSpeedX -= meteorSpeedX;
			}

			if(meteorSpawn.y < transform.position.y)
			{
			meteorSpeedY += meteorSpeedY;
			}

			else if(meteorSpawn.y > transform.position.y)
			{
			meteorSpeedY -= meteorSpeedY;
			}

	}

    public void SpawnMeteor()
    {
		randomMeteor = Random.Range(1,80);
		if(randomMeteor <= 10 & randomMeteor >= 1){
			CalculateSpawn();
			GameObject meteor = Instantiate(meteorBigOne, meteorSpawn, Quaternion.identity) as GameObject;
			CalculateDirection();
			meteor.GetComponent<Rigidbody2D>().velocity = new Vector2(meteorSpeedX, meteorSpeedY);
			}
		if(randomMeteor <= 20 & randomMeteor >= 11){
			CalculateSpawn();
			GameObject meteor = Instantiate(meteorBigTwo, meteorSpawn, Quaternion.identity) as GameObject;
			CalculateDirection();
			meteor.GetComponent<Rigidbody2D>().velocity = new Vector2(meteorSpeedX, meteorSpeedY);
			}
		if(randomMeteor <= 30 & randomMeteor >= 21){
			CalculateSpawn();
			GameObject meteor = Instantiate(meteorBigThree, meteorSpawn, Quaternion.identity) as GameObject;
			CalculateDirection();
			meteor.GetComponent<Rigidbody2D>().velocity = new Vector2(meteorSpeedX, meteorSpeedY);
			}
		if(randomMeteor <= 40 & randomMeteor >= 31){
			CalculateSpawn();
			GameObject meteor = Instantiate(meteorBigFour, meteorSpawn, Quaternion.identity) as GameObject;
			CalculateDirection();
			meteor.GetComponent<Rigidbody2D>().velocity = new Vector2(meteorSpeedX, meteorSpeedY);
			}
		if(randomMeteor <= 50 & randomMeteor >= 41){
			CalculateSpawn();
			GameObject meteor = Instantiate(meteorMedOne, meteorSpawn, Quaternion.identity) as GameObject;
			CalculateDirection();
			meteor.GetComponent<Rigidbody2D>().velocity = new Vector2(meteorSpeedX, meteorSpeedY);
			}
		if(randomMeteor <= 60 & randomMeteor >= 51){
			CalculateSpawn();
			GameObject meteor = Instantiate(meteorMedTwo, meteorSpawn, Quaternion.identity) as GameObject;
			CalculateDirection();
			meteor.GetComponent<Rigidbody2D>().velocity = new Vector2(meteorSpeedX, meteorSpeedY);
			}
		if(randomMeteor <= 70 & randomMeteor >= 61){
			CalculateSpawn();
			GameObject meteor = Instantiate(meteorSmallOne, meteorSpawn, Quaternion.identity) as GameObject;
			CalculateDirection();
			meteor.GetComponent<Rigidbody2D>().velocity = new Vector2(meteorSpeedX, meteorSpeedY);
			}
		if(randomMeteor <= 80 & randomMeteor >= 71){
			CalculateSpawn();
			GameObject meteor = Instantiate(meteorSmallTwo, meteorSpawn, Quaternion.identity) as GameObject;
			CalculateDirection();
			meteor.GetComponent<Rigidbody2D>().velocity = new Vector2(meteorSpeedX, meteorSpeedY);
			}
    }

    void ResetTimer(){
			timeRemaining = startTime;
			Debug.Log ("Countdown has been reset!");
			}

	public void Timer(){
		timeRemaining -= Time.deltaTime;
		}

	// Use this for initialization
	void Start () {

		}
	
	// Update is called once per frame
	void Update () {
		Timer ();
		if(timeRemaining <= 0f){
			ResetTimer();
			SpawnMeteor();
			}
	}
}

Hi Arwyn,

void is used as a return type in a method declaration when a method doesn’t return a value.

If you require a method to return a value, you would replace the void return type with the Type you plan to return instead.

For example;

public string GetName()
{
    return "Rob";    // returns a string
}
public string GetFullName()
{
    string fullName;

    fullName = forename + " " + surname;    // assumes forename and surname are member variables

    return fullName;    // returns string
}
public int CalculateSum(int valueOne, int valueTwo)
{
    return valueOne + valueTwo;    // returns an int
}

In the first example, a value of type string is return, in the third, a value of type int.

Be aware that you should also consider validation, for example, validation of parameter values which are passed into a method, and also, those that are returned.

Hope this helps.


See also;

Thanks, I think I understand all that. If I wanted to have the return type as a Vector2, how would I go about doing that? I’ve tried altering the code as below but Unity 2017 returns an error of ‘meteorSpawn’ conflicts with the declaration ‘MeteorSpawner.meteorSpawn’ for the return meteorSpawn; line .

	public Vector2 CalculateSpawn()
    {
    	leftBoundary = transform.position.x - (width / 2);
		rightBoundary = transform.position.x + (width / 2);
		topBoundary = transform.position.y + (height / 2);
		bottomBoundary = transform.position.y - (height / 2);
    	leftSpawn = leftBoundary - 3;
		rightSpawn = rightBoundary + 3;
		topSpawn = topBoundary + 3;
    	bottomSpawn = bottomBoundary - 3;

    	randomSpawn = Random.Range(1,4);

    	//spawn left
    	if(randomSpawn == 1){
			Vector2 meteorSpawn = new Vector2(Random.Range(leftBoundary,leftSpawn),Random.Range(topSpawn,bottomSpawn));
    	}

    	//spawn right
		if(randomSpawn == 2){
			Vector2 meteorSpawn = new Vector2(Random.Range(rightBoundary,rightSpawn),Random.Range(topSpawn,bottomSpawn));
    	}

    	//spawn bottom
		if(randomSpawn == 3){
			Vector2 meteorSpawn = new Vector2(Random.Range(leftSpawn,rightSpawn),Random.Range(bottomBoundary,bottomSpawn));
    	}

    	//spawn top
		if(randomSpawn == 4){
			Vector2 meteorSpawn = new Vector2(Random.Range(leftSpawn,rightSpawn),Random.Range(topBoundary,topSpawn));
    	}

    	return meteorSpawn;

    }

You have meteorSpawn declared as a member variable for the class, and you are then trying to re-declare it (several times) within all of the if statements.

Remove the type from in front of the line in each if statement where you initialise meteorSpawn like this;

meteorSpawn = new Vector2 .... etc

Example from your code;

//spawn left
if(randomSpawn == 1){
    meteorSpawn = new Vector2(Random.Range(leftBoundary,leftSpawn),Random.Range(topSpawn,bottomSpawn));
}

Updated Fri Feb 23 2018 12:59

Just to add, in my example I used the public access modifier, you would only need to use that if you wanted to access these methods from other scripts. If not, you can use private, these would then only be able to be called from within the class itself.

Where you have methods which do not specify an access modifier, they use the default, which in C# is private.

1 Like

Cool, that’s sorted things so that the Meteors now spawn at random points within the four boundary areas. The velocity set to each spawned Meteor is a bit janky however, as they only ever seem to move in one direction and the velocity gets increasingly faster, but I’ll mess about with the code some more and see if I can fix that.

Thanks again for your help! :grinning:

1 Like

Great, well done!

You’re more than welcome :slight_smile:

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms