So, if you play tower defense simulator, you know that when you move your mouse when you have a tower, it moves in a sway movement, I made something similar to this Character Sway Effect which I customized and made it so that it works with regular rigs, here is the script, put it in starterplayer, then characterscripts `-
- LocalScript inside StarterPlayerScripts
local RunService = game:GetService("RunService")
local RS = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
local UIS = game:GetService("UserInputService")
local plr = game.Players.LocalPlayer
local mouse = plr:GetMouse()
local Gui = plr.PlayerGui
local Towers = RS.Objects.Towers
local TowerToSpawn = nil
local mainPart = workspace.Rig.HumanoidRootPart
mainPart.Anchored = true
mainPart.CanCollide = false
mainPart.CanQuery = false
mainPart.CanTouch = false
mainPart.Size = Vector3.new(1,1,1)
mainPart.Parent = workspace
local oldCFrame = mainPart.CFrame
local rad = math.rad
local Camera = workspace.CurrentCamera
local function MouseRaycast(Blacklist)
local MousePosition = UIS:GetMouseLocation()
local MouseRay = Camera:ViewportPointToRay(MousePosition.X, MousePosition.Y)
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
raycastParams.FilterDescendantsInstances = Blacklist
local RaycastResult = workspace:Raycast(MouseRay.Origin, MouseRay.Direction * 1000, raycastParams)
return RaycastResult
end
local MouseRaycastRig = MouseRaycast({workspace.Rig})
-- tweakable variables
local tweenInfo = TweenInfo.new(.5,Enum.EasingStyle.Sine) -- the more time, the slower and smoother.
local offset = Vector3.new(0,1.6,0) -- can be used if reaching too high or too low
local sway = 30 -- sway multiplier
RunService.Heartbeat:Connect(function()
if TowerToSpawn then
local Result = MouseRaycast({workspace.Rig})
if Result and Result.Instance then
if not mouse.Target then return end -- return if mouse is in the sky or smth
local cFrame = CFrame.new(Result.Position.X, Result.Position.Y + offset.Y, Result.Position.Z)
for i, v in ipairs(TowerToSpawn:GetChildren()) do
if v:IsA("BasePart") then
v.CollisionGroup = "Tower"
end
end
if cFrame ~= oldCFrame then -- If the part has actually moved
local m = cFrame.Position - oldCFrame.Position -- magnitude
local angle = CFrame.Angles(rad(m.Z*sway),0,rad(-m.X*sway))
cFrame *= angle
TweenService:Create(mainPart,tweenInfo,{CFrame = cFrame}):Play()
oldCFrame = cFrame
end
end
end
end)
local function AddPlaceHolderTower(Name)
local TowerExists = Towers:FindFirstChild(Name)
if TowerExists then
TowerToSpawn = TowerExists:Clone()
TowerToSpawn.Parent = workspace.Towers
for i, v in ipairs(workspace.Rig:GetDescendants()) do
if v:IsA("BasePart") then
v.CollisionGroup = "Tower"
end
end
end
end
Gui.ScreenGui.Frame.TowerButton.Activated:Connect(function()
AddPlaceHolderTower("Rig")
end)
UIS.InputBegan:Connect(function(Input, Processed)
if Processed then
return
end
if TowerToSpawn then
if Input.UserInputType == Enum.UserInputType.MouseButton1 then
game:GetService("ReplicatedStorage").Remotes.SpawnTower:FireServer(TowerToSpawn.Name, Vector3.new(mouse.Hit.Position.X, 1.8, mouse.Hit.Position.Z), TowerToSpawn.HumanoidRootPart.Rotation)
end
end
end)`
There are other parts which are included and, because I am stupid, I put the original in scripting support now, the next script is for the spring mechanic which is the quenty spring mechanic Spring and I recommend watching gnomecode on YT cuz umm, I changed a bit of the next code from his video for this one so umm, yeah, put this is replicated storage and make it module script
local RS = game:GetService("ReplicatedStorage")
local Tower = {}
function Tower.Spawn(Plr, Name, cframe, rotation)
local TowerExists = game:GetService("ReplicatedStorage").Objects.Towers:FindFirstChild(Name)
local RigClone = TowerExists:Clone()
RigClone.HumanoidRootPart.Position = cframe
RigClone.HumanoidRootPart.Rotation = rotation
RigClone.Parent = workspace.Towers
RigClone.HumanoidRootPart:SetNetworkOwner(nil)
RigClone.Name = "Clone"
for i, v in ipairs(workspace.Rig:GetDescendants()) do
if v:IsA("BasePart") then
v.CollisionGroup = "Tower"
end
end
end
RS.Remotes.SpawnTower.OnServerEvent:Connect(Tower.Spawn)
return Tower
I like to be organized so I put stuff in folders so put a folder in ReplicatedStorage and call it Remotes specifically for the noobs, and also put SpawnEvent inside Remotes, then make a Modules folder in ReplicatedStorage and name it Modules, again specifically, and then you put in the module I just said and the Spring module and name spring module, Spring, along with naming the one I just said, Tower. Now you should have a working product with all you need is to put in a script in serverscriptservice with the following code and boom, your done.
local Tower = require(game:GetService("ReplicatedStorage").Modules.Tower)
Also just add screengui in starterpack, then a frame with the size 1,0,1,0, and a textbutton called, “TowerButton” If you want the whole thing in a pack, just get it here see ya
I changed the effect so that it runs with a restricted area and might be the only update I make for this other than the errors I fix from ya’ll telling me about bugs on this forum page.