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 `-
local RS = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
local UIS = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local plr = game.Players.LocalPlayer
local mouse = plr:GetMouse()
local Gui = plr.PlayerGui
local Towers = RS.Objects.Towers
local Cart = Towers.Parent.Cart:Clone()
local Circle = Towers.Parent.Circle:Clone()
local TowerToSpawn = nil
local rad = math.rad
local CanPlace = false
-- tweakable variables
local tweenInfo = TweenInfo.new(.1,Enum.EasingStyle.Sine) -- the more time, the slower and smoother.
local tweenInfo1 = TweenInfo.new(.5,Enum.EasingStyle.Sine)
local sway = 30 -- sway multiplier
local rotation = 0
local Camera = workspace.CurrentCamera
local offset = Vector3.new()
local cFrame
local mainPart = nil
local oldCFrame = nil
local function MouseRaycast(Blacklist) -- Raycasting
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 function RemovePlaceHolderTower(Name) -- Removing the tower you put
if TowerToSpawn then
TowerToSpawn:Destroy()
TowerToSpawn = nil
end
end
local function AddPlaceHolderTower(Name) -- Adding the tower you put
local TowerExists = Towers:FindFirstChild(Name)
if TowerExists then
RemovePlaceHolderTower()
TowerToSpawn = TowerExists:Clone()
TowerToSpawn.Parent = workspace.Towers
mainPart = TowerToSpawn.HumanoidRootPart
oldCFrame = mainPart.CFrame
offset = Vector3.new(0,TowerToSpawn["Right Leg"].Size.X + TowerToSpawn["Right Leg"].Size.Y,0)
for i, v in ipairs(TowerToSpawn:GetDescendants()) do
if v:IsA("BasePart") then
v.CollisionGroup = "Tower"
end
end
end
end
local function ColorPlaceHolderTower(Color) -- Colors the tower based of of where it is
if TowerToSpawn ~= nil then
for i, v in ipairs(TowerToSpawn:GetDescendants()) do
if v:IsA("BasePart") then
if CanPlace == true then
v.Material = Enum.Material.Plastic
v.Color = Color
else
v.Material = Enum.Material.ForceField
v.Color = Color
end
end
end
end
end
Gui.ScreenGui.Frame.TowerButton.Activated:Connect(function()
AddPlaceHolderTower("Rig") -- Change to the Tower name
end)
RunService.Heartbeat:Connect(function()
if not mouse.Target then return end -- return if mouse is in the sky or smth
local Result = MouseRaycast({TowerToSpawn})
cFrame = CFrame.new(Result.Position + offset)
if Result and Result.Instance then
if Result.Instance.Parent.Name == "PlaceArea" then
CanPlace = true
ColorPlaceHolderTower(Color3.fromRGB(248, 217, 109))
else
CanPlace = false
ColorPlaceHolderTower(Color3.fromRGB(255, 48, 34))
end
if cFrame ~= oldCFrame then -- If the part actually moved
local m = cFrame.Position - oldCFrame.Position -- magnitude (as a vector3)
local angle = CFrame.Angles(rad(m.Z*sway),rad(rotation),rad(-m.X*sway))
cFrame *= angle
TweenService:Create(mainPart,tweenInfo,{CFrame = cFrame}):Play()
oldCFrame = cFrame
end
end
end)
UIS.InputBegan:Connect(function(Input, Processed)
if Processed then
return
end
if TowerToSpawn then
if Input.UserInputType == Enum.UserInputType.MouseButton1 then
if CanPlace == true then
game:GetService("ReplicatedStorage").Remotes.SpawnTower:FireServer(TowerToSpawn.Name, Vector3.new(cFrame.X, cFrame.Y, cFrame.Z), TowerToSpawn.HumanoidRootPart.Rotation)
RemovePlaceHolderTower()
end
elseif Input.KeyCode == Enum.KeyCode.R then -- Just for smoother rotation and not straight up facing one direction
for i = 1,3 do
rotation += 30
wait(0.06)
end
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()
local PlaceEffect = game:GetService("ReplicatedStorage").Objects.Effects.Place:Clone()
RigClone.HumanoidRootPart.Position = cframe
RigClone.HumanoidRootPart.Rotation = rotation
RigClone.Parent = workspace.Towers
PlaceEffect.Parent = RigClone.HumanoidRootPart.PlaceAttachment
RigClone.HumanoidRootPart:SetNetworkOwner(nil)
PlaceEffect.Enabled = true
task.delay(0.3, function()
PlaceEffect.Enabled = false
end)
RigClone.Name = Name
for i, v in ipairs(RigClone:GetDescendants()) do
if v:IsA("BasePart") then
v.CollisionGroup = "Tower"
end
end
end
RS.Remotes.SpawnTower.OnServerEvent:Connect(Tower.Spawn)
return 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
This is the Sway Effect 3.0 which I made 3.0 because of people wanting a different size for rigs so I made it so that you don’t have to change the offset and a place effect, this should help with some of the small problems I see.