As a roblox developer, it’s annoying to translate between Vector2 and Vector3 values. This is something you have to do rather often as a developer, especially when working with input since InputObjects use a Vector3 to describe a position on the screen.
I want an easy way to minimize this:
local pos = Vector2.new(input.Position.X, input.Position.Y)
My suggestion is to add some new functions:
Vector3.fromVector2(vector2)
which is the same as
Vector3.new(vector2.X, vector2.Y, 0)
and
Vector2.fromVector3(vector3)
which is the same as
Vector2.new(vector3.X, vector3.Y)
Or add overrides to Vector2.new and Vector3.new to accept Vector2s and Vector3s.
This isn’t the entire story. Consider the case where you have a long expression to evaluate. In the best case, it’s just a long property name, but in the worst case, it’s a complex bespoke expression:
This is both wasteful computationally and wasteful visually. Right now, our best bet is to separate out the expressions:
local scaledInput3D = ((input.Position - centrePoint) * inputScaling + centrePoint)
local scaledInput2D = Vector2.new(scaledInput3D.X, scaledInput3D.Y)
I’ve done this lots of times in my codebase, and it’s getting more common as I start writing more generic code in my projects. I end up with a lot of boilerplate code this way, and it pollutes the local namespace with intermediary variables. Remember that this is not the only snippet of code present in a codebase - often, I’m doing a whole chain of mathematical processing and this is just one atomic step.
Whereas this feature request makes it meaningfully better - suppose Vector2.new could take a Vector3 to reduce down:
local scaledInput = Vector2.new((input.Position - centrePoint) * inputScaling + centrePoint)
I think it is worth considering this before inserting expressionless emojis into forum replies.
You could make the tool you want, which could be something like this:
--Swizzler
local function Swiz(source, members)
local vectype
if #members == 1 then
return source[members]
elseif #members == 2 then
vectype = Vector2
elseif #members == 3 then
vectype = Vector3
end
local newargs = {}
for i = 1, #members do
local axis = string.upper(string.sub(members, i, i))
newargs[i] = source[axis]
end
return vectype.new(table.unpack(newargs))
end
print(Swiz(Vector3.new(1,2,3), "xz")) --Vector2: 1, 3
print(Swiz(Vector2.new(1,2), "xyx")) --Vector3: 1, 2, 1
You could get downright funky with this:
local function NewSwizvec(...)
local args = table.pack(...)
local vectype
if #args == 2 then
vectype = Vector2
elseif #args == 3 then
vectype = Vector3
end
local vec = vectype.new(...)
local swizvec = {["xyz"] = vec}
local swizmt = {}
function swizmt.__index(t, k)
--print("Index: " ..tostring(t).. " : " ..tostring(k))
return Swiz(t.xyz, k)
end
setmetatable(swizvec, swizmt)
return swizvec
end
print(NewSwizvec(1, 2, 3).xxx) --1, 1, 1
print(NewSwizvec(2, 3).yyx) --3, 3, 2
print(NewSwizvec(2, 3).y) --3 (just a number)