How do I make this script so that it play the animation for the npc when the player is nearby and stop to play the animation of the npc when the player is not nearby and out of range. I tried to debug this for hours now and the animations is either bugging, not playing, and very weird. The animation is an emote from Roblox.
Distance checker function:
local function CheckPlayerDistance(ObjectsToGet: {BasePart})
if #ObjectsToGet == 0 then
return false, nil
end
local minDistance = math.huge
for _, ObjectToGet in ipairs(ObjectsToGet) do
if ObjectToGet and ObjectToGet.Parent:IsA('Model') and ObjectToGet.Parent:FindFirstChildWhichIsA('Humanoid') then
local Config = NPCsQuestConfigs[ObjectToGet.Parent.Parent.Name]
if Config then
local distance = (Hrp.Position - ObjectToGet.Position).Magnitude
if distance <= Config.Trigger.ActivateRange then
return true, ObjectToGet
elseif distance < minDistance then
minDistance = distance
CurrentTarget = ObjectToGet
end
end
end
end
return false, CurrentTarget
end
Animation playing function:
local function PlayNearbyAnim(Status: boolean, TargetHrp: BasePart)
assert(typeof(TargetHrp) == 'Instance' and TargetHrp:IsA('BasePart'), 'Hrp expect to be a BasePart!!')
assert(typeof(Status) == 'boolean', 'Status expect to be a boolean but got '..typeof(Status)..' instead!!')
local TargetChar: Model = TargetHrp.Parent
local TargetHum: Humanoid = TargetHrp.Parent:FindFirstChild('Humanoid')
local Animator: Animator = TargetHum:FindFirstChild(Player.UserId)
if not (TargetHum or Animator) then
warn('Something went wrong with TargetHum or Animator. Please check again! ->', TargetHum, Animator)
return
end
local TargetConfig = NPCsQuestConfigs[TargetChar.Parent.Name]
if not TargetConfig then
warn('Something went wrong with TargetConfig. Please check again! -> ', TargetConfig)
return
end
if Status then
if not PlayDebounces[TargetHrp] then
PlayDebounces[TargetHrp] = true
NearbyAnim.AnimationId = TargetConfig.NPC.Animations.OnNearbyAnimation
local LoadedAnim = Animator:LoadAnimation(NearbyAnim)
if not CurrentTrackList[TargetChar.Parent.Name] then
CurrentTrackList[TargetChar.Parent.Name] = LoadedAnim
end
LoadedAnim:Play()
task.delay(LoadedAnim.Length, function()
PlayDebounces[TargetHrp] = false
end)
end
else
if CurrentTrackList[TargetChar.Parent.Name] then
CurrentTrackList[TargetChar.Parent.Name]:Stop()
end
end
end
Code block where I call the function:
while task.wait() do
local MouseTarget = PlayerMouse.Target
if MouseTarget and CanHover and MouseTarget.Parent:IsA('Model') and MouseTarget.Parent:FindFirstChildWhichIsA('Humanoid') and MouseTarget.Parent.Parent.Parent.Name == 'Quests' then
local Config = NPCsQuestConfigs[MouseTarget.Parent.Parent.Name]
if Config.NPC.HighlightOnHover.Enabled and not MouseTarget.Parent:FindFirstChildWhichIsA('Highlight') then
NewHighlight = Instance.new('Highlight', MouseTarget.Parent)
NewHighlight.Name = 'NPCHighlight'
NewHighlight.DepthMode = Config.NPC.HighlightOnHover.DepthMode
NewHighlight.FillColor = Config.NPC.HighlightOnHover.FillColor
NewHighlight.OutlineColor = Config.NPC.HighlightOnHover.OutlineColor
NewHighlight.OutlineTransparency = Config.NPC.HighlightOnHover.OutlineTransparency
NewHighlight.FillTransparency = Config.NPC.HighlightOnHover.FillTransparency
end
else
if NewHighlight then
NewHighlight:Destroy()
end
end
for _, NPC in QuestsNPCFolder:GetDescendants() do
if NPC:IsA('Model') and NPC:FindFirstChildWhichIsA('Humanoid') then
local NPC_Config = NPCsQuestConfigs[NPC.Parent.Name]
local NPC_Hrp = NPC:WaitForChild('HumanoidRootPart') or NPC.PrimaryPart
local NPC_Hum = NPC:WaitForChild('Humanoid')
if NPC_Hrp and NPC_Hum then
local CurrentNPCCFrame = NPC_Hrp.CFrame
local NPC_Prompt = NPC_Hrp:FindFirstChildWhichIsA('ProximityPrompt')
local NPC_Camera = QuestsNPCFolder:WaitForChild(NPC_Config.Name):FindFirstChild('DialogCamera')
if not table.find(NpcHrpList, NPC_Hrp) then
table.insert(NpcHrpList, NPC_Hrp)
end
if NPC_Prompt and NPC_Config and NPC_Camera and not PromptDebounces[NPC_Prompt] then
PromptDebounces[NPC_Prompt] = NPC_Prompt
if NPC_Prompt:IsA('ProximityPrompt') == false or NPC_Camera:IsA('BasePart') == false then
warn('Something went wrong with the NPC prompt and camera part.')
return
end
NPC_Prompt.ActionText = NPC_Config.Trigger.ActionText
NPC_Prompt.ObjectText = NPC_Config.Trigger.ObjectText
NPC_Prompt.HoldDuration = NPC_Config.Trigger.ActivateCooldown
NPC_Prompt.MaxActivationDistance = NPC_Config.Trigger.ActivateRange
NPC_Prompt.Triggered:Connect(function(PlayerWhoTriggered: Player)
print(NPC_Config.Name)
local PlrGui = PlayerWhoTriggered.PlayerGui
if not PlrGui then
warn('Cannot find PlayerGui in player when starting dialog.')
return
end
local DialogUI = PlrGui:WaitForChild('DialogUI')
local DialogMain = DialogUI:WaitForChild('Main')
local DialogTextHolder = DialogMain:WaitForChild('DialogTextHolder')
local NameLabel = DialogTextHolder:WaitForChild('NameLabel')
local DialogText = DialogTextHolder:WaitForChild('DialogText')
local RotateInfo = TweenInfo.new(NPC_Config.NPC.RotateInfo[1], NPC_Config.NPC.RotateInfo[2], NPC_Config.NPC.RotateInfo[3], NPC_Config.NPC.RotateInfo[4], NPC_Config.NPC.RotateInfo[5], NPC_Config.NPC.RotateInfo[6])
local RotateOpen = TweenService:Create(NPC_Hrp, RotateInfo, {CFrame = CFrame.lookAt(NPC_Hrp.Position, Vector3.new(NPC_Camera.Position.X, NPC_Hrp.Position.Y, NPC_Camera.Position.Z))})
local RotateClose = TweenService:Create(NPC_Hrp, RotateInfo, {CFrame = CurrentNPCCFrame})
QuestStatusSignal:FireServer(true)
Hum.WalkSpeed = 0
StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.All, false)
NameLabel.Text = NPC_Config.Name
CanHover = false
NPC_Prompt.Enabled = false
for _, PlrInGame in Players:GetPlayers() do
if PlrInGame then
local AllPlrChar = PlrInGame.Character or PlrInGame.CharacterAdded:Wait()
if AllPlrChar then
ToggleCharInvisibility(AllPlrChar, true)
end
end
end
Utils.Transition.Run(PlayerWhoTriggered, true, NPC_Config)
RotateOpen:Play()
QuestController.ToggleDialogFrame(PlayerWhoTriggered, NPC_Config, true)
task.delay(RotateOpen.TweenInfo.Time, function()
Utils.Typewriter.typeWrite(DialogText, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 0)
QuestController.AddOption(PlayerWhoTriggered, 'TestOption', 'Click to end quest!!', function()
CompleteQuest(PlayerWhoTriggered, NPC_Config)
RotateClose:Play()
end)
end)
end)
end
if NPC_Config.NPC.PlayAnimOnNearby and not IsInQuest.Value then
task.spawn(function()
local DistanceResult, PartResult = CheckPlayerDistance(NpcHrpList)
if PartResult then
--print(PartResult.Parent.Parent)
PlayNearbyAnim(DistanceResult, PartResult)
end
end)
end
end
end
end
end