Announcement

Collapse
No announcement yet.

Spawn actor on ground within radius of a given location

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Spawn actor on ground within radius of a given location

    I'm looking to write a script that can spawn an actor at a random location within a given radius of a location. And also so that it is on the floor (not floating in the air or under the floor).

    I'm a bit of a noob working with these kinds of scripts. Could anyone offer some advice as to how I should attempt this?

    Thanks in advance

    #2
    I'd recommend writing it up as a function that takes a vector and the radius as inputs and returns the spawned actor (or None if one couldn't be spawned).

    Code:
    function Actor SpawnActorNearLocation(vector SpawnRadiusCenter, float SpawnRadius)
    {
          /// Logic
    }
    Generating a random vector is a pretty elementary exercise. There are lots of ways you could explore doing it, with varying effects. One method would be to work in polar coordinates, picking a random angle Theta between [0, 2 Pi], and a random length between [0, Radius]. Those, plus your starting location, will give you a random location somewhere within your radius.

    To place the actor on the floor, you'll want to pick a random location and then trace straight down until you hit something. Then, you just need to spawn the actor itself at the location found by the Trace function.

    The functions Trace() and Spawn() can both be found in Actor.uc

    Comment


      #3
      You can try by using:

      native final function bool FindSpot(vector BoxExtent, out vector SpotLocation);

      or if using navMesh, you can use:

      NavigationHandle.GetValidPositionsForBox()

      or create your own Random function:

      Code:
      function vector RandomLocation()
      {
      	local vector result;
      
      	result = BoundingBox.Min;
      	result.X += FRand() * (BoundingBox.Max.X - BoundingBox.Min.X);
      	result.Y += FRand() * (BoundingBox.Max.Y - BoundingBox.Min.Y);
      
      	return result;
      }

      Comment


        #4
        Thanks for the input guys. I know how to do traces from an actor, but how can i do a trace from a location?

        Comment


          #5
          As gastonb mentioned, you should use GetValidPositionsForBox() in the NavigationHandle class. It has all of the functionality you need + it's a fast native function. Win-win!

          Code:
          /**
           * will return a list of valid spots on the mesh which fit the passed extent and are within radius to Pos
           * @param Pos - Center of bounds to check for polys
           * @param Radius - radius from Pos to find valid positions within
           * @param Extent - Extent of entity we're finding a spot for
           * @param bMustBeReachableFromStartPos - if TRUE, only positions which are directly reachable from the starting position will be returned
           * @param ValidPositions - out var of valid positions for the passed entity size
           * @param MaxPositions - the maximum positions needed (e.g. the search for valid positions will stop after this many have been found)
           * @param MinRadius    - minimum distance from center position to potential spots (default 0)
           * @param ValidBoxAroundStartPos - when bMustBeReachableFromStartPos is TRUE, all hits that are within this AABB of the start pos will be considered valid
           */
          native static function GetValidPositionsForBox(Vector Pos, float Radius, Vector Extent, bool bMustBeReachableFromStartPos, out Array<Vector> out_ValidPositions, optional int MaxPositions=-1, optional float MinRadius, optional vector ValidBoxAroundStartPos=vect(0,0,0));

          Comment


            #6
            Great I'll take a look into that, thanks.

            Comment


              #7
              I usually do something like:

              Code:
              function dropPlaceable()
              {
                      local rotator r;
                      local vector p, hitloc, hitnrm;
              
                      r.yaw = rand(64786);
                      p = source + vector(r) * radius;
              
                      trace(hitloc, hitnrm, p + vect(0,0,-100), p);
              
                      if(hitloc != vect(0,0,0))
                          return spawn(class, self, , p, rotator(self - p));
                      else
                         return none;
              }
              of course that being psedo, but the idea is to randomize based on a random roation on the yaw times a radius since I believe the extend would give you box rather than a circle also the trace is to find a valid z but it may need adjustment depending on the actors pivot, and I woudl handle the error somewhere else like:

              Code:
              exec function placeturret()
              {
                     local turret t;
              
                     t = dropPlaceable();
              
                     if(t != none)
                           myTurrent = t;
                     else
                          Playsound(placementerrorcue);      
              }

              Comment


                #8
                There is a grass spawn script , somewhere wich does exacly what you want. very physical.

                Comment


                  #9
                  https://forums.epicgames.com/threads...untime-Foliage

                  here is the post Neongho mentions.

                  Comment

                  Working...
                  X