Search Unity

Random point help?

Discussion in 'Scripting' started by DethRaid, Nov 29, 2010.

  1. DethRaid

    DethRaid

    Joined:
    Aug 29, 2010
    Posts:
    210
    So I have this beautiful little C# script and I'd like to use it to generate 10 random points within 50 units of an object, which will then proced to travel between them. I've gotten up to the point where I need to check whether or not the points I generated are within 50 units of the object. In order to do this, I need to get the location of the object. I've checked the online scripting guide that Unity has, but I can't seem to find it there. Could someone please help?

    Here's the code I have so far (this is all in the Update() method)

    Code (csharp):
    1.  
    2. //variables to hold the x and y value of the point until I check to see if the point is within 50 units of my object
    3. int xCord = 0, yCord = 0;
    4. //array to hold the points I find are valid
    5. int[,] listGather = new int[10, 2];
    6. for( int x = 0; x < 10; x++ )
    7. {
    8.      for( int y= 0; y < 2; y++ )
    9.      {
    10.      //generate random numbers between 1(inclusive) and 50(exclusive)
    11.           xCord = Random.Range(1, 50);
    12.           yCord = Random.Range(1, 50);
    13.      }
    14. }
    15.  
     
  2. Jesse Anders

    Jesse Anders

    Joined:
    Apr 5, 2008
    Posts:
    2,857
    Is 'transform.position' what you're looking for?
     
  3. DethRaid

    DethRaid

    Joined:
    Aug 29, 2010
    Posts:
    210
    Possibly... let me see what it does...

    Yeah... that looks good... Should I replace "transform" with the name of the object I want to get the position of, or will it just pull the location of the object the script is attached to?
     
  4. DethRaid

    DethRaid

    Joined:
    Aug 29, 2010
    Posts:
    210
    Another thing: why can't Unity just use the nice, standard C# commands? Why mustit have its own library? I'm trying to find the square root of a number, and Math.Sqrt() doesn't work. What will?
     
  5. Jesse Anders

    Jesse Anders

    Joined:
    Apr 5, 2008
    Posts:
    2,857
    This.

    (Technically, 'transform' is a property/field of the MonoBehaviour class, which custom components inherit from, either explicitly or implicitly.)

    It's Mathf.Sqrt() (note the 'f'). But, you can use .NET library stuff as well. (I haven't tried using .NET math library functions in Unity, but I assume that you can.)
     
  6. hallamasch

    hallamasch

    Joined:
    Nov 29, 2010
    Posts:
    153

    To make your life simpler you could just do this:
    Code (csharp):
    1.  
    2.  
    3. // Now you are guaranted a random Point, within 50 units of your object.
    4.           xCord = Random.Range(-25, 25);
    5.           yCord = Random.Range(-25, 25);
    6.          
    7. // Now move your object there
    8.           Vector3 pos = tranform.position;
    9.           pos.x += xCord;
    10.           pos.y += yCord;
    11.  
    12. // You will probally want todo somekind of interpolation.
    13.           transform.position = pos;
    14.  
    15.  
    Quick Question: why are you doing this for loop twice:
    Code (csharp):
    1.  
    2.      for( int y= 0; y < 2; y++ )
    3.      {
    4.      //generate random numbers between 1(inclusive) and 50(exclusive)
    5.           xCord = Random.Range(1, 50);
    6.           yCord = Random.Range(1, 50);
    7.      }
    8.  
     
  7. mightymao

    mightymao

    Joined:
    Oct 21, 2009
    Posts:
    108
    Yep, I am not 100 percent sure exactly what you are trying to do, but you may look at the following code to start with:

    Code (csharp):
    1.  
    2.   public GameObject aPointPrefab;
    3.  
    4.   void Awake()
    5.   {
    6.     CreatePoint();
    7.   }
    8.  
    9.   private void CreatePoint()
    10.   {
    11.     //variables to hold the x and y value of the point until I check to see if the point is within 50 units of my object
    12.     int xCord = 0;
    13.     int zCord = 0;
    14.     float distance;
    15.     //array to hold the points I find are valid
    16.     GameObject[,] listGather = new GameObject[10, 2];
    17.     //get a position of an object.  For example, a character
    18.     Vector3 pos = transform.position;
    19.     print("pos.x = " + pos.x.ToString());
    20.     print("pos.z = " + pos.z.ToString());
    21.     for (int x = 0; x < 10; x++)
    22.     {
    23.       for (int y = 0; y < 2; y++)
    24.       {
    25.         //generate random numbers between 1(inclusive) and 50(exclusive)
    26.         xCord = Random.Range((int)pos.x, 50);  //use integer Random instead of float
    27.         zCord = Random.Range((int)pos.z, 50);
    28.         listGather[x, y] = Instantiate(aPointPrefab, new Vector3(xCord, 2, zCord), Quaternion.identity) as GameObject;
    29.         distance = Vector3.Distance(pos, listGather[x, y].transform.position);
    30.         print("Distance = " + distance.ToString());
    31.  
    32.       }
    33.     }
    34.   }
    35.  
    In this case, I use x-cord and z-cord and y = 2. Also, you need to create a prefab object and assign to aPointPrefab in the Inspector. For example, a sphere prefab.
     
    Last edited: Nov 29, 2010
  8. Tom163

    Tom163

    Joined:
    Nov 30, 2007
    Posts:
    1,290
    uh, what's wrong with Random.insideUnitSphere * 50 or Random.insideUnitCircle * 50 ?
     
  9. DethRaid

    DethRaid

    Joined:
    Aug 29, 2010
    Posts:
    210
    Oh boy.. all these programming commands I knew nothing about...

    The idea here is to create a set of ten random points within 50 units of my object, choose the 5 that are closest to a pentagram, and sent the object to them in succession. The whole "sending object" thing will be handled by an adaptation of some of the scripts I already have for A* pathfinding.

    I've updated my code since I last logged on.. here's what i have noe in the Update function:
    Code (csharp):
    1.  
    2. void Update ()
    3. {
    4.      bool valid = true;
    5.      int xCord = 0, yCord = 0, temp = 0;
    6.      int[,] listGather = new int[10, 2];
    7.      for( int x = 0; x < 10; x++ )
    8.      {
    9.           while( !valid )
    10.           {
    11.                xCord = Random.Range(1, 50);
    12.                yCord = Random.Range(1, 50);
    13.                temp = Math.Sqrt(((transform.position.x-xCord)*(transform.position.x-xCord))+((transform.position.y-yCord)*(transform.position.y-yCord)));
    14.                if( temp < 50 )
    15.                {   
    16.                temp = Math.Sqrt(((transform.position.y-yCord)*(transform.position.y-yCord))+((transform.position.y-yCord)*(transform.position.y-yCord)));
    17.                     if( temp < 50 )
    18.                     {  
    19.                          listGather[x][1] = yCord;
    20.                          listGather[x][0] = xCord;
    21.                          valid = false;
    22.                     }
    23.               }
    24.        }
    25. }
    26.  
    Everythign inside the while loop was to check to see if my point is within 50 units of my starting place... Random.insideUnitCircle * 50 seems to be a much better idea, though. Thanks, I didn't really know that was out there. My code recently became much simpler.

    @Hallamasch: the whole idea with the two for loops was to write to each spot in the array... I don't think that that would actually work too well, though, so I got rid of it.

    EDIT: I have a new problem now... I tried declaring a Vector2 variable to hold the data from Random.insideUnitNumber, but i keep getting an error... here's the code:

    Code (csharp):
    1.  
    2. int Vector2 newPosition= Random.insideUnitCircle*50;
    3.  
    The error says "Unexpected symbol 'newPosition' and that I need a ), comma, ;, [, or =... I really don't know what this means.
     
    Last edited: Nov 30, 2010
  10. Chris-Sinclair

    Chris-Sinclair

    Joined:
    Jun 14, 2010
    Posts:
    1,326
    Wouldn't it be easier to calculate the 5 points of a pentagram (and have the pentagram randomly rotated if that's your intent), then apply a small random offset to each of those points? 'Cause if you generate 10 random points like this, I'm worried that:

    A) their distribution won't be pentagram-like at all
    B) analyzing the distribution to discover the 5 points that make the "best" pentagram shape might be overly complex.
    C) The points might not be centralized around your origin point (that is, randomly speaking, they could all be generated to the right of the origin point)
     
  11. DethRaid

    DethRaid

    Joined:
    Aug 29, 2010
    Posts:
    210
    Well, as it is, the object I want to move is right next to a wall, so they'd all need to be on one side of the wall anyways.

    Also, the idea here is that the unit is gathering rescources that are evenly distributed throught the soil, so it seemed to me to be a good idea to give it a somewhat random path, I just want to find the points closest to those of a pentagram so that it has a somewhat smooth path, even though the path will be pretty random and probably ugly. But hey, that's what I'm going for.
     
  12. mightymao

    mightymao

    Joined:
    Oct 21, 2009
    Posts:
    108
    Your statement
    should be

     
  13. DethRaid

    DethRaid

    Joined:
    Aug 29, 2010
    Posts:
    210
    So I did that... now, though, it tells me that the compiler can't implicitly convert a float to an int, but that a conversion does exist. It won't tell me what that conversion is, though. I've searched the Unity scripting guide, as well as google, but I can't seem to find it...

    The problem is in the line listGather[x][1] = pos.x; The purpose of that statement is to write the x value of my point to one space in an array. The array is of ints. Is there a better way to store the data from my ten random points?
     
  14. mightymao

    mightymao

    Joined:
    Oct 21, 2009
    Posts:
    108
    OK, your array has been declared as int, but the pos.x is float. To fix it, change it to this:

    listGather[x][1] = (int)pos.x;

    or

    listGather[x][1] = (int)newPostion.x;