Getting touching parts is gimmicky niche keyword and you shouldn’t rely your entire system on it their is countless ways to achieve this that are many times more reliable here is some example code. Heck your better off just using .touched your use of GetTouchingParts is reinventing the wheel. I will create a code for you okay
Can you show me a image from the explorer I want to see how the ancestory works so I can have the script work perfectly
You know for the referencing in the code
If you don’t you will just have to modify the code to work for your game change some reference etc
nvm i can figure out from the code you showed me
This code i made works perfectly no flaws hope this helped
local CoinSystem = script.Parent
local Speed = 0.1
game.Players.PlayerAdded:Connect(function(Plr)
Plr.CharacterAdded:Connect(function(Char)
while task.wait() do
local Mag = math.floor((Char:WaitForChild("HumanoidRootPart").Position - CoinSystem.AnimationActivator.Position).Magnitude)
if Mag <= 35 then
CoinSystem.Coin.CFrame = CoinSystem.Coin.CFrame * CFrame.fromAxisAngle(Vector3.new(0,Speed,0),Speed)
end
end
end)
end)
I think in my case the issue is calling wait().
On the last level, the user will be able to have up to 8450
Try to apply that script
local distance = 5
local currentOffset = distance
for i = 1, 8450 do
local CoinClone = workspace.Camp.Coin:Clone()
CoinClone.Position += Vector3.new(currentOffset, 0, 0)
CoinClone.Parent = workspace.Camp
currentOffset += distance
end
and please let me know is it work correctly for you. Maybe I’m trying to resolve the issue in the wrong place
i don’t really fully understand what you mean but did my response help you at all? i mean the script makes the coin spin when close and when you get farther away it stops isn’t that what you wanted?
Ok, so, as I understand in my case the issue was when we had a lot of wait() calls their wait for each other (what the surprise ) so at the end between each tick it takes a while for > 8k objects on a map.
There is horrible naming in POC code Coin.Coin → MasterCoin.Coin, you were worn, now you can continue
The solution is to combine @swag4lifex solution with the “PlayerDetector” part.
For us, the most important information is the size (Z and Y because the object is rotated by 90 deg) and the fact that the animation script is disabled at the start.
When the player enters the “PlayerDetector” area the animation will be fired:
local Coin = script.Parent
local PlayerDetector = script.Parent.PlayerDetector
local AnimatinoScript = script.Parent.Coin["Rotate animation"]
PlayerDetector.Touched:Connect(function(otherPart: BasePart)
local HumanoidRootPart = otherPart.Parent:FindFirstChild("HumanoidRootPart")
if HumanoidRootPart then
local player = game.Players:GetPlayerFromCharacter(HumanoidRootPart.Parent)
if not Coin:GetAttribute(player.UserId) then
AnimatinoScript.Enabled = true
end
Coin:SetAttribute(player.UserId, true)
end
end)
In the animation script we count the distance between the coin and the player and when it is larger than half the size of “PlayerDetector” we disable the animation
local MasterCoin = script.Parent.Parent
local PlayerDetector = MasterCoin.PlayerDetector
local Coin = script.Parent
local speed = .1
while wait() do
for userId, _ in pairs(MasterCoin:GetAttributes()) do
local player = game.Players:GetPlayerByUserId(userId)
local HumanoidRootPart = player.Character:WaitForChild("HumanoidRootPart")
if not HumanoidRootPart then
continue
end
local characterPosition = HumanoidRootPart.Position
local coinPosition = Coin.Position
local distance = math.floor((characterPosition - coinPosition).Magnitude)
if distance <= (PlayerDetector.Size.Z / 2) then
Coin.CFrame = Coin.CFrame * CFrame.fromAxisAngle(Vector3.new(speed, 0,0),speed)
else
script.Enabled = false
MasterCoin:SetAttribute(userId, nil)
return
end
end
end
Conclusion: there are only a few wait() calls at the same time and the animations are smooth
If your going to check if the player is in range of something you should use magnitude or region3 and possibly raycast in more advanced cases just don’t use touched it will just cause lag and be innificent
.touched should only be used to see if a play is touching sonething eg. Kill brick speed brick that kind of thing.
(Object1.position - object2.position).magnitude
Put this in a loop use a simple if then logic and boom you can check if the players within distance of an object
Theoretically, I agree but… as you mention I need to
Put this in a loop
So I need some condition for the loop, putin 8k while true do don’t look like a good idea
As I described before using wait() as a “condition” also does not resolve the issue. So when the user touches the invisible part I know he is in a range and touched the handle do nothing more than enable another script once. If there will be a big performance issue, an option is to disconnect the Touched handler (or use :Once instead of :Connect) after enabling AnimationScript and bind it when the user is out of the range.
In my case I don’t need really big precision I just need to know aproxymently how far from the coin model the user is, if it will be exactly half of the Size.Z or +/- 10 - 20 it is ok in my case, for r = 50 (Size.Z = 100) the maring of mismatch is acceptable.
The next thought is to create a “detect area” around the player instead of for each coin separately. In that case, I will have only one while wait() do loop instead of 8k, but:
it required a loop through all objects in the area and check whether is it a coin or not
it will also work when there are will be no coins on the map
it looks like a more complicated solution and does not necessarily have a performance advantage