MoonAnimator2 - Playing Particles in game

Heyo,
I made a little test animation that has particles playing at specific keyframes with MoonAnimator2, I haven’t really used it before as I have just found it to be no better than the inbuilt animator.

I was wondering if there is a specific way to play the particles from a Moon2 file in game, preferably with some sort of script reference as I have no idea where to start and everywhere online people just say ‘figure it out’.

1 Like

would require a script to trigger the effects when the keyframes are reached in the animation, moon has some cool selling points but it is funadmentally still using the same animation player at its core, it just has a more user friendly design and a bunch of flashy effects that you can use.

so your most likely need this to tie in effects to your animations
AnimationTrack | Documentation - Roblox Creator Hub

5 Likes

Hey,
Yes I am well aware I would need to tie it in with in-built animation editor track stuff.
I am asking for an example or an idea of how some code that may read moon’s keyframes may look so that I can script it myself.

2 Likes

In the keyframe where the effect emits, put a keyframe event and name it, then, in your script, use animationTrack:GetMarkerReachedSignal(keyframeName) and the code that should execute for effects, it shoud see like this:

myAnimationTrack:GetMarkerReachedSignal(KeyframeName):Connect(function()
--put your code here
end)

Now every time that a keyframe with that name is played, the code inside the event fires

1 Like

Alright sweet, do you know how to do the same when you have used MoonAnimator2 and turned the animation into a moon file?
Is there a way to get the frames out of that to replicate into this kind of code?

In your animation in MoonAnimator export your rig, this will export its animation into an instance called AnimSaves inside the rig, then right click it and import it as a roblox animation, copy the AnimationId and paste it in an Animation instance, all the keyframe events you added in MoonAnimator will be in the animation, so you just have to track in an animation track and use the code I sent you for each animation event with the code that must execute when the animation reaches the keyframe inside the event.

I did this by using moon2cutscene (which has basic support for playing moon files which are not animations) and then modifying the code to allow for animation events

I think i made animation events and then attached modules to them (supported by moon animator), which call functions from _G so that you can use them in studio for the animation preview

Then, to integrate with moon2cutscene, you require a module that maps keyframes to code and then run those on the corresponding keyframe

The module is automatically generated from the keyframes using this script

local replicatedStorage = game.ReplicatedStorage
local cutsceneHolder = replicatedStorage.cutscenes

local cutsceneModuleHolder = replicatedStorage.cutsceneModules

local SOURCE_LINE_FORMAT = "m[%s]=function()\n%s\nend"

local function initMarkerTrack (propertyFolder : Folder, cutsceneFile : StringValue) : ()
	
	local source = {"local m = {}"} :: {string}
	
	for _, keyframeFolder in ipairs(propertyFolder:GetChildren()) do
		
		local keyframeIndex : string = keyframeFolder.Name
		local executeFunctionBody : string = (keyframeFolder:FindFirstChild("codeBegin") :: StringValue).Value
		
		table.insert(source, SOURCE_LINE_FORMAT:format(keyframeIndex, executeFunctionBody))
		
	end
	
	table.insert(source, "return m")
	
	local previousModule = cutsceneModuleHolder:FindFirstChild(cutsceneFile.Name)
	if previousModule then previousModule:Destroy() end
	
	local module = Instance.new("ModuleScript")
	module.Parent = cutsceneModuleHolder
	module.Source = table.concat(source, "\n")
	module.Name = cutsceneFile.Name
	
end

local function updateCutsceneFile(cutsceneFile : StringValue) : ()
	
	for _, objectFolder in ipairs(cutsceneFile:GetChildren()) do
		for _, propertyFolder in ipairs(objectFolder:GetChildren()) do
			if propertyFolder.Name ~= "MarkerTrack" then continue end
			initMarkerTrack(propertyFolder :: Folder,cutsceneFile)
		end
	end
	
end

local cutsceneFile = cutsceneHolder:FindFirstChild("introCutscene")

updateCutsceneFile(cutsceneFile)

Then the result looks like this

local m = {}
m[0]=function()
_G.eventUtil.defaultCinematic()
_G.eventUtil.speaker("bobsquared")
end
m[104]=function()
_G.eventUtil.subtitle("hello player!!", "bobsquared")
end
m[268]=function()
_G.eventUtil.subtitle("this is the {core}memory core!{/core}", "bobsquared")
end
m[497]=function()
_G.eventUtil.subtitle("get {core}7 fragments{/core} for me and you can restore it to complete the questline", "bobsquared")
end
m[879]=function()
_G.eventUtil.subtitle("good luck!!!!!!", "bobsquared")
end
m[1116]=function()
_G.eventUtil.reset()
end
return m

And in the moon2cutscene module you would just do if module[keyframe] then module[keyframe]()

1 Like