Part 2 Remote Events & Functions In this section, we’ll be talking about Remote Events & Remote Functions + how to secure them as much as possible. Introduction:So first, what are they and why do we need them? As mentioned above, the idea of using RemoteEvents and RemoteFunctions is to help us handle our game as correctly as possible, and to protect our game from being completely ruined. From the moment they were added, we now can use them to prevent exploiters from doing some crazy and weird exploits. Le’ts begin! Remote EventsA remote event allows us to : one-way communicate across the client-server boundary. You can use it to send requests across the boundary without yielding for a response.[ Meaning: You could use these to handle things on the server / client when needed. When can I use remote events ? Using this to fire an event from a certain client[player] to the server, so that everyone could see those changes. Let’s have an example: --Local Script, StarterGui local Replicated = game:GetService("ReplicatedStorage") local UserInput = game:GetService("UserInputService") local Remote = Replicated:WaitForChild("ClientServer") UserInput.InputBegan:Connect(function(Key,IsTyping) if IsTyping then return end -- if he's typing in chat/anything like that. if Key.KeyCode == Enum.KeyCode.K then Remote:FireServer("string1",Color3.fromHSV(0.056, 0.501961, 1),25) end end) --Server Script local Replicated = game:GetService("ReplicatedStorage") local Remote = Replicated.ClientServer Remote.OnServerEvent:Connect(function(Player,arg1,arg2,arg3) -- Player is the player who fired the remote. --Let's check their types, to see that an exploiter didn't provide a not matching type --If the types are not matching, we end the function. if typeof(arg1) ~= "string" and typeof(arg2) ~= "Color3" and typeof(arg3) ~= "number" then return end print(Player.Name.." has fired a remote!") end) Server --> Client --Server Script local Replicated = game:GetService("ReplicatedStorage") local Players = game:GetService("Players") local Remote = Replicated.ServerClient Players.PlayerAdded:Connect(function(Player) Remote:FireClient(Player,Player.Name) end) --Local Script, StarterPlayerScripts local Replicated = game:GetService("ReplicatedStorage") local Remote = Replicated:WaitForChild("ServerClient") Remote.OnClientEvent:Connect(function(Player) game:GetService("StarterGui"):SetCore("ChatMakeSystemMessage",{ Text = string.format("Hey %s , welcome to the game!",Player); Color = Color3.fromRGB(85, 255, 127) }) end) Server --> All Clients --Server Script local Replicated = game:GetService("ReplicatedStorage") local Players = game:GetService("Players") local Remote = Replicated.ServerClients Players.PlayerAdded:Connect(function(Player) Remote:FireAllClients(Player.Name) end) --Local Script, StarterPlayerScripts local Replicated = game:GetService("ReplicatedStorage") local Remote = Replicated:WaitForChild("ServerClients") Remote.OnClientEvent:Connect(function(Player) game:GetService("StarterGui"):SetCore("ChatMakeSystemMessage",{ Text = string.format("%s has joined the game!",Player); Color = Color3.fromRGB(255, 170, 127) }) end)As you can see here, on the server side, we’re using FireAllClients() function, which would fire/ notify every client[player] in the game, about the given event/message provided / made on the client. Note: the message could’ve been made on the server and sent as the second argument within the FireAllClients(). This can’t be directly done, so it has to be through the server. Here is how: A remote function , unlike remote events, allow us to two-way communicate across the client-server boundary. You can use it to send requests across the boundary and yield for a response. Here it what it means: Player1: Invokes the server [ using InvokeServer()], then, on the server ,he returns something [ most commonly is booleans], and then - on the client, he can use that result after he assigned the InvokeServer() call as a variable, like this -local call = remote:InvokeServer(). (This is very useful when we want to make a code redeeming system, for example, or even a trade system). When can I use remote functions? Not recommended, do not try it unless you’ve a strong sanity checks that would prevent exploiters from ruining and messing up with it. These are the risks you could have with it: 1.If the client throws an error, the server throws the error too. In this section, we’ll be talking about the Player and its ‘visual’ appearance - the Character. The Player is an object/instance, where you can view most of the main things/properties your player/other players have in-game[ and some can actually give info from out of the game]. To be a bit more accurate, every Player object represents the Client when they’re connected to the game. PropertiesLike every other object, the Player object has properties aswell, let’s review some of them: CharacterThis property is an ObjectValue, and it should represent the actual model of the player - the character [ which we can visually see in-games]. DisplayNameObviously, this property is a String, and it should represent the DisplayName of the player. AccountAge [Read Only]This property is a Number , and it automatically updates the Age [in days] of the player. This property belongs to the Team class, and this allows us to know/edit and change the player’s team.The Team value itself, is an ObjectValue. And it’s supposed to represent the player’s team or nil [if the team doesnt exist/destroyed]. EventsIn here, we’ll be talking about some cool and useful events the Player object has. CharacterAdded(Character)This event should fire every time the player’s character spawns or respawns. local Players = game:GetService("Players") Players.PlayerAdded:Connect(function(Player) print(Player.Name.."- Player Instance") Player.CharacterAdded:Connect(function(Character) print(Character.Name.."- Model Instance") end) end) Chatted(Message)This event would fire each time the player is chatting through Roblox built-in chat. local Players = game:GetService("Players") Players.PlayerAdded:Connect(function(Player) Player.Chatted:Connect(function(Message) print(string.format("%s has said the word: %s",Player.Name,Message)) end) end) MethodsIn here, we’ll be talking about some useful methods you might need to know and use. ClearCharacterAppearance()This method would remove all accessories and objects from the player’s character.[if they are decals, accessories and clothes]. local Players = game:GetService("Players") Players.PlayerAdded:Connect(function(Player) print(Player.Name.."- Player Instance") Player.CharacterAppearanceLoaded:Connect(function(Character) Player:ClearCharacterAppearance() end) end) Kick(Message)This method would kick the player from your game and show him the given message [if given], if not,t then the default Roblox message. local Players = game:GetService("Players") Players.PlayerAdded:Connect(function(Player) Player:Kick("Test") end) CharacterThe Character is a Model object, which should represent the player’s character [ or any player’s character], and can also be used for making NPC’s. Every character essentially contains: Like every other object/instance, the Character object has properties aswell, let’s review some of them. ArchivableThis property [ boolean ] would determine if the object is included in the game and can be seen when published and it also impacts to clone objects. If set to false, the object won’t be cloned. If set to true, the object will be cloned when using the Clone() method. local newObject = Instance.new("Part") print(newObject:Clone()) --> Part, because `Archivable` is automatically set here to true newObject.Archivable = false print(newObject:Clone()) --> nil PrimaryPartThis is an ObjectValue, which refers to the PrimaryPart of your model. You should know that - In here, we’ll be talking about some useful events to use on our character. AncestryChanged()This event would run when the parent or any of its ancestors is changed. It includes 2 parameters: child and parent. Where: child is the object whose parent was changed. In this section, we’ll be learning about some cool and useful methods to use on our character. BreakJoints()This method will break any connection between parts in your character. Using this on your character, will kill you [ by killing your humanoid]. local Players = game:GetService("Players") Players.PlayerAdded:Connect(function(Player) Player.CharacterAdded:Connect(function(Char) task.wait(1) Char:BreakJoints() end) end) MoveTo()This method will move the character/any model’s primary part to the provided position.Make sure your model always has a PrimaryPart. Because if your model doesnt have one, this would select the root part of that model as the primary part. And, since the root part is not deterministic, it is recommended to always set a primary part. Tools, Backpack & StarterGearIn this section, we’ll be talking about tools, backpack ,startergear, and how to use and how they work. ToolsBy definition, tools on Roblox are objects which the Character[ if he has a humanoid within], can equip , unequip and activate it. Notice this pattern: You notice that when you die, you lose your tools. How can you prevent this? On desktops,pressing a number key (1, 2, 3…) will equip the tool whose index is at that number key. The tool in the above example will create an explosion at the position of the tool owner. In here, we’ll be talking about some useful properties you might need when working with tools. CanBeDropped [ boolean ]This property will determine if you can drop your tool [by pressing Backspace] or not. Enabled [ boolean ]This property will determine if you can actually use the tool or not.[ Say you wanted to remain that tool in the player’s backpack, but only preventing him from using it]. This property determines if your tool can work without the need of a handle. In here, we’ll be talking about some useful events on tools. ActivatedThis event runs whenever the player clicks while equipping a tool. This event runs whenever the player equips a tool. local Tool = script.Parent Tool.Equipped:Connect(function() print(string.format("%s was equipped!",Tool.Name)) end) MethodsIn this section, we’ll be learning about some useful methods to do with tools. ClearAllChildren()This method simply clears every child / descendant of the given object. In this category, we’ll be trying to understand the ideas behind gamepasses and devproducts, and what they do.Before we dive into that, let’s first explain what service they stand behind. In this part, we’ll be using the Marketplace Service. It has many many events, as well as methods. We’ll be talking about some prominent ones. EventsHere,we’ll be talking about some very useful events to work with MarketplaceService. PromptGamePassPurchaseFinishedThis event would run whenever the purchase dialog of a game pass is closed.Meaning whenever the player presses either ‘OK’ or ‘Cancel’. It contains 3 parameters: player[instance]: the player object whom got the prompt. Notice that we got false here, because I already own this gamepass. PromptPremiumPurchaseFinishedFires whenever the premium purchase modal closes[ meaning ‘Cancel’ or ‘OK’ buttons]. --Defining Services local MarketplaceService = game:GetService("MarketplaceService") local Players = game:GetService("Players") MarketplaceService.PromptPremiumPurchaseFinished:Connect(function() print("Player either closed or purchased premium!") end) task.wait(5) --Prompting a Gamepass Purchase for the testing MarketplaceService:PromptPremiumPurchase(Players.LocalPlayer) MethodsIn this section, we’ll be learning about some useful methods. PromptGamePassPurchase()This method prompts the given player, the given gamePassID. --Defining Services local MarketplaceService = game:GetService("MarketplaceService") local Players = game:GetService("Players") local GamepassID = 000000000 -- change it to your gamepass ID --Prompting a Gamepass Purchase for the testing MarketplaceService:PromptGamePassPurchase(Players.LocalPlayer,GamepassID) PromptPremiumPurchase()This method simply prompts the player to buy/get premium from the game.[Only parameter is the player whom this will be shown to]. GetDeveloperProductsAsync()This method returns pages/lists of all current DevProducts the game has. local MarketplaceService = game:GetService("MarketplaceService") local developerProducts = MarketplaceService:GetDeveloperProductsAsync():GetCurrentPage() for _, devProduct in pairs(developerProducts) do for index, value in pairs(devProduct) do print(index .. ": " .. value) end print(" ") end --Result: --[[ DeveloperProductId: 16344291 displayName: Developer Product 1 Name: Developer Product 1 ProductId: 1316305655 PriceInRobux: 25 ]] GetProductInfo()This method returns information about an asset,dev product or even a gamepass. In this section, we’ll be learning about ClickDetectors and ProximityPrompts. Introduction:So, before we dive into it. Let’s first understand what they are and what they do. ClickDetectors:allow us receive pointer input on 3D objects through their MouseClick event, meaning - lets us click on objects with our cursor, and do lots of stuff. They only work if they’re parented to: ProximityPrompts: unlike ClickDetectors, ProximityPrompts are visualized gui that appears each time the player approaches to objects, within a certain range of a distance. So after that introduction, let’s begin by learning some of its properties and events. Properties CursorIcon[Content]This property allows you to change the icon of your cursor. MaxActivationDistance[number]This property tells you from what distance you’re able to click and activate that clickdetector. Events MouseClickThis event fires everytime a player presses and releases the left mouse button while the cursor is hovering over a model or any basepart with a clickdetector.Also, it’s important for the player’s character to be within the MaxActivationDistance, in order to activate it. local clickDetector = script.Parent:FindFirstChild("ClickDetector") clickDetector.MouseClick:Connect(function(Player) -- Player is a parameter for the player who clicked on it print(string.format("%s has pressed on me!",Player.Name)) end) MouseHoverEnterThis event runs whenever the player begins to hover his cursor over the ClickDetector's parent.[Can be used in both Script and LocalScript]. local clickDetector = script.Parent:FindFirstChild("ClickDetector") clickDetector.MouseHoverEnter:Connect(function(Player) -- Player is a parameter for the player who clicked on it print(string.format("%s has hovered his cursor!",Player.Name)) end) ProximityPromptsSo after that introduction, let’s begin by learning some of its properties and events. Properties ActionText[string]This property is where the text you’ll see on your prompt, like this: This would determine how long the player would have to hold the prompt. MaxActivationDistance[float]This would help you determine from what distance the player can activate the prompt. Events TriggeredThis event runs whenever the player has done clicking/holding the prompt [and finished it]. script.Parent.Triggered:Connect(function() print("Prompt has been triggered!") game.Workspace.Baseplate.Size = Vector3.new(4,4,4) end) PromptButtonHoldBeganThis event runs whenever the prompt is being held by the player[make sure HoldDuration is > 0]. script.Parent.PromptButtonHoldBegan:Connect(function() print("Prompt triggering has begun") end) TweenServiceIn this section, we’ll be learning about TweenService, what it does and how to use it. Introduction:Tweens are used to interpolate the properties of instances. Meaning, to edit,modify and change them in style/animation.Notice! Only the following types can be used in TweenService: To start using this server and its features, you should use the main function : TweenService:Create(), which takes information about the object and acts accordingly when playing the tween. NOTES: In this section, we’ll be learning about Camera ; what it is , and what it does. Introduction:Camera on Roblox is a special object which lets us define and view the world from a 3D prespective. The Camera object has many important proprties, however - only 5 of them are more important than others, and these are: [Camera.CFrame]: Simply represents the position and rotation of the camera. In this section, we’ll be learning how to apply animations onto tools/player’s character. For animation replication to function it is important for the Animator to be first created on the server. The Animator object must be initially created on the server and replicated to others for animation replication in order to be shown to all. If the Animator is created locally, then any animation loaded through this animator, won’t replicate to server. Loading Animation:You’ll need to use the LoadAnimation() method ,and provide an Animation object [NOT its animationID]. An example: local UIS = game:GetService('UserInputService') local Players = game:GetService("Players") local Player = Players.LocalPlayer local Character = Player.Character or Player.CharacterAdded:Wait() local Humanoid = Character:WaitForChild("Humanoid") local Anim = Instance.new('Animation') Anim.AnimationId = 'rbxassetid://10910827063' --Start Running Animation UIS.InputBegan:connect(function(input,processed) if processed then return end if input.KeyCode == Enum.KeyCode.LeftShift then Humanoid.WalkSpeed = 24 PlayAnim = Humanoid:LoadAnimation(Anim) PlayAnim:Play() end end) --Stop Running Animation UIS.InputEnded:connect(function(input) if input.KeyCode == Enum.KeyCode.LeftShift then Humanoid.WalkSpeed = 16 if PlayAnim then PlayAnim:Stop() PlayAnim:Destroy() end end end) Mouse & UserInputServiceIn this section, we’ll be learning about Mouse and UserInputService ; what they are and what they do. Introduction:Mouse: Although Mouse is deprecated [UserInputService and ContextActionService are its replacement], This property returns the mouse’s position in the 3D space which we work with in studio. Target(BasePart)This property returns the 3D object which the mouse is pointing to. This event fires whenever the mouse is moved.[Only when the mouse’s position is updated/changed]. local Players = game:GetService("Players") local Player = Players.LocalPlayer local Mouse = Player:GetMouse() Mouse.Move:Connect(function() local Target = Mouse.Target print(Target) -- would print nil if pointed to sky end)UserInputService: This service is client-sided only. Meaning, it can only be used on the client. Which obviously means - you can only use it in LocalScript's or in ModuleScript's required by localscripts. Properties MouseEnabled[boolean]This property checks if the player’s device has a mouse.[ and returns true if found], if not found - it returns false. TouchEnabled[boolean]Simply checks if the player’s device has any available touch screen. Simply checks if the player is using a VR device. If a VR device was found, you could use some events such as UserInputService:GetUserCFrame() to do some cool stuff with it. Events InputBeganThis event would run whenever a player begins interacting with one of the following devices [ pc,mobile,console,vr,etc]. local UserInputService = game:GetService("UserInputService") UserInputService.InputBegan:Connect(function(Key,Processed) if Processed then return end -- if I am during chatting, then end the function. print(Key.KeyCode.Name) -- would print the name of the pressed key. end) InputChangedThis would fire everytime the player is changing their interaction type [ for example: Mouse button down]. local UserInputService = game:GetService("UserInputService") UserInputService.InputChanged:Connect(function(Key,Processed) if Processed then return end -- if I am during chatting, then end the function. if Key.UserInputType == Enum.UserInputType.MouseMovement then print("The Mouse has been moved!") end end)Here is Part2, since I couldnt fit it in the original post because of a limit. (责任编辑:) |