Sway Effect 3.0 (TDS)

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)

Sway Effect

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.

3 Likes

Good job

Make sure to edit this post and change the category to #resources:community-resources, otherwise it will get taken down for being in the wrong category. Development Discussion is for talking about subjects, not publishing resources