Hi,
I’m super new to the roblox platform and do not have a background in development. I’m working on my own game and am trying to learn through breaking down the things I see that already work in some of the pre-populated games when you launch studio. Specifically the walk-it simulator. I wanted to experiment with the animations in my own game but when I take the model and the script that I think is controlling the animation it doesn’t seem to work in my own game. Can anyone help me find out what I might be missing so I can actually start to mess around with animation?
Here’s the script:
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
-- When the player gets closer than WAVE_THRESHOLD, NPC will wave.
-- Will not wave again until the player goes outside of WAVE_THRESHOLD again.
local WAVE_THRESHOLD = 20 -- studs
local WAVE_DEBOUNCE_TIME = 3 -- seconds
-- Variables
local player = Players.LocalPlayer
local character = script.Parent
local npcModel = workspace.LobbyAssets.NPC
local animationController = npcModel.AnimationController
local animation = Instance.new("Animation")
local lastWavedAt = 0
local characterIsNear = false
local waveAnimationTrack
-- Subtracting position from the CFrame leaves you with just the rotational elements of the CFrame
local rotationOffset = (npcModel.PrimaryPart.CFrame - npcModel.PrimaryPart.CFrame.Position):Inverse()
local Animations = {
SuperheroIdle = 616111295,
Wave = 507770239,
}
local NPC = {
Waist = npcModel.UpperTorso.Waist,
Root = npcModel.LowerTorso.Root,
Neck = npcModel.Head.Neck,
}
local TwistProportions = {
Root = .2,
Waist = .3,
Neck = .5,
Full = 1,
}
-- Helper functions
local function loadAnimation(controller, animationId)
animation.AnimationId = "rbxassetid://" .. animationId
return controller:LoadAnimation(animation)
end
local function isolateAndDampenYAngle(targetCFrame, proportionMultiplier)
proportionMultiplier = proportionMultiplier or 1
local _, y = targetCFrame:ToEulerAnglesXYZ()
return CFrame.new(targetCFrame.Position) * CFrame.Angles(
0,
y * proportionMultiplier,
0
)
end
local function makeNPCLookAt(lookAtPosition)
if not lookAtPosition then
return
end
local differenceVector = lookAtPosition - npcModel.PrimaryPart.Position
local targetCFrame = rotationOffset * CFrame.new(Vector3.new(), differenceVector.Unit) or rotationOffset
-- Let the waving animation move the body
if not waveAnimationTrack.IsPlaying then
NPC.Root.Transform = isolateAndDampenYAngle(targetCFrame, TwistProportions.Root)
NPC.Waist.Transform = isolateAndDampenYAngle(targetCFrame, TwistProportions.Waist)
end
NPC.Neck.Transform = isolateAndDampenYAngle(targetCFrame, waveAnimationTrack.IsPlaying and TwistProportions.Full or TwistProportions.Neck)
return differenceVector.Magnitude
end
-- Create and load the animations
loadAnimation(animationController, Animations.SuperheroIdle):Play()
waveAnimationTrack = loadAnimation(animationController, Animations.Wave)
waveAnimationTrack.Looped = false
RunService.Stepped:Connect(function()
local distance = makeNPCLookAt(character.PrimaryPart.Position)
if distance and distance < WAVE_THRESHOLD then
if tick() - lastWavedAt > WAVE_DEBOUNCE_TIME and not characterIsNear then
waveAnimationTrack:Play(.5)
lastWavedAt = tick()
end
characterIsNear = true
else
characterIsNear = false
end
end)
Here’s a screenshot of the model I’m trying to work with and how it’s setup: