And now, in just a few weeks’ time, we’re going to be bringing this intuitive experience to the Roblox website as well. Introducing New Ways to Customize As we put the finishing touches on our website’s new Avatar Editor page, we’d like to give you a quick sneak peek so you know what to expect once it drops in the next few weeks. Product 1: Each package comes with a redeemable code to unlock an exclusive virtual item on Roblox Product 2: Go out for a spin with this exhilarating vehicle set, featuring a unique character, a vehicle, and accessories Product 2: Mix and match parts to build your own unique Roblox character.
- local child = parent:findFirstChild(childName)
- while true do
- if child.NamechildName then return child end
- end
- local Figure = script.Parent
- local RightShoulder = waitForChild(Torso, 'Right Shoulder')
- local LeftShoulder = waitForChild(Torso, 'Left Shoulder')
- local RightHip = waitForChild(Torso, 'Right Hip')
- local Neck = waitForChild(Torso, 'Neck')
- local Humanoid = waitForChild(Figure, 'Humanoid')
- local currentAnimInstance = nil
- local currentAnimKeyframeHandler = nil
- local animTable = {}
- idle = {
- { id = 'http://www.roblox.com/asset/?id=180435571', weight = 9 },
- { id = 'http://www.roblox.com/asset/?id=180435792', weight = 1 }
- walk = {
- { id = 'http://www.roblox.com/asset/?id=180426354', weight = 10 }
- run = {
- },
- { id = 'http://www.roblox.com/asset/?id=125750702', weight = 10 }
- fall = {
- { id = 'http://www.roblox.com/asset/?id=180436148', weight = 10 }
- climb = {
- { id = 'http://www.roblox.com/asset/?id=180436334', weight = 10 }
- sit = {
- { id = 'http://www.roblox.com/asset/?id=178130996', weight = 10 }
- toolnone = {
- { id = 'http://www.roblox.com/asset/?id=182393478', weight = 10 }
- toolslash = {
- { id = 'http://www.roblox.com/asset/?id=129967390', weight = 10 }
- },
- { id = 'http://www.roblox.com/asset/?id=129967478', weight = 10 }
- wave = {
- { id = 'http://www.roblox.com/asset/?id=128777973', weight = 10 }
- point = {
- { id = 'http://www.roblox.com/asset/?id=128853357', weight = 10 }
- dance1 = {
- { id = 'http://www.roblox.com/asset/?id=182435998', weight = 10 },
- { id = 'http://www.roblox.com/asset/?id=182491037', weight = 10 },
- { id = 'http://www.roblox.com/asset/?id=182491065', weight = 10 }
- dance2 = {
- { id = 'http://www.roblox.com/asset/?id=182436842', weight = 10 },
- { id = 'http://www.roblox.com/asset/?id=182491248', weight = 10 },
- { id = 'http://www.roblox.com/asset/?id=182491277', weight = 10 }
- dance3 = {
- { id = 'http://www.roblox.com/asset/?id=182436935', weight = 10 },
- { id = 'http://www.roblox.com/asset/?id=182491368', weight = 10 },
- { id = 'http://www.roblox.com/asset/?id=182491423', weight = 10 }
- laugh = {
- { id = 'http://www.roblox.com/asset/?id=129423131', weight = 10 }
- cheer = {
- { id = 'http://www.roblox.com/asset/?id=129423030', weight = 10 }
- }
- -- Existance in this list signifies that it is an emote, the value indicates if it is a looping emote
- local emoteNames = { wave = false, point = false, dance1 = true, dance2 = true, dance3 = true, laugh = false, cheer = false}
- function configureAnimationSet(name, fileList)
- for _, connection in pairs(animTable[name].connections) do
- end
- animTable[name] = {}
- animTable[name].totalWeight = 0
- local config = script:FindFirstChild(name)
- -- print('Loading anims ' .. name)
- table.insert(animTable[name].connections, config.ChildAdded:connect(function(child) configureAnimationSet(name, fileList) end))
- table.insert(animTable[name].connections, config.ChildRemoved:connect(function(child) configureAnimationSet(name, fileList) end))
- for _, childPart in pairs(config:GetChildren()) do
- table.insert(animTable[name].connections, childPart.Changed:connect(function(property) configureAnimationSet(name, fileList) end))
- animTable[name][idx].anim = childPart
- local weightObject = childPart:FindFirstChild('Weight')
- animTable[name][idx].weight = 1
- animTable[name][idx].weight = weightObject.Value
- animTable[name].count = animTable[name].count + 1
- animTable[name].totalWeight = animTable[name].totalWeight + animTable[name][idx].weight
- -- print(name .. ' [' .. idx .. '] ' .. animTable[name][idx].anim.AnimationId .. ' (' .. animTable[name][idx].weight .. ')')
- end
- end
- -- fallback to defaults
- for idx, anim in pairs(fileList) do
- animTable[name][idx].anim = Instance.new('Animation')
- animTable[name][idx].anim.AnimationId = anim.id
- animTable[name].count = animTable[name].count + 1
- animTable[name].totalWeight = animTable[name].totalWeight + anim.weight
- -- print(name .. ' [' .. idx .. '] ' .. anim.id .. ' (' .. anim.weight .. ')')
- end
- function scriptChildModified(child)
- if (fileList ~= nil) then
- end
- script.ChildRemoved:connect(scriptChildModified)
- configureAnimationSet(name, fileList)
- local toolAnim = 'None'
- local jumpAnimDuration = 0.3
- local toolTransitionTime = 0.1
- local jumpMaxLimbVelocity = 0.75
- -- functions
- function stopAllAnimations()
- if (emoteNames[oldAnim] ~= nil and emoteNames[oldAnim] false) then
- end
- currentAnim = '
- if (currentAnimKeyframeHandler ~= nil) then
- end
- if (currentAnimTrack ~= nil) then
- currentAnimTrack:Destroy()
- end
- end
- function setAnimationSpeed(speed)
- currentAnimSpeed = speed
- end
- if (frameName 'End') then
- local repeatAnim = currentAnim
- if (emoteNames[repeatAnim] ~= nil and emoteNames[repeatAnim] false) then
- end
- local animSpeed = currentAnimSpeed
- setAnimationSpeed(animSpeed)
- end
- -- Preload animations
- function playAnimation(animName, transitionTime, humanoid)
- local roll = math.random(1, animTable[animName].totalWeight)
- local idx = 1
- while (roll > animTable[animName][idx].weight) do
- idx = idx + 1
- -- print(animName .. ' ' .. idx .. ' [' .. origRoll .. ']')
- if (anim ~= currentAnimInstance) then
- if (currentAnimTrack ~= nil) then
- currentAnimTrack:Destroy()
- currentAnimTrack = humanoid:LoadAnimation(anim)
- -- play the animation
- currentAnim = animName
- if (currentAnimKeyframeHandler ~= nil) then
- end
- currentAnimKeyframeHandler = currentAnimTrack.KeyframeReached:connect(keyFrameReachedFunc)
- end
- end
- -------------------------------------------------------------------------------------------
- -------------------------------------------------------------------------------------------
- local toolAnimName = '
- local toolAnimInstance = nil
- if (frameName 'End') then
- playToolAnimation(toolAnimName, 0.0, Humanoid)
- end
- function playToolAnimation(animName, transitionTime, humanoid)
- local roll = math.random(1, animTable[animName].totalWeight)
- local idx = 1
- while (roll > animTable[animName][idx].weight) do
- idx = idx + 1
- -- print(animName .. ' * ' .. idx .. ' [' .. origRoll .. ']')
- toolAnimTrack:Stop()
- transitionTime = 0
- toolAnimTrack = humanoid:LoadAnimation(anim)
- -- play the animation
- toolAnimName = animName
- currentToolAnimKeyframeHandler = toolAnimTrack.KeyframeReached:connect(toolKeyFrameReachedFunc)
- end
- function stopToolAnimations()
- currentToolAnimKeyframeHandler:disconnect()
- toolAnimInstance = nil
- toolAnimTrack:Stop()
- toolAnimTrack = nil
- return oldAnim
- -------------------------------------------------------------------------------------------
- -------------------------------------------------------------------------------------------
- if speed>0.01 then
- if currentAnimInstance and currentAnimInstance.AnimationId 'http://www.roblox.com/asset/?id=180426354' then
- end
- else
- playAnimation('idle', 0.1, Humanoid)
- end
- end
- function onDied()
- end
- function onJumping()
- jumpAnimTime = jumpAnimDuration
- end
- function onClimbing(speed)
- setAnimationSpeed(speed / 12.0)
- end
- function onGettingUp()
- end
- function onFreeFall()
- playAnimation('fall', fallTransitionTime, Humanoid)
- pose = 'FreeFall'
- pose = 'FallingDown'
- pose = 'Seated'
- pose = 'PlatformStanding'
- if speed>0 then
- else
- end
- for _, kid in ipairs(Figure:GetChildren()) do
- end
- end
- function getToolAnim(tool)
- if c.Name 'toolanim' and c.className 'StringValue' then
- end
- return nil
- playToolAnimation('toolnone', toolTransitionTime, Humanoid)
- end
- if (toolAnim 'Slash') then
- return
- playToolAnimation('toollunge', 0, Humanoid)
- end
- RightShoulder.MaxVelocity = 0.15
- RightShoulder:SetDesiredAngle(3.14 /2)
- RightHip:SetDesiredAngle(3.14 /2)
- end
- local lastTick = 0
- function move(time)
- local frequency = 1
- lastTick = time
- local climbFudge = 0
- jumpAnimTime = jumpAnimTime - deltaTime
- if (pose 'FreeFall' and jumpAnimTime <= 0) then
- playAnimation('fall', fallTransitionTime, Humanoid)
- playAnimation('sit', 0.5, Humanoid)
- elseif (pose 'Running') then
- elseif (pose 'Dead' or pose 'GettingUp' or pose 'FallingDown' or pose 'Seated' or pose 'PlatformStanding') then
- stopAllAnimations()
- frequency = 1
- end
- if (setAngles) then
- desiredAngle = amplitude * math.sin(time * frequency)
- RightShoulder:SetDesiredAngle(desiredAngle + climbFudge)
- LeftShoulder:SetDesiredAngle(desiredAngle - climbFudge)
- LeftHip:SetDesiredAngle(-desiredAngle)
- local tool = getTool()
- toolAnim = animStringValueObject.Value
- animStringValueObject.Parent = nil
- end
- if time > toolAnimTime then
- toolAnim = 'None'
- else
- toolAnim = 'None'
- toolAnimTime = 0
- end
- -- connect events
- Humanoid.Running:connect(onRunning)
- Humanoid.Climbing:connect(onClimbing)
- Humanoid.FreeFalling:connect(onFreeFall)
- Humanoid.Seated:connect(onSeated)
- Humanoid.PlatformStanding:connect(onPlatformStanding)
- game.Players.LocalPlayer.Chatted:connect(function(msg)
- if msg '/e dance' then
- elseif (string.sub(msg, 1, 3) '/e ') then
- elseif (string.sub(msg, 1, 7) '/emote ') then
- end
- if (pose 'Standing' and emoteNames[emote] ~= nil) then
- end
- end)
- playAnimation('idle', 0.1, Humanoid)
- local _, time = wait(0.1)
- end
Product & Tech
We’re always working on new ways to enhance the Roblox experience. Our Avatar Editor, which was launched on smartphones late last year, has been a wild success. The community was thrilled to take avatar editing on the go. With your feedback, we’ve been doing a lot of work behind the scenes to introduce our redesigned Avatar Editor to new platforms. And now, in just a few weeks’ time, we’re going to be bringing this intuitive experience to the Roblox website as well.
Introducing New Ways to Customize
As we put the finishing touches on our website’s new Avatar Editor page, we’d like to give you a quick sneak peek so you know what to expect once it drops in the next few weeks.
We’ve redesigned the architecture of the customization menu on the website so it has a more consistent visual language. It’s better organized, allowing you to seamlessly browse and swap between different categories of clothing, body parts, animations, and costumes.
Avatar Editor Comparison (Left: Desktop; Right: Smartphone)
Our goal is to craft an intuitive experience that allows users to peruse their inventory quickly and easily. If you’ve ever experimented with the Avatar Editor on a smartphone, this page and its functionality will be quite familiar.
Changing Body Colors to Skin Tones
For the first time on the website, we’re also going to be introducing a more refined skin tone color palette that’s less saturated and more authentic than our current “body color” palette.
After choosing a skin tone, all of your avatar’s body parts (Head, Left/Right Arms, Torso, Left/Right Legs) will be replaced with the same color simultaneously.
Important – Action Required: We highly encourage users to save outfits with unique body part colors now if they wish to go back to them in the future. Otherwise, after we launch the new Avatar Editor page in the next few weeks, you will only be able to select one color at a time to represent all body parts going forward. Until then, you can continue customizing the color of individual body parts as you please.
As we continue to expand our modernized Avatar Editor to more platforms, we look forward to hearing your feedback to help us further improve the experience. Come chat with us on the forums or on social media, and stay tuned for more updates soon!