My linear velocity has no effect, it applies velocity to an attachment which is inside the player’s root part, what the hell…
code
local players = game:GetService("Players")
local debris = game:GetService("Debris")
-- Functions;
function CreateSound(soundId: number, volume: number, range: number)
local sound = Instance.new("Sound")
sound.SoundId = "rbxassetid://" .. soundId
sound.Volume = volume
sound.RollOffMaxDistance = range
return sound
end
function CreateLinearVelocity()
local linearVelocity = Instance.new("LinearVelocity")
linearVelocity.MaxForce = 100000000
linearVelocity.RelativeTo = Enum.ActuatorRelativeTo.Attachment0
return linearVelocity
end
function ClearGivenInstance(instanceToClear: Instance, timeBeforeClear: number)
-- most would say this function sucks, but i'd rather have it be a function
-- than consistently do debris:AddItem()
-- very minor i know
debris:AddItem(instanceToClear, timeBeforeClear)
end
function CreateSphere(size: Vector3)
local sphere = Instance.new("Part")
sphere.Shape = Enum.PartType.Ball
sphere.Size = size
sphere.Anchored = true
sphere.CanCollide = false
sphere.Transparency = 1
return sphere
end
local classFunctionalityModule = {
Groundbreaker = {
useCriteria = 100,
timeBeforeAbilityEffect = 0.950, -- this is just so i know what delays to give,
onTriggered = function(plr: Player)
local character = plr.Character
local humanoid: Humanoid = character:FindFirstChildOfClass("Humanoid")
if not character or not humanoid then plr:Kick("What?") return end
-- Some crucial values;
local abilityRadius = Vector3.new(64,64,64)
local stunLength = 6
-- Minor connections;
local slamSoundConnection = nil
local rootPart: BasePart = character:FindFirstChild("HumanoidRootPart")
-- we assign some values that we will pass onto CreateSound()
-- first for the ability starting
local abilityStartSoundId = 94844622980879
local abilityStartVolume = 0.5
local abilityStartRange = 80
-- then for the slam
local abilitySlamSoundId = 90712690705018
local abilitySlamVolume = 0.8
local abilitySlamRange = 120
-- Range is the value of RollOffMaxDistance, before anyone (including me) asks
-- now we actually create the sounds, by passing those variables created above
-- for some reason i have to define the type, because otherwise
-- auto completion doesn't pop-up
-- weird...
local buildUpSound: Sound = CreateSound(abilityStartSoundId, abilityStartVolume, abilityStartRange)
local slamSound: Sound = CreateSound(abilitySlamSoundId, abilitySlamVolume, abilitySlamRange)
buildUpSound.Parent = rootPart
slamSound.Parent = rootPart
local buildUpTime = 0.7
-- i also have to define the type in here??
-- what the hell??
local upwardVelocity: LinearVelocity = CreateLinearVelocity()
local downwardVelocity: LinearVelocity = CreateLinearVelocity()
downwardVelocity.Enabled = false -- this is extremely pointless but i'd rather have it here
-- create the attachment so we can parent the linear velocities
local velocityAttachment = Instance.new("Attachment")
velocityAttachment.Parent = rootPart
-- setting the upwardVelocity properties
upwardVelocity.VectorVelocity = Vector3.new(0, 10, 0) -- will launch the player upwards
upwardVelocity.Parent = velocityAttachment
upwardVelocity.Enabled = true
-- can't forget about the build up sound
buildUpSound:Play()
ClearGivenInstance(upwardVelocity, buildUpTime)
ClearGivenInstance(buildUpSound, buildUpTime)
upwardVelocity.Destroying:Wait() -- wait for the upwardVelocity to get destroyed before continuing
-- okay, now after we have launched the player upwards
-- we launch them downwards
-- rocket science!
downwardVelocity.VectorVelocity = Vector3.new(0, -10, 0) -- will launch the player downwards
downwardVelocity.Parent = velocityAttachment
downwardVelocity.Enabled = true
local slamTime = 0.25
ClearGivenInstance(downwardVelocity, slamTime)
downwardVelocity.Destroying:Wait() -- again, wait for the downforce to be destroyed before continuing
velocityAttachment:Destroy()
slamSound:Play() -- now we slam the sound!
-- not sure why i'm setting up a connection here, but i'd rather move on from the yielding
-- and instead move onto the actual thing that makes the ability work
slamSoundConnection = slamSound.Ended:Connect(function()
slamSound:Destroy()
slamSoundConnection:Disconnect() -- wow it kills itself right here, a bit sad
end)
-- oh boy, it's time to make the ability work!
local detectorSphere: BasePart = CreateSphere(abilityRadius)
detectorSphere.CFrame = rootPart.CFrame
local enemyDetector = workspace:GetPartsInPart(detectorSphere)
local enemiesHit = {}
for _, bodyPart in enemyDetector do
local enemyHumanoid: Humanoid = bodyPart.Parent:FindFirstChildOfClass("Humanoid") or bodyPart.Parent.Parent:FindFirstChildOfClass("Humanoid")
local enemyCharacter: Model = enemyHumanoid and enemyHumanoid.Parent
-- some checks to ensure that the for loop actually works
if bodyPart.Parent.Parent == nil then continue end
if players:GetPlayerFromCharacter(enemyCharacter) then continue end
if not enemyCharacter or not enemyHumanoid then continue end
if table.find(enemiesHit, enemyCharacter) then continue end
table.insert(enemiesHit, enemyCharacter) -- inserting the enemy into a table
-- so we can prevent stun stacking
warn("Stunned enemy!")
-- TODO; Add stun logic;
end
-- clearing the entire stun table
table.clear(enemiesHit)
end,
}
}
function classFunctionalityModule:UseAbillity(plr: Player, currentClass: string)
self[currentClass].onTriggered(plr)
end
return classFunctionalityModule