Basicly math functions but for vectors.
So math.vectorClamp(v,minv,maxv); math.vectorEquals(v0,v1); math.vectorLowerThan(v0,v1); math.vectorLowerEquals(v0,v1)
you get the point. Functions like these would be amazing to have and it’s a real bummer that we don’t have them by default. A must have in the module in my opinion!
If you want to get so far with it I will suggest you to make a part:GetPartsWelded()
that will return all the parts that are relying on that part for welds.
Hmm. I’m not sure I would use this myself, but I guess some people might. I have my own ModuleScript full of random functions that I use across many of my projects, but what’s the point of putting stuff like math.random or other “standard library” functions? It’s already available without having to require another module.
Anyway, I’ll post my own utility function module, feel free to use any of them if you think they might be useful.
my 'utility function' module
local TagS = game:GetService("CollectionService")
local random = Random.new(os.time())
--Various utility functions that might be used across several scripts
local util = {}
function util.map(v, a0, a1, b0, b1)
--Maps number v from range [a0-a1] to range [b0-b1]
local aNormalized = (v-a0)/(a1-a0)
return b0 + (b1-b0) * aNormalized
end
function util.filter(t, filter, ...)
--Returns elements of t that satisfy the condition filter(t)
local result = {}
for _, v in pairs(t) do
if filter(t, ...) then
table.insert(result, v)
end
end
return result
end
function util.combine(t0, ...)
--Concatenates any number of tables
local ts = {...}
for _, t in pairs(ts) do
for _, v in pairs(t) do
if not util.indexOf(t0, v) then
table.insert(t0, v)
end
end
end
return t0
end
function util.indexOf(t, value)
--Returns the index at which value is found in the table t, or nil if it is not found
for i, v in pairs(t) do
if v == value then
return i
end
end
return nil
end
function util.getChildrenOfClass(parent, class)
--Gets a list of children of parent, which have the ClassName class
local ch = {}
for _, v in pairs(parent:GetChildren()) do
if v.ClassName == class then
table.insert(ch, v)
end
end
return ch
end
function util.turnFaceToFront(cframe, face)
--Returns a rotated CFrame so that its' given face faces towards its' previous lookVector/ front face
local angles
if face == Enum.NormalId.Front then
angles = CFrame.Angles(0, 0, 0)
elseif face == Enum.NormalId.Back then
angles = CFrame.Angles(math.pi, 0, 0)
elseif face == Enum.NormalId.Left then
angles = CFrame.Angles(0, -math.pi/2, 0)
elseif face == Enum.NormalId.Right then
angles = CFrame.Angles(0, math.pi/2, 0)
elseif face == Enum.NormalId.Top then
angles = CFrame.Angles(-math.pi/2, 0, 0)
elseif face == Enum.NormalId.Bottom then
angles = CFrame.Angles(math.pi/2, 0, 0)
end
return cframe * angles
end
function util.majorAxis(v3, abs)
--Returns the name of the largest component of a Vector3
--If abs is true-like, the component with the largest absolute size is considered instead
local abs = math.abs
local x, y, z
if abs then
x, y, z = abs(v3.X), abs(v3.Y), abs(v3.Z)
else
x, y, z = v3.X, v3.Y, v3.Z
end
local max = math.max(x, y, z)
if x == max then
return 'X'
elseif y == max then
return 'Y'
else
return 'Z'
end
end
function util.otherAxes(axis)
--Given the name of an axis, returns the names of the other two axes
if axis == 'X' then
return 'Y', 'Z'
elseif axis == 'Y' then
return 'X', 'Z'
elseif axis == 'Z' then
return 'X', 'Y'
else
error()
end
end
function util.round(n, to)
--Rounds a number to the nearest 'to', e.g. nearest 0.5 or nearest 10
if to == 0 then return n end
return math.floor(n/(to or 1) + 0.5) * (to or 1)
end
local round = util.round
function util.roundVector3(v3, to)
--Returns a Vector3, with each component rounded to the nearest 'to'
return Vector3.new(
round(v3.X, to),
round(v3.Y, to),
round(v3.Z, to)
)
end
function util.roundVector3V3(v3, to)
--Returns a Vector3, with each component rounded with respect to each component of the Vector3 'to'
return Vector3.new(
round(v3.X, to.X),
round(v3.Y, to.Y),
round(v3.Z, to.Z)
)
end
function util.v3FromAxes(axis1Name, axis1Value, axis2Name, axis2Value, axis3Name, axis3Value)
--Creates a Vector3 from three sets of axis names and axis values
--This makes it possible to create a Vector3 without knowing the order of the axes
local t = {}
if axis1Name == 'X' then
t.X = axis1Value
end
if axis2Name == 'X' then
t.X = axis2Value
end
if axis3Name == 'X' then
t.X = axis3Value
end
if axis1Name == 'Y' then
t.Y = axis1Value
end
if axis2Name == 'Y' then
t.Y = axis2Value
end
if axis3Name == 'Y' then
t.Y = axis3Value
end
if axis1Name == 'Z' then
t.Z = axis1Value
end
if axis2Name == 'Z' then
t.Z = axis2Value
end
if axis3Name == 'Z' then
t.Z = axis3Value
end
return Vector3.new(t.X, t.Y, t.Z)
end
function util.v3InSphere(r)
--A random Vector3 with magnitude <= r
local v3
repeat
v3 = Vector3.new(
random:NextNumber(-1, 1),
random:NextNumber(-1, 1),
random:NextNumber(-1, 1)
)
until v3.Magnitude < 1
return v3 * r
end
function util.v3OnSphere(r)
--A random Vector3 with magnitude = r
return util.v3InSphere(1).Unit * r
end
function util.faceToNormal(part, face)
--Returns the direction that a face on a part is pointing
return part.CFrame:vectorToWorldSpace(Vector3.FromNormalId(face))
end
function util.nextFace(face)
--Given a face, returns the next face Enum
local faces = Enum.NormalId:GetEnumItems()
local index = util.indexOf(faces, face) + 1
if index > #faces then
index = 1
end
return faces[index]
end
function util.normalToFace(part, normal)
--Returns the face on a part that is closest to pointing in the direction of 'normal'
local bestFace, smallestError = nil, math.huge
local objectNormal = part.CFrame:vectorToObjectSpace(normal)
for _, face in pairs(Enum.NormalId:GetEnumItems()) do
local faceNormal = Vector3.FromNormalId(face)
local faceError = (-objectNormal:Dot(faceNormal) + 1) * 0.5
if faceError == 0 then
smallestError = 0
bestFace = face
break
end
if faceError < smallestError then
smallestError = faceError
bestFace = face
end
end
return bestFace, smallestError
end
function util.faceToAxis(face)
if face == Enum.NormalId.Front or face == Enum.NormalId.Back then
return Enum.Axis.Z
elseif face == Enum.NormalId.Left or face == Enum.NormalId.Right then
return Enum.Axis.X
elseif face == Enum.NormalId.Top or face == Enum.NormalId.Bottom then
return Enum.Axis.Y
else
error()
end
end
function util.findTaggedChild(instance, tag, recursive)
return util.findTaggedChildren(instance, tag, recursive)[1]
end
function util.findTaggedChildren(instance, tag, recursive)
local c = {}
local list = (recursive and instance:GetDescendants()) or instance:GetChildren()
for _, v in pairs( list ) do
if TagS:HasTag(v, tag) then
table.insert(c, v)
end
end
return c
end
function util.findTaggedAncestor(descendant, tag)
for _, tagged in pairs(TagS:GetTagged(tag)) do
if descendant:IsDescendantOf(tagged) then
return tagged
end
end
end
function util.weldBetween(a, b)
--Make a new Weld and Parent it to a.
local weld = Instance.new("Weld", a)
--Get the CFrame of b relative to a.
weld.C0 = a.CFrame:inverse() * b.CFrame
--Set the Part0 and Part1 properties respectively
weld.Part0 = a
weld.Part1 = b
--Return the reference to the weld so that you can change it later.
return weld
end
function util.rayCast(ray, whitelist)
return game.Workspace:FindPartOnRayWithWhitelist(ray, whitelist)
end
return util
EDIT: Oh, and here’s a fractal noise generator I use for all sorts of procedural generation:
fractal noise
local r = Random.new(os.time())
function fractalNoiseGenerator(seed, amplitude, frequency, octaves, lacunarity, persistence)
--Generates a fractal noise generator using cohrent noise (math.noise)
--Uses "sensible" default values.
--Check out this glossary: http://libnoise.sourceforge.net/glossary/index.html
local noise = math.noise
local seed = seed or (r:NextInteger(-10e3, 10e3) * math.pi) -- * pi because noise is weird at integer coordinates, and pi is irrational
local amplitude = amplitude or 1
local frequency = frequency or 4
local period = 1/frequency
local octaves = octaves or 5
local lacunarity = lacunarity or 1.75
local persistence = persistence or 0.8
return function(x, y, z)
local v = 0
local a = amplitude
local f = frequency
for o = 1, octaves do
v = v + noise(seed + x*f, seed + y*f, seed + z*f) * a
a = a * persistence
f = f * lacunarity
end
return v
end
end
return fractalNoiseGenerator
Thanks for the advice!
I’ll be sure to do what you recommend!
Script Benchmarker.
Put a tick at the beginning and end of the function/loop of any script you want to benchmark and pass them as arguments to the function, returns an average time a bit of code takes to execute. Useful if you have performance problems and are testing performance solutions in your script!
local results = {}
local count = 0
local total = 0
local benchmarking = false
function measureTick(tick2, tick1)
if #results <= 1000 then -- Sample Count, increase for higher accuracy but takes longer to finish.
local result = tick1 - tick2
table.insert(results, #results + 1, result)
--print("SAMPLES TAKEN: "..#results..) -- Optional, will show progress but completely fill up your output
if #results >= 1000 and benchmarking == true then
print("Generating Results")
for i = 1, #results do
total = total + results[i]
if i >= 1000 then
total = total / #results
print("RESULTS ARE: "..total)
end
end
end
end
end
Haha cool. Roblox jQuery. Call it roQuery lol
Sorry getting back to you so late, the ModuleScript is nearing release.
Should be released this week perhaps.
Yay! I’m excited! And don’t fell bad, people are busy now a days!
A cutscene creator, create cutscenes with ease and being able to change their easing style, easing direction, delay, reverse, duration, and also setting parts as focus points and or camera points. Then having it play it back.