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 Spring = require(game:GetService("ReplicatedStorage").Modules.Spring)
local plr = game.Players.LocalPlayer
local mouse = plr:GetMouse()
local Gui = plr.PlayerGui
local Towers = RS.Objects.Towers
local TowerToSpawn = nil
local rad = math.rad
local CanPlace = false
-- tweakable variables
local TweenInfoSway = TweenInfo.new(.05,Enum.EasingStyle.Sine) -- the more time, the slower and smoother.
local sway = 40 -- sway multiplier
local rotation = 0
local Camera = workspace.CurrentCamera
local offset = Vector3.new(0,0.5,0)
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
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.SmoothPlastic
v.Color = game:GetService("ReplicatedStorage").Objects.Towers[TowerToSpawn.Name][v.Name].Color
else
v.Material = Enum.Material.ForceField
v.Color = Color
end
end
end
end
end
Gui.ScreenGui.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})
if Result and Result.Instance then
if Result.Instance.Parent.Name == "PlaceArea" then
CanPlace = true
ColorPlaceHolderTower()
else
CanPlace = false
ColorPlaceHolderTower(Color3.fromRGB(255, 48, 34))
end
local OldCFrame = TowerToSpawn.PrimaryPart.CFrame
local X = Result.Position.X
local Y = Result.Position.Y + TowerToSpawn.PrimaryPart.Size.Y + 0.5
local Z = Result.Position.Z
local CurrentLocation = Vector3.new(X,Y,Z)
local MaxAngle = 15
local cFrame = CFrame.new(X,Y,Z)
if cFrame ~= OldCFrame then
local M = cFrame.Position - OldCFrame.Position
local Angle = CFrame.Angles(math.clamp(rad(-M.Z*sway), math.rad(-MaxAngle),
math.rad(MaxAngle)), 0, math.clamp(rad(M.X*sway), math.rad(-MaxAngle), math.rad(MaxAngle)))
cFrame *= Angle * CFrame.Angles(0, math.rad(rotation), 0)
TweenService:Create(TowerToSpawn.PrimaryPart, TweenInfoSway, {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, TowerToSpawn.PrimaryPart.Position, 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)
Now put a script in ServerScriptService and put this inside it
local Tower = require(game:GetService("ReplicatedStorage").Modules.Tower)
I have made a model for the lazy people out there but good luck with your tds games and you can like if this was useful (Not required)
This is the smoothest version and will be for a long time before there is an update with roblox that will require me to update this.