Search Unity

Spawning Outside a Radius and Inside Another Radius

Discussion in 'Getting Started' started by nicobacay19, Oct 13, 2019 at 12:39 AM.

  1. nicobacay19

    nicobacay19

    Joined:
    Sunday
    Posts:
    5
    Hello Unity Users,

    I just recently learned how to make games with unity, usually, I just find my answers in forums and youtube videos but this time I really can't find anything about this problem.

    Here's what I'm trying to do.
    I want my object to only spawn in the green zone and not in the red zone or beyond the green zone.
    my code currently allows me to spawn my object inside the green and the red zone.

    upload_2019-10-13_7-36-1.png

    Code (CSharp):
    1.     void Update()
    2.     {
    3.        
    4.         transform.position = new Vector2(Random.Range(CellLoc.x-3,CellLoc.x+3),Random.Range(CellLoc.y-3,CellLoc.y+3));
    5.         SpawnEvolutionEssense();
    6.     }
    7.  
    8.     void SpawnEvolutionEssense()
    9.     {
    10.         int rand = Random.Range(1, 50);
    11.         if(rand == 1)
    12.         {
    13.             Instantiate(EvolutionEssence, transform.position, Quaternion.identity);
    14.         }
    15.     }
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    8,194
    This problem is hard in Cartesian (x/y) coordinates, but easy in polar (angle/radius) coordinates. So, use Random.Range(0, Mathf.PI*2) to pick an angle (in radians), and Random.Range(innerRadius, outerRadius) to pick a radius. Then just use sine and cosine to convert these to x/y coordinates. (x = Mathf.Cos(ang)*r, y = Mathf.Sin(ang)*r.)

    (And you thought you'd never use that high-school math! :p )
     
    Ryiah and nicobacay19 like this.
  3. nicobacay19

    nicobacay19

    Joined:
    Sunday
    Posts:
    5
    I understand the logic behind your response. I feel like it will really work. My problem is that I have no idea how to code that. I would really appreciate it if I get help from anyone with that. For now, I'm gonna try and search it up. I may get an answer somewhere. I will reply to this thread again with the code I made. Thanks a lot :)
     
  4. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    8,194
    I doubt that searching will turn up more than I gave you. But I gave you all the tricky bits. And you already showed you know how to use Random.Range in your code. So I'm not certain where the confusion lies.

    I think you should just roll up your sleeves and give it a try. And then, please do post here the code you come up with. If it's right, we'll give you well-deserved congrats; if not, we'll give you kudos for trying and be able to help with whatever the point of confusion turns out to be.
     
    nicobacay19 likes this.
  5. nicobacay19

    nicobacay19

    Joined:
    Sunday
    Posts:
    5
    You're right. I could not find any tutorial or thread about it at all. I'm really new at this, about a month I think, that's why there are still lots of things that I do not understand. I think I am very close to solving this one. I'll be posting my code later :) Thanks a lot

    PS: I am confused about how to use this (x = Mathf.Cos(ang)*r, y = Mathf.Sin(ang)*r.)
     
  6. nicobacay19

    nicobacay19

    Joined:
    Sunday
    Posts:
    5
    It worked! Thank you!
    But now I have a different problem.
    My previous code allowed me to spawn the objects from the blue circle(which constantly moves around).
    My new code only allows the objects to spawn from the center of the screen.
    When the blue circle moves the spawn area stays the same.


    Code (CSharp):
    1. public class EvolutionEssenceSpawner : MonoBehaviour
    2. {
    3.     public GameObject EvolutionEssence;
    4.     Vector2 CellLoc;
    5.     float randRad;
    6.     float randDist;
    7.  
    8.     // Start is called before the first frame update
    9.     void Start()
    10.     {
    11.         CellLoc = GameObject.FindGameObjectWithTag("CellBubble").transform.position;
    12.     }
    13.  
    14.     // Update is called once per frame
    15.     void Update()
    16.     {
    17.         randRad = Random.Range(0, Mathf.PI * 2);
    18.         randDist = Random.Range(6, 10);
    19.  
    20.         transform.position = new Vector2(Mathf.Cos(randRad),Mathf.Sin(randRad))*randDist;
    21.         SpawnEvolutionEssense();
    22.         //transform.position = new Vector2(Random.Range(CellLoc.x-3,CellLoc.x+3),Random.Range(CellLoc.y-3,CellLoc.y+3));
    23.     }
    24.  
    25.     void SpawnEvolutionEssense()
    26.     {
    27.         int rand = Random.Range(1, 2);
    28.         if(rand == 1)
    29.         {
    30.             Instantiate(EvolutionEssence, transform.position, Quaternion.identity);
    31.         }
    32.     }
    33.  
    34. }
     
  7. damonp

    damonp

    Joined:
    Dec 7, 2012
    Posts:
    8
    Another solution to the initial question is to use Random.insideUnitCircle like this:
    Code (CSharp):
    1. transform.position = Random.insideUnitCircle.normalized * Random.Range(innerRadius, outerRadius);
     
    nicobacay19 and Ryiah like this.
  8. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    8,194
    You just need to add the desired spawn center to the coordinates you calculate. So change:

    Code (CSharp):
    1.      transform.position = new Vector2(Mathf.Cos(randRad),Mathf.Sin(randRad))*randDist;
    to:

    Code (CSharp):
    1.      transform.position = CellLoc + new Vector2(Mathf.Cos(randRad),Mathf.Sin(randRad))*randDist;
    P.S. Congratulations on writing that code! :)
     
    nicobacay19 likes this.
  9. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    14,540
    Neat. I never knew this existed but now that I'm looking at it I love how there is one for spheres and even one for placing stuff on the surface of a sphere.
     
    nicobacay19 and damonp like this.
  10. nicobacay19

    nicobacay19

    Joined:
    Sunday
    Posts:
    5
    Thank you, friends, for the help. I finally got it to work. I learned what and how to use polar coordinates and "Random.insideUnitCircle" in this thread.

    I got an error when I tried Random.insideUnitCircle but I found an answer here.
    Here's my final code.

    I tried to use the variable I made "CellLoc" but it does not seem to work so I just used the raw code(dunno how it is called) instead which is "GameObject.FindGameObjectWithTag("CellBubble").transform.position". I don't understand why is it not working if I use a variable.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.SceneManagement;
    5.  
    6. public class EvolutionEssenceSpawner : MonoBehaviour
    7. {
    8.     public GameObject EvolutionEssence;
    9.     //Vector3 CellLoc;
    10.     Vector3 RandRange;
    11.  
    12.     // Start is called before the first frame update
    13.     void Start()
    14.     {
    15.         //CellLoc = GameObject.FindGameObjectWithTag("CellBubble").transform.position;
    16.        
    17.     }
    18.  
    19.     // Update is called once per frame
    20.     void Update()
    21.     {
    22.         if(SceneManager.GetActiveScene().name != "StartMenu")
    23.         {
    24.             SpawnEvolutionEssense();
    25.             RandRange = (Vector3)Random.insideUnitCircle.normalized * Random.Range(4, 4);
    26.             transform.position = GameObject.FindGameObjectWithTag("CellBubble").transform.position + RandRange;
    27.         }
    28.     }
    29.  
    30.     void SpawnEvolutionEssense()
    31.     {
    32.         int rand = Random.Range(1, 2);
    33.         if(rand == 1)
    34.         {
    35.             Instantiate(EvolutionEssence, transform.position, Quaternion.identity);
    36.         }
    37.     }
    38.  
    39. }
    40.