/// <summary>
 /// Draws gizmos to show the shape of the spawn area
 /// </summary>
 /// <param name="props"></param>
 /// <param name="origin"></param>
 /// <param name="quantity"></param>
 /// <param name="size"></param>
 public static void DrawGizmos(MMSpawnAroundProperties props, Vector3 origin, int quantity, float size, Color gizmosColor)
 {
     Gizmos.color = gizmosColor;
     for (int i = 0; i < quantity; i++)
     {
         Gizmos.DrawCube(SpawnAroundPosition(props, origin), SpawnAroundScale(props) * size);
     }
 }
 public static void ApplySpawnAroundProperties(GameObject instantiatedObj, MMSpawnAroundProperties props, Vector3 origin)
 {
     // we randomize the position
     instantiatedObj.transform.position = SpawnAroundPosition(props, origin);
     // we randomize the rotation
     instantiatedObj.transform.rotation = SpawnAroundRotation(props);
     // we randomize the scale
     instantiatedObj.transform.localScale = SpawnAroundScale(props);
 }
        /// <summary>
        /// Returns the position at which the object should spawn
        /// </summary>
        /// <param name="props"></param>
        /// <param name="origin"></param>
        /// <returns></returns>
        public static Vector3 SpawnAroundPosition(MMSpawnAroundProperties props, Vector3 origin)
        {
            // we get the position of the object based on the defined plane and distance
            Vector3 newPosition;

            if (props.Shape == MMSpawnAroundProperties.MMSpawnAroundShapes.Sphere)
            {
                float distance = Random.Range(props.MinimumSphereRadius, props.MaximumSphereRadius);
                newPosition = Vector3.Cross(Random.insideUnitSphere, props.NormalToSpawnPlane);
                newPosition.Normalize();
                newPosition *= distance;
            }
            else
            {
                float randomX = Random.Range(props.MinimumCubeBaseSize.x, props.MaximumCubeBaseSize.x);
                newPosition.x = Random.Range(-randomX, randomX) / 2f;
                float randomY = Random.Range(props.MinimumCubeBaseSize.y, props.MaximumCubeBaseSize.y);
                newPosition.y = Random.Range(-randomY, randomY) / 2f;
                float randomZ = Random.Range(props.MinimumCubeBaseSize.z, props.MaximumCubeBaseSize.z);
                newPosition.z = Random.Range(-randomZ, randomZ) / 2f;
                newPosition   = Vector3.Cross(newPosition, props.NormalToSpawnPlane);
            }

            float randomOffset = Random.Range(props.MinimumNormalAxisOffset, props.MaximumNormalAxisOffset);

            // we correct the position based on the NormalOffsetCurve
            if (props.UseNormalAxisOffsetCurve)
            {
                float normalizedOffset = 0f;
                if (randomOffset != 0)
                {
                    if (props.InvertNormalOffsetCurve)
                    {
                        normalizedOffset = MMMaths.Remap(randomOffset, props.MinimumNormalAxisOffset, props.MaximumNormalAxisOffset, 1f, 0f);
                    }
                    else
                    {
                        normalizedOffset = MMMaths.Remap(randomOffset, props.MinimumNormalAxisOffset, props.MaximumNormalAxisOffset, 0f, 1f);
                    }
                }

                float offset = props.NormalOffsetCurve.Evaluate(normalizedOffset);
                offset = MMMaths.Remap(offset, 0f, 1f, props.NormalOffsetCurveRemapZero, props.NormalOffsetCurveRemapOne);

                newPosition *= offset;
            }
            // we apply the normal offset
            newPosition += props.NormalToSpawnPlane.normalized * randomOffset;

            // relative position
            newPosition += origin;

            return(newPosition);
        }
 /// <summary>
 /// Returns the rotation at which the object should spawn
 /// </summary>
 /// <param name="props"></param>
 /// <returns></returns>
 public static Quaternion SpawnAroundRotation(MMSpawnAroundProperties props)
 {
     return(Quaternion.Euler(MMMaths.RandomVector3(props.MinimumRotation, props.MaximumRotation)));
 }
 /// <summary>
 /// Returns the scale at which the object should spawn
 /// </summary>
 /// <param name="props"></param>
 /// <returns></returns>
 public static Vector3 SpawnAroundScale(MMSpawnAroundProperties props)
 {
     return(MMMaths.RandomVector3(props.MinimumScale, props.MaximumScale));
 }