Sway Effect (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 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 :nerd_face: 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 :smiley:

Sway Effect

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.

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