What do you want to achieve?
As of right now, the script uses the mouse, but the mouse is incredibly unreliable when it comes to clicking on the PlayerModel—hence, I’d like to use a proximity prompt instead.
Here’s a video of what I’d like to achieve, but instead of using the mouse—it uses the proximity prompt instead:
What is the issue?
Since I’m new to scripting, I’m not sure how to accomplish this! I’ve spent hours trying to get the player from the proximity prompt, but nothing seems to work.
Screenshots:
ServerScript:
local Players = game:GetService("Players")
local ProximityPromptService = game:GetService("ProximityPromptService")
local replicatedStorage = game:GetService("ReplicatedStorage")
local getEmoteAnimationId = replicatedStorage.CrossCommunication:WaitForChild("GetEmoteAnimationId")
local function onPlayerAdded(player)
player.CharacterAdded:Connect(function(character)
-- Wait for the character to load
character:WaitForChild("HumanoidRootPart")
-- Create a ProximityPrompt for the owner player
local ownerPrompt = Instance.new("ProximityPrompt")
ownerPrompt.Name = "OwnerPrompt"
ownerPrompt.ActionText = "Join"
ownerPrompt.ObjectText = "Hold E to join dance!"
ownerPrompt.Parent = character.HumanoidRootPart
ownerPrompt.RequiresLineOfSight = false
end)
end
-- Connect the function to the PlayerAdded event
Players.PlayerAdded:Connect(onPlayerAdded)
LocalScript (in StarterPlayerScripts):
local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local Animator = Humanoid:WaitForChild("Animator")
local Mouse = LocalPlayer:GetMouse()
UserInputService.InputBegan:Connect(function(inputObj, processed)
if not processed and inputObj.UserInputType == Enum.UserInputType.MouseButton1 then
-- checks if input is mouse
local PlayerModel: Model = Mouse.Target.Parent
-- gets the Player's model
if PlayerModel:IsA("Model") then
local targetPlayer = Players:GetPlayerFromCharacter(PlayerModel)
-- checks if this is a Player
if PlayerModel:FindFirstChild("Humanoid") or targetPlayer then
-- checks if the model is a Player's character or an NPC.
-- you can modify to just players by removing "PlayerModel:FindFirstChild("Humanoid")
local targetHumanoid = PlayerModel:WaitForChild("Humanoid") :: Humanoid
local targetAnimator = targetHumanoid:WaitForChild("Animator") :: Animator
local playingAnimations = targetAnimator:GetPlayingAnimationTracks()
local currentAnimation = playingAnimations[1] :: Instance | AnimationTrack
-- gets the first playing animation, aka higher priority
if not currentAnimation then return end
-- if there's no animation, exit
local timeStamp = currentAnimation.TimePosition :: number
-- gets the current playing time
local Animation = Animator:LoadAnimation(currentAnimation.Animation) :: AnimationTrack
-- loads the animation
Animation:Play()
Animation.TimePosition = timeStamp
-- plays the animation and sets the time to the same timestamp
elseif not targetPlayer then return end
-- if it's not a player or an npc then do nothing
end
end
end)
Since PlayerScripts isn’t able to be accessed on the server, and all LocalScripts inside of StarterPlayerScripts are placed into the player’s PlayerScripts, there are 2 methods you can use to solve your problem which are:
Use a RemoteEvent to send a signal to the LocalScript when the prompt is triggered
Create the prompt inside of the LocalScript itself
I’ve tried using a RemoteEvent to send a signal to the LocalScript when the prompt is triggered, but I feel like I’m not doing it right cause none of my prints worked :\
I created the prompts on the server so other players can see them, as when I create them on the client, they’re only visible from that player’s client. What do you suggest I do?
If you create the prompts on the client, then while the server cant see them all the players can have their own individual prompts. They still have them its just not replicated on the server.
I personally recommend just to move it all to the client.
Thank you for the reply! I’ve tried this method, but because the prompt is created with Instance.new, I’ve been having some difficulty making sure the path is correct. In addition to the Server vs Client communication
If you want other players to be able to see the prompt, then the RemoteEvent method needs to be used. I’ll need to know what you’d like to happen when the prompt is triggered to be able to write code though
Wait… I can do this?! I wish I knew how to do it! One of the things I’ve FINALLY accomplished after many hours was making it so the proximity prompt was only visible to other players but not the player whose HumanoidRootPart it was inside… would this still be possible?
When the prompt is triggered I’d like it to do the same code as the LocalScript—what the script is doing essentially is syncing the player’s animation to the targetplayer’s animation.
I’ll start writing the code now and will update this reply when ready
Edit: @Auevi Quick question: Do you want the player who triggered the prompt to dance or the player who’s prompt got triggered? Also, I’m noticing an important detail which is if you start the dance within a LocalScript other player’s wont see that player dance, which means we might need to start the dance on the server as well if that’s the case (I’ll see if it’s possible to do so locally just in case)
Edit2: Currently I’m combatting the very annoying “Property “Animator.EvaluationThrottled” is not currently enabled.” error
Edit3: @Auevi Hopefully these script works as you’d wish: Server Script inside of ServerScriptService:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local remoteEvent = ReplicatedStorage.RemoteEvent
local function onTriggered(player)
remoteEvent:FireAllClients(player)
end
local function onCharacterAdded(character, player)
local ownerPrompt = Instance.new("ProximityPrompt")
ownerPrompt.ActionText = "Join"
ownerPrompt.Name = "OwnerPrompt"
ownerPrompt.HoldDuration = 1 -- I added this because in the object text you wrote "Hold E"
ownerPrompt.ObjectText = "Hold E to join dance!"
ownerPrompt.RequiresLineOfSight = false
ownerPrompt.Parent = character.PrimaryPart
ownerPrompt.Triggered:Connect(function()
onTriggered(player)
end)
end
local function onPlayerAdded(player)
player.CharacterAdded:Connect(function(character)
onCharacterAdded(character, player)
end)
end
Players.PlayerAdded:Connect(onPlayerAdded)
LocalScript inside of StarterPlayerScripts:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
local function onClientEvent(player)
if player.Character then
local animator = player.Character.Humanoid.Animator
local currentAnimation = animator:GetPlayingAnimationTracks()[1]
if currentAnimation then
local timePosition = currentAnimation.TimePosition
local animation = animator:LoadAnimation(currentAnimation.Animation)
animation:Play()
animation.TimePosition = timePosition
end
end
end
remoteEvent.OnClientEvent:Connect(onClientEvent)
You’ll also need to add a RemoteEvent inside of ReplicatedStorage, for the sake of testing I left it with the default name of “RemoteEvent”
That might be more of a challenge.
If your going that route, making it only visible to select players, id recommend trying to create your own type of “proximity prompt” from scratch entirely. Recommend searching up “UserInputService” and doing some research into that.
I’ve made my own custom proximity prompts before, but my main issue is just getting the proximity prompt to work as I’ve already accomplished the proximity prompt “other player” visibility.
Oh no, I just meant unfortunately because usually output errors can help us find the issue and since there isn’t errors being printed, it will be more difficult.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local remoteEvent = ReplicatedStorage.RemoteEvent
local function onTriggered(player1, player2)
remoteEvent:FireAllClients(player1, player2)
end
local function onCharacterAdded(character, player1)
local ownerPrompt = Instance.new("ProximityPrompt")
ownerPrompt.ActionText = "Join"
ownerPrompt.Name = "OwnerPrompt"
ownerPrompt.HoldDuration = 1 -- I added this because in the object text you wrote "Hold E"
ownerPrompt.ObjectText = "Hold E to join dance!"
ownerPrompt.RequiresLineOfSight = false
ownerPrompt.Parent = character.PrimaryPart
ownerPrompt.Triggered:Connect(function(player2)
onTriggered(player1, player2)
end)
end
local function onPlayerAdded(player)
player.CharacterAdded:Connect(function(character)
onCharacterAdded(character, player)
end)
end
Players.PlayerAdded:Connect(onPlayerAdded)
The new LocalScript:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
local function dance(player)
if player.Character then
local animator = player.Character.Humanoid.Animator
local currentAnimation = animator:GetPlayingAnimationTracks()[1]
if currentAnimation then
local timePosition = currentAnimation.TimePosition
local animation = animator:LoadAnimation(currentAnimation.Animation)
animation:Play()
animation.TimePosition = timePosition
end
end
end
local function onClientEvent(player1, player2)
dance(player1)
dance(player2)
end
remoteEvent.OnClientEvent:Connect(onClientEvent)