I understand animations are best looking on the client but I’m creating a ton of emotes in my game and some of them need M6Ds and parts.
The main problem right now is that some emotes emit particles and utilize parts to create their effect.
Should I make visuals on the server for every player to see? (create m6d, emit particles, etc on server)
I’ve already done these things on server but I’ve come across an error where the server can’t access an emitter inside part being animated.
Server: I use modules for each emote to set it up, same for client side if I want changes I on client.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Functions = ReplicatedStorage.Functions
local Assets = ReplicatedStorage.Assets
local Modules = {
["Poop"] = require(script.Poop),
["Clap"] = require(script.Clap),
["Rock On"] = require(script["Rock On"]),
["Cool"] = require(script.Cool)
}
Functions.Animator.OnServerInvoke = function(player,signal,length)
if typeof(signal) ~= "string" then return end
if typeof(length) ~= "number" then return end
local character = player.Character or player.CharacterAdded:Wait()
local emote = Assets.Emotes:FindFirstChild(signal)
if emote then
local m6d = emote:FindFirstChildWhichIsA("Motor6D"):Clone()
local bsp = emote:FindFirstChildWhichIsA("BasePart"):Clone()
m6d.Parent = character:FindFirstChild(m6d:GetAttribute("Parent"))
bsp.Parent = character
m6d.Part0 = m6d.Parent
m6d.Part1 = bsp
bsp:SetNetworkOwner(player)
task.spawn(function()
Modules[signal]:Init(m6d,bsp,length)
end)
return {m6d,bsp}
else
return
end
end
Client
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local StarterPlayer = game:GetService("StarterPlayer")
local Bindables = ReplicatedStorage.Bindables
local Assets = ReplicatedStorage.Assets
local Functions = ReplicatedStorage.Functions
local Emotes = script.Emotes
local Modules = {
["Poop"] = require(Emotes.Poop),
["Clap"] = require(Emotes.Clap),
["Rock On"] = require(Emotes["Rock On"]),
["Cool"] = require(Emotes.Cool)
}
local Character = script.Parent
local Humanoid = Character:WaitForChild("Humanoid")
local CurrentTrack = nil
local CurrentSound = nil
local Animator = {}
function Animator:FreezeWhenAnimationStopped(track)
Humanoid.WalkSpeed = 0
Humanoid.JumpPower = 0
Humanoid.AutoRotate = false
track.Stopped:Connect(function()
Humanoid.WalkSpeed = StarterPlayer.CharacterWalkSpeed
Humanoid.JumpPower = StarterPlayer.CharacterJumpPower
Humanoid.AutoRotate = true
end)
end
function Animator:Destroy(anim)
if Character:FindFirstChild(anim) then Character:FindFirstChild(anim):Destroy() end
if CurrentTrack then CurrentTrack:Stop() end
if CurrentSound then CurrentSound:Destroy() end
end
function Animator:Play(anim,freezing)
if anim == nil then return end
local Animation = Instance.new("Animation")
Animation.AnimationId = anim
Animation.Name = anim
Animation.Parent = Character
CurrentTrack = Humanoid.Animator:LoadAnimation(Animation)
CurrentTrack:Play()
if freezing then self:FreezeWhenAnimationStopped(CurrentTrack) end
end
function Animator:Emote(anim,freezing,emote)
self:Play(anim,freezing)
Modules[emote]:Init(CurrentTrack,Animator)
end
return Animator