Using Mathf.round for a vector3?

hello, I would like to know how to round to the nearest.5 for all vectors. meaning…

vector3(1.263, 2.2, 3);
will now be
vector3(1.5 , 2, 3);
I have tried and also searched for an answer, I keep coming up empty.

5 Answers

5

Create this class:

static class ExtensionMethods
{
	/// <summary>
	/// Rounds Vector3.
	/// </summary>
	/// <param name="vector3"></param>
	/// <param name="decimalPlaces"></param>
	/// <returns></returns>
	public static Vector3 Round(this Vector3 vector3, int decimalPlaces = 2)
	{
		float multiplier = 1;
		for (int i = 0; i < decimalPlaces; i++)
		{
			multiplier *= 10f;
		}
		return new Vector3(
			Mathf.Round(vector3.x * multiplier) / multiplier,
			Mathf.Round(vector3.y * multiplier) / multiplier,
			Mathf.Round(vector3.z * multiplier) / multiplier);
	}
}

and now you can use it in whole project. Usage example:

vector3 = new Vector3(1.23243f, 2.213124f, 12.4123f);
var roundedVector3 = vector3.Round(1);

Nice one! I keep a collection of extension methods like this. I like solving a problem only once.

Below are my Vector3 extension methods to snap a position to a grid. To solve your problem you’d do

vec = vec.SnapToGrid(0.5f);

The first one is just a simple snap, and the 2nd one allows you to offset your position from the grid. It first adds on an offset, then snaps, then reverses the offset.

public static class GmVector3Extensions
{
    /// <summary>
    /// Snap Vector3 to nearest grid position
    /// </summary>
    /// <param name="vector3">Sloppy position</param>
    /// <param name="gridSize">Grid size</param>
    /// <returns>Snapped position</returns>
    public static Vector3 Snap(this Vector3 vector3, float gridSize = 1.0f)
    {
        return new Vector3(
            Mathf.Round(vector3.x / gridSize) * gridSize,
            Mathf.Round(vector3.y / gridSize) * gridSize,
            Mathf.Round(vector3.z / gridSize) * gridSize);
    }

    /// <summary>
    /// Snap Vector3 to nearest grid position with offset
    /// </summary>
    /// <param name="vector3">Sloppy position</param>
    /// <param name="gridSize">Grid size</param>
    /// <returns>Snapped position</returns>
    public static Vector3 SnapOffset(this Vector3 vector3, Vector3 offset, float gridSize = 1.0f)
    {
        Vector3 snapped = vector3 + offset;
        snapped = new Vector3(
            Mathf.Round(snapped.x / gridSize) * gridSize,
            Mathf.Round(snapped.y / gridSize) * gridSize,
            Mathf.Round(snapped.z / gridSize) * gridSize);
        return snapped - offset;
    }
}

Thanks! I was definitely overthinking this.

have you tried:

Vector3 newVector3 = new Vector3(Mathf.Round(oldVector3.x10f)/10f, Mathf.Round(oldVector3.y10f)/10f, Mathf.Round(oldVector3.z*10f)/10f)

?

edit: because Vector3 is struct and i don’t see any simple way how to round it

var vec = Vector3(1.263, 2.2, 3);
vec *= 2.0;
vec = Vector3(Mathf.Round(vec.x), Mathf.Round(vec.y), Mathf.Round(vec.z));
vec /= 2.0;

Okay thank you kom and rob. Rob, can you explain what Each bidt does? (Exept setting the var.) Im not sure what vec *= 2 is for and all that. I under stand what lien 3 does though. also does that round to nearest .5?

This code rounds to the nearest .5. The second line can be rewritten as: vec = vec * 2.0; So it multiplies each of the components by 2.0. So the resulting vector would be (2.526, 4.4, 6); Line 3 rounds the values, so the result is (3.0, 4.0, 6.0); The last line can be rewritten as: vec = vec / 2.0; And the result at the (1.5, 2.0, 3).

Holy crap (Please escuse my language) Thank you!, I will test this out later.

More logical and clear would be first divide by .5 and then multiply by .5, because instead of ".5" there could be a variable.

public static Vector3 Round(Vector3 vector3)
{

          Vector3 resultVector=new Vector3();
         if ((Mathf.Ceil(vector3.x) + Mathf.Floor(vector3.x)) / 2.0f-vector3.x<vector3.x-Mathf.Floor(vector3.x)&& (Mathf.Ceil(vector3.x) + Mathf.Floor(vector3.x)) / 2.0f < Mathf.Ceil(vector3.x)-vector3.x)
          {
               resultVector.x = (Mathf.Ceil(vector3.x) + Mathf.Floor(vector3.x)) / 2.0f;
          }
          else
          {
               resultVector.x = Mathf.Round(vector3.x);

          }
          if ((Mathf.Ceil(vector3.y) + Mathf.Floor(vector3.y)) / 2.0f - vector3.y < vector3.y - Mathf.Floor(vector3.y) && (Mathf.Ceil(vector3.y) + Mathf.Floor(vector3.y)) / 2.0f < Mathf.Ceil(vector3.y) - vector3.y)
          {
               resultVector.y = (Mathf.Ceil(vector3.y) + Mathf.Floor(vector3.y)) / 2.0f;
          }
          else
          {
               resultVector.y = Mathf.Round(vector3.y);

          }
          if ((Mathf.Ceil(vector3.z) + Mathf.Floor(vector3.z)) / 2.0f - vector3.z < vector3.z - Mathf.Floor(vector3.z) && (Mathf.Ceil(vector3.z) + Mathf.Floor(vector3.z)) / 2.0f < Mathf.Ceil(vector3.z) - vector3.z)
          {
               resultVector.z = (Mathf.Ceil(vector3.z) + Mathf.Floor(vector3.z)) / 2.0f;
          }
          else
          {
               resultVector.z = Mathf.Round(vector3.z);

          }

          return resultVector;
              
     }