1
votes

What I'm trying to do: I want to have a tree and every few seconds an Apple falls down from that tree. Player can "pick up" that Apple. If more players are in the game, player who picks up the most apples, wins.

What I have: I have a tree and apples are falling down. Until here it works perfect. Player can pick up an apple - if he touches the apple by his foot, apple is destroyed and player gets 1 point. Still OK.

What is wrong: If more players join the game, it looks like every player can see his own (local) apple. So if Player1 picks up an apple, apple is destroyed - but only for him :( all other players can see that apple still there and they can pick it up too. If I test-run the game with 2 players, in the server-window I can see that apple still there, even after all players picked it up. So the server has it's own instance apparently.

But I want just one global apple.

Application is like this:

I have an apple in the Workspace. Every few seconds I clone it in the script (not local script, but Script) which is under the AppleTree model in Workspace:

function GrowNewApple()

    local newApplePos = GetRandomPlace()
    local appleTemplate = workspace.apples.prototype
    local newApple = appleTemplate:Clone()

    newApple.Parent = appleTemplate.Parent
    newApple.Name = "apple"
    newApple.Position = newApplePos
end

In StarterPlayer / StarterPlayerScripts I have a localscript with this:

local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:wait()

character:WaitForChild("LeftFoot")

character.LeftFoot.Touched:Connect( PickUpApple )

And finally my PickUpApple function looks like this:

function PickUpApple( touchObject )

    if touchObject:IsDescendantOf(workspace.apples) then
        touchObject:Destroy()
    end
end

Any ideas please?

Is it because the PickUpApple() is called from LocalScript? Is it possible that this LocalScript is sending local touchObject into this function?

I have no idea how to do this. Thanks guys.

2

2 Answers

0
votes

Deleting the apple from a local script will only delete it for the client, To prevent this, Try it so the apple gets deleted by a server side script, You have 2 options:

1, Make the script a server side script and make sure it's compatible for the server.

2, Make a remote event which is fired once the local script detects the local player touching an apple, And make sure the remote event is connected to a function that deletes the apple and gives the player a point, Should be a server script, To do that:

1, Create a RemoteEvent (Make sure it's a RemoteEvent not a RemoteFunction!) in the ReplicatedStorage and rename it to "PickupApple".

2, Change the local script to:

local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:wait()
local event = game.ReplicatedStorage:WaitForChild("PickupApple")
local apples = workspace:WaitForChild("apples")  -- Using WaitForChild() function to prevent errors for requesting the object before it loads


character:WaitForChild("LeftFoot")

character.LeftFoot.Touched:Connect(function(touchObject)
   if touchObject:IsDescendantOf(apples) then
       event:FireServer(touchObject)
   end
end)

3, Create a script (Not a LocalScript!) in the ServerScriptService, And put this:

game.ReplicatedStorage.PickupApple.OnServerEvent:Connect(function(player, item)
   if item:IsDescendantOf(workspace.apples) then
      item:Destroy()
      -- Add here any extra code such as giving points, etc
   end
end)
0
votes

OK, problem solved.

The problem was that Touched event was fired on Local Player parts (feet, legs). This has sent the local instance of the apple to the Touched Event Handler.

Now I removed this:

character.LeftFoot.Touched:Connect( PickUpApple )

and instead of firing Touched on player foot I moved it to the Apple part and now I'm firing Touched event on that Apple part.

apple.Touched:Connect(PickUpApple)

And it works. While Apple part sends to the Touched Event Handler player's foot which is OK - I don't need to destroy it - I can destroy Apple now.

I have to say I moved whole function PickUpApple() into the apple part also so I have direct access to the apple part itself.