I’m currently working on a Wand system - It’s essentially 100% operational to the needs I require.
However I’m struggling to create any sort of /decent/ movement effect?
By this I mean as opposed to moving in a linear line - It has a somewhat erratic movement to it similar to the projectiles in YouTube video posted below.
Below is the code I use for projectile movement.
Does anyone have any suggestions on how I can achieve the desired effects? Somewhat spinning etc.
local LastPos = Part.Position
Part.CFrame *= CFrame.new(-Vector3.zAxis * 5)
local Distance = (Part.Position - LastPos).Magnitude
local Direction = (Part.Position - LastPos).Unit * Distance
local RaycastParam = RaycastParams.new()
RaycastParam.FilterType = Enum.RaycastFilterType.Exclude
RaycastParam.FilterDescendantsInstances = {Part.Parent.Parent}
local Result = Server:GetService('Workspace'):Raycast(LastPos, Direction, RaycastParam)
if not Result then
--
else
Part.Position = Result.Position
Part:RemoveTag('Projectile')
end
If you want the movement to be completely erratic, moving randomly (but still getting to its target),
you could just add a random amount to its position, keeping track of the actual intended position, like so:
if not Result then
--
else
IntendedPos = Result.Position
Part.Position = Result.Position + Vector3.new(math.random(), math.random(), math.random())
Part:RemoveTag('Projectile')
end
Then when changing the part’s position afterwards you can do it based off IntendedPos instead of the part’s actual position, so that the part wont stray away from where it’s meant to go.
Though @mynameisjeb2018’s response is valid, I would like to add that it may make it too random, especially if the update rate is high. Ideally, it would be for hit-detetion purposes, and so would be client-sided and update with RenderStepped.
The first spell appears to use a sine wave to create an oscilating effect (in other words, going up and then down). All you need is a constantly increasing or decreasing number as ‘x’ in math.sin(x) to create this effect. In this case, you could just use the elapsed time since the projectile began.
To make the waves shorter, multipy x by a value greater than one, and the opposite for making them longer. Similarly, to make the waves taller, multiple the result of “math.sin(x)” by a value greater than 1 or the opposite to make them shorter.
Then you can use the final result to offset the spell’s visuals by a certain amount in a wave-like pattern. Though remember that it’s only the visual here being effect; the real hitbox is still in the center of the oscilation, so gameplay isn’t effected.
totalTime
runservice.RenderStepped:Connect(function(delta)
totalTime += delta
--//Regular movement
projectileCore.CFrame *= CFrame.new(0,0,-speed * delta)
doHitDetectionStuff()
--// Use sine to offset projectile
local SinOffset = math.sin(totalTime)
--// Also a slight spin could be put on the projectile like this. I think, idk.
local Spin = (20 * totalTime)%360
visualOffset = projectileCore.CFrame * (CFrame.new(0,SinOffset,0) * CFrame.Angles(0,0,math.rad(Spin)))
end)
I’m making this same thing at the moment, I’ll post my code once I wrap it up here later today, but to keep it short:
Get the Start and Finish positions
Get the Vector3 between those two positions
Create a loop which:
a) breaks that single long Vector3 into a series of positions (still techniclaly Vector3’s). Set the distance between each position to be the length you want each ‘erractic arc’ to be.
b) add the X and Y offset to each position
c) Insert that position into a table
Loop through that table and tween your projectile from its current position to the current indexed position that your loop is at.
Disclaimer that this likely isnt the most efficient way to do it, as I have a line count to meet, but it does accomplish the desired projectile motion pattern that you’re describing.
I’ll edit this post with the the code once I’m done
When it comes to projectiles I’ve never really worked with Start & Finish points.
I’ve always used motion in a sense that once the Projectile is fired it’ll move along the Parts LookVector until either it times out or a collision is detected, I’ve found this to be my best way of detecting accurate collisions.
Where as moving along a linear Path from A to B, especially using a tween, doesn’t use a desired response if you get me?
I made it to follow this type of logic, and therefore it ignores my previous post’s outline. You can play around with it to tweak it however you like.
-- Demo chaotic projectile movement; you can run this in your studio console
local c0:CFrame = CFrame.new(0,10,0) -- Starter position
local distanceInterval:number = 5 -- Distance per interval
local xOffset:number, yOffset:number = 1,1 -- Offset intervals for the 'chaotic' effect
-- Create projectile
local p:BasePart = Instance.new("Part",workspace) p.Name = "Projectile"
p.Size = Vector3.new(0.5,0.5,1)
p.Color = Color3.new(1,1,1)
p.CFrame = c0
-- Bonus: A trail to help visualize the path
local att0 = Instance.new("Attachment", p) att0.Position = Vector3.zAxis*2.5
local att1 = att0:Clone() att1.Parent = p att1.Position = Vector3.zAxis*-2.5
local trail = Instance.new("Trail", p) trail.Attachment0 = att0 trail.Attachment1 = att1
trail.TextureMode = Enum.TextureMode.Stretch
trail.MaxLength = 30
trail.TextureLength = 5
trail.WidthScale = NumberSequence.new(0.5) trail.Transparency = NumberSequence.new(0,1)
trail.Color = ColorSequence.new(p.Color)
-- I used a for loop that will cause it travel 150 studs for simplicity
local rayParams:RaycastParams = RaycastParams.new()
rayParams.FilterType = Enum.RaycastFilterType.Exclude
rayParams.FilterDescendantsInstances = {p}
for iterator:number = 0, 150, distanceInterval do task.wait(0.05)
-- Raycast for part detection. Uses c0 as a reference to keep the projectile path linear
local rayResult:RaycastResult = workspace:Raycast(c0.Position, c0.LookVector.Unit*distanceInterval,rayParams)
if rayResult then
-- Whatever happens on hit
break
else
c0 *= CFrame.new(0,0,-distanceInterval) -- Update our reference point
p.PivotOffset = CFrame.new(math.random(-xOffset,xOffset),math.random(-yOffset,yOffset),0) -- Apply the offset to make it 'erratic'
p:PivotTo(c0) -- Use PivotTo to apply the PivotOffset. Setting CFrame wont create the effect
end
end
p:Destroy() -- Cleanup
This looks promising!
I’ve been looking into Bezier Curves & was wondering about utilising this to create a zigzag flow also.
I’ll look into this soon, thank you!
When I run this in the command bar , it errors out…
and way to get it in a .rbxl or a model etc.?? that works…
18:15:48.836 require(79851394307177).GetReleases()-- Demo chaotic projectile movement; you can run this in your studio console
local c0:CFrame = CFrame.new(0,10,0) -- Starter position
local distanceInterval:number = 5 -- Distance per interval
local xOffset:number,:1: attempt to call a nil value - Edit
18:15:48.836 Stack Begin - Studio
18:15:48.836 Script 'require(79851394307177).GetReleases()-- Demo chaotic projectile movement; you can run this in your studio console
local c0:CFrame = CFrame.new(0,10,0) -- Starter position
local distanceInterval:number = 5 -- Distance per interval
local xOffset:number,', Line 1 - Studio
18:15:48.836 Stack End - Studio