- Home /
Iterating over Vector's axes
(C#) I want to apply an operation on all three of the Vector3's axes, x, y and z. Is there any way I can do it without copy-pasting it three times?
I expected the vector to be IEnumerable
but it isn't, so I can't use foreach
.
Answer by Jessespike · Jul 22, 2016 at 05:49 PM
Vector3's xyz variables are simply floats in a struct. So no you can't use IEnumerator and foreach on them.
What's the problem with performing the operation 3 times? I mean, even if foreach worked, that would still be 3 operations being performed.
Vector3 does however have a public indexer that you can access:
Vector3 v3 = new Vector3();
for (int i = 0; i < 3; i++)
{
v3[i] = Random.Range(0f, 100f);
}
Right, it would also be interesting what kind of "operation" he wants to perform. Vector2/3/4 provide several operators. For example you can "scale" a vector by a float by simply doing:
Vector3 vec;
vec = vec * 5f;
This will multiply each component by "5f". You can't add a single float that way but you can simply do
vec = vec + Vector3.one * 5f;
This will add "5f" to each component.
Thanks, the index is exactly what I was looking for. To be precise, I wanted to use $$anonymous$$athf.round()
on each but I knew I would turn that into something a bit longer and I'll probably use a loop for that because it's not likely it will be a one-liner modification for each variable. And I actually use vector addition and such a lot, this is the first thing where I need to access each variable separately.
The indexer is actually more overhead than doing it for each axis seperately. The indexer uses a switch-statement to address each axis. If you just need a "round" method for Vector3 you can write extension methods like this:
public static class Vector3Extensions
{
public static Vector3 Round(this Vector3 aVec)
{
return new Vector3($$anonymous$$athf.Round(aVec.x), $$anonymous$$athf.Round(aVec.y), $$anonymous$$athf.Round(aVec.z));
}
public static Vector3 Round(this Vector3 aVec, int aDigits)
{
return Round(aVec*aDigits) / aDigits;
}
}
With that class somewhere in your project you can simply do this:
Vector3 vec = new Vector3(1.1234f, 2.55555f, 3.987654f);
Vector3 vec2 = vec.Round(); // (1.0f, 3.0f, 4.0f);
Vector3 vec3 = vec.Round(2); // (1.12f, 2.56f, 3.99f);
$$anonymous$$eep in $$anonymous$$d that Vector3 uses float variables and a lot numbers can't be represented exactly. If you need to work with whole numbers you might want to use your own struct that uses ints ins$$anonymous$$d of floats and implement some casting operators to easily convert a Vector3 to your custom struct.
I've once written a struct like that: Vector3i. It provides pretty much the same methods and operators as Vector3. You can also simply cast between those two types:
Vector3 vec = new Vector3(1.1234f, 2.55555f, 3.987654f);
Vector3i v = vec; // v == (1, 3, 4)
Vector3 v2 = v; // v2 == (1.0f, 3.0f, 4.0f)
The round is simply for aligning that vector to a grid and I've also did it with the digit version but I've only used it once, so there's no real need for any extensions. I'm thinking of maybe doing a prismatic grid ins$$anonymous$$d of a cubic one, which would be a more complex function (I'm not implementing it yet, so no concrete thoughts). And so far I'm more concerned about my program being clear, I doubt this overhead will make me optimize it anyways. Thanks for your input!
Your answer
Follow this Question
Related Questions
How do I make an array of vectors? 1 Answer
Casting a Ray in the direction of the movement 1 Answer
Vector math problem 1 Answer
Vector direction after collision 1 Answer
Why the object being moved is faster than the rest? 1 Answer