So I got an idea for my upcoming project is to create a “Morale system”. Basically how this work is when your close to your teammate (maximum 3 players in order for it to take affect) or have specific actions (such as getting a kill, near the base, etc), the morale will go up and will boost your stats. If your morale goes down, the stats will be decrease. Those stats would be the weapon’s accuracy, range, etc. I know I will have to use the magnitude and get the character, but I don’t know how to get a specific amount of players. Any help is appreciated!
Wouldn’t you just have a function getSurroundingPlayers(player, distance)
then loop through all the players (game:GetService("Players"):GetChildren()
) and do magnitude checks for each then return the sum and then use that function when the player gets a kill or something.
In this post, what are you exactly asking, are you asking how to make your scripts detect the amount of people around the given person? If not please correct me.
Yes I am planning to do that, but I don’t know how to get specific players (like I only want to get 3, 4 etc players)
Is that possible? If yes, where do I need to put it?
Where ever you need to get the number of players. That might be when the player gets a kill or, if you need the player count constantly, constantly (probably delay that, maybe RunService.Heartbeat
or task.wait(n)
).
I don’t understand much about what you said, yes I will need to get the amount of players around me using framerate but I don’t understand about the magnidute part you said above. Could you give me an example of that if you don’t mind?
So first, you need to loop through the players. You can get a table of the players by getting the children of Players:
game:GetService("Players"):GetChildren()
Now we can loop through that with ipairs
, because the table is an array (it uses numbers as keys, ex: {[1]=player2, [2]=player1}
):
for index, player in ipairs(game:GetService("Players"):GetChildren()) do
--code to run on each player here
end
Then we need to make a sum variable to keep track of the number of players:
local sum = 0
for index, player in ipairs(game:GetService("Players"):GetChildren()) do
--code to run on each player here
end
Now we need to find if the player is close enough. How we do that is we subtract the main player’s position from the other player’s position.
First we learn how to get the player’s character:
local player --Equals the player
local character = player.Character
if not character then
--handle there not being a character
end
The distance between two points is:
--Difference between the two points then the length of the difference
(positionOne - positionTwo).Magnitude
Then we use that stuff and add the function stuff and get this:
--The function stuff
local function getClosePlayers(mainPlayer, distance)
local sum = 0
--Get the main player's character and it's position
local mainCharacter = mainPlayer.Character
if not mainCharacter then
return 0 -- if the main player has no character there are zero surrounding players. You can also return nil and handle it somewhere else.
end
local mainPlayerPosition = mainCharacter.HumanoidRootPart.Position
for index, otherPlayer in ipairs(game:GetService("Players"):GetChildren()) do
--Get the other player's character and it's position
local otherCharacter = otherPlayer.Character
if not otherCharacter then
break --Goes to the next player b|c there is no character for this player
end
local otherPlayerPosition = otherCharacter.HumanoidRootPart.Position
-- We find the difference between the positions, then we find the length of the difference
-- then we check if the distance between the players is within the distance if it is we add
-- to the sum
if (mainPlayerPosition - otherPlayerPosition).Magnitude < distance then
sum = sum + 1
end
end
return sum --Output the sum so you can use it ;)
end
It actually works! Thank you very much. But is there a way to update the player’s position without using RunService.RenderStepped
or RunService.Heartbeat
? Or should I make a while loop inside a thread and run it?
Example of what I mean:
local sum
spawn(function()
while wait(.5) do
sum = getClosePlayers()
end
end)
-- Functions above here will deploy and use the sum variable
And also do you know how to make so when they are in a formation (such as they’re all in a straight line, or they’re in a group (not in a line but it kinda like when your spreading out)), the stats will behave differently (Sorry for asking you too much).
If you’re worried about performance, unless you have 100+ players in a server, it shouldn’t drop performance. I would recommend using Heartbeat.
Aye, I never know the difference between Heartbeat
and RenderStepped
(probably Heartbeat
is for real-time game framerate) but I’ll look into it!
The difference is that Heartbeat runs after physics and rendering, while RenderStepped runs before rendering and will actually block rendering until it is finished. For this reason, don’t use RenderStepped unless it impacts rendering, like updating viewmodels or the camera.