Scripting a tool: Holding down left mouse click to hold an animation

Alright, so I’ve been trying to make my first tool. I’ve done some research and managed to get an animation to activate with my tool. Here’s the animation:

The idea is that it’s meant to be a spell. I understand the theory behind getting my spell effect to work, but I don’t understand how to have my tool maintain the extended arm position whilst the user holds down the left mouse button.

This is what I’ve achieved so far:

Any help is hugely appreciated!! :slight_smile:

2 Likes

Apparently, AnimationTracks' speed can be paused using :AdjustSpeed(0). If you can predict when your intended keyframe is, you could pause it after however many seconds pass. If you are able to, try placing a marker at the end of your animation and, using AnimTrack:GetMarkerReachedSignal to get the event for that marker, call AnimTrack:AdjustSpeed(0) when it fires. When finished with the animation, you could just call :Stop to cancel the animation, and you could also play it in reverse if you wish and stop it once it reaches the beginning.

5 Likes

Thanks for the response!

How do I play it in reverse?

1 Like

You would just use :AdjustSpeed again, except -1 would be your argument.

2 Likes

And how do I place a marker?
I haven’t used the Roblox animation editor I’ve used the Blender rig exporter plugin. Is it a feature of the Roblox animation editor?

1 Like

Personally, I use Moon Animation Suite.
There is documentation on the Roblox animation editor here, linked from the :GetMarkerReachedSignal method, but there is also an :AddMarker method of keyframes, if you are to use those. I also found that KeyframeMarkers are its own instance, if that helps.

1 Like

And lastly is there a separate function for detecting left-mouse-button being held down as opposed to a single click?

On the tool specifically, there is no such event available.

Edit: Tools have an .Activated and .Deactivated event, which you can keep track of with a boolean variable:

local isActivated = false

Tool.Activated:Connect(function()
	isActivated = true
end)

Tool.Deactivated:Connect(function()
	isActivated = false
end)

You can also connect just a regular function that is enabled and disabled through these events.

My apologies.

Alternative:

A clever alternative would be using ContextActionService's :BindAction and :UnbindAction on the tool’s .Equipped and .Unequipped events.
Probably something like this:

local ContextActionService = game:GetService("ContextActionService")

local Tool = -- script.Parent  -- presumably

-- when tool is equipped,
Tool.Equipped:Connect(function()
	-- bind input to tool
	ContextActionService:BindAction("onToolActivate",
		function(name, inputState, inputObject)
			-- ...
		end,
		false,
		Enum.UserInputType.Mouse1 -- , ...
	)
end)

-- when tool is unequipped
Tool.Unequipped:Connect(function()
	-- unbind input from tool
	ContextActionService:UnbindAction("onToolActivate")
end)

If you are confused as to how to use this, i strongly recommend you to research ContextActionService and its methods in the developer wiki; it has tons of information and example code to absorb from.

2 Likes

Thanks for all the help!
All of this is very complex to me but I think you’ve given me the information I need to work it all out. Thanks so much!

1 Like

Alright, so this is what I’ve thrown together so far with a little feedback from a friend.
I managed to workout how to add markers with the blender add-on, so I’ve got two marker. One named “extended” and another named “retracted”

Two issues so far:
Although I’m not getting any error messages, the animation doesn’t stop (line15)

I’m having some issues with learning how to use GetMarkerReachedSignal. Everything I’ve tried hasn’t worked. I’ve no idea how to use it.

I think the problem is that you are loading a new animation track every time you call the function ToolActivation. Just create animation from outside the function, and you can continue on with everything else:

-- At line 1
local isActivated = false
local animation = --place animation here
local function ToolActivation()
	-- instead of here

-- ...

And personally, I have not ever used keyframe markers before, but I would assume you just use the keyframe marker’s name and connect it like an event:

-- assuming "extended" is the marker at the end,
animation:GetMarkerReachedSignal("extended"):Connect(function()
	animation:AdjustSpeed(0)
end)

-- assuming "retracted" is the marker at the beginning??
animation:GetMarkerReachedSignal("retracted"):Connect(function()
	animation:Stop()
end)