Tower Defense Move Effect

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 and what to do

-- LocalScript inside StarterPlayerScripts
local RunService = game:GetService("RunService")
local TweenService = game:GetService("TweenService")
local UIS = game:GetService("UserInputService")

local plr = game.Players.LocalPlayer
local mouse = plr:GetMouse()

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.7,0) -- can be used if reaching too high or too low

local sway = 150 -- sway multiplier

RunService.Heartbeat:Connect(function()
	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 + offset.X, Result.Position.Y + offset.Y, Result.Position.Z + offset.Z)

		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)

I customized my rig size but in order to work properly, you must find the size of the legs of the rig, ( I used a part and saw the Y value on size) and change the middle value of the offset. (Y for beginners :smiley: ) If the humanoidrootpart is not a member of rig, then start and put your cursor in like the middle of the screen, you can customize this if you want it to place but that’s all for this idea of mine.

3 Likes

I believe you can use the Spring pattern that was brought up back in RDC2020’s powerful design patterns. This is assuming that you have appropriately assembled the model in a way to make it work. The module is freely available from a repository.

Here’s a topic of similar area:

1 Like

Yes, I do use this module, Quenty’s spring module, in order to make this work, I just kind of learned how to code and am getting way better

I’m a little confused. Why is this in scripting support if you aren’t actually have any issues?