Restraint Plugin
See RestraintPluginModule for API
This section includes some intermediate scripting
Introduction
The plugin allows you to setup restraints on your AnimationPlayer's current train model.
Script Setup
To access the restraint plugin module, get it through plugins
like so:
local rtrf = require(ReplicatedStorage.rtrf)
local plugins = rtrf.plugins
local restraintPluginModule = plugins.restraint
local RestraintPlugin = restraintPluginModule.RestraintPlugin
Here we get the plugin itself, RestraintPlugin. It doesn't require a different version for if it's used on server or client. Restraints, however, do.
To get the server version:
local Restraint_Server = restraintPluginModule.Restraint_Server
To get the client version:
local Restraint_Client = restraintPluginModule.Restraint_Client
Adding it to an animation player is similar to other plugin setup.
local animPlayer = rideManager:getAnimationPlayer("Train1")
local restraintPlugin = RestraintPlugin.new(animPlugin, getRestraintsFromModel)
However, you'll notice it requires a second argument which we will refer to as getRestraintsFromModel
.
According to RestraintPlugin's constructor getRestraintsFromModel
is a function which takes a model a returns an array of Restraint
This is where most of the complexity comes from.
getRestraintsFromModel
enables us to be able to manually setup each restraint, but by being explicit in this choice, you have to add more code.
Getting restraints can usually be split into two sections:
- Getting the restraint models
- Setting up the restraint class for each model
You'll notice that this is a more functional-based approach compared to the majority object-oriented approach this
(If you don't know what each of these mean, feel free to read the wikipedia articles for Functional and Object-Oriented Programing (links not setup))
To simplify, the reason this approach was chosen is to prevent what's known as the multiple inheritance problem. I don't want to create different "Restraints" for each different type when they just share different setups.
This approach is already used in code such as AnimationPlayer.
Getting Restraints
The restraintsFromTag
function gets descendants from a Model with the given CollectionService tag.
local restraintsWithTag = restraintPluginModule.restraintsWithTag
-- code
-- ...
local restraintModels = restraintsWithTag()(model)
By default, the tag it will look for will be RESTRAINT
. You can change it by passing it in beforehand like so:
local restraintModels = restraintsWithTag("MY_RESTRAINT_TAG_NAME")(model)
Setting Up Restraints
Restraints modify and react to the seats they are attached to. As such, the Restraint
class constructor needs to be given a RideSeat
.
Getting RideSeat
Depending on how you have your seat system setup, you just need to pass the associated seat Instance like so:
local seat = restraintModel:FindFirstChildOfClass("Seat")
local rideSeat = rideSeatPlugin:getSeat(seat)
Finally, once we have our seat, we create our restraint like so. It is the same on both server and client.
Server:
local restraint = Restraint_Server.new(rideSeat, model)
Client:
local restraint = Restraint_Client.new(rideSeat, model)
Setting Up Multiple Seats
The restraintSystem also supports being able to control multiple seats per restraint.
To setup, just pass in an array of RideSeats:
local rideSeats = {}
table.insert(rideSeats, rideSeat1)
table.insert(rideSeats, rideSeat2)
--- .etc
local restraint = Restraint_Server.new(rideSeats, model)
Model Setup
- Tag any restraint Model with the tag you want to use.
- Setup contents for the restraint plugin you want to use.
Plugins
Similar to AnimationPlayer plugins, these extend and provide functionality to a Restraint.
Controlling Restraints
Once you have your restraints, you need to be able to control them in-game.
setIsOpen sets whether this is open or not.
restraint:setIsOpen(true)
setIsLocked sets whether this restraint is locked or not.
While it is locked, isOpen cannot be changed. This is useful if you want a player to not be able to open/close a restraint while the ride is in motion.
restraint:setIsLocked(true)
Example Code
Example Code (Server)
local restraintPluginModule = plugins.restraint
local RestraintPlugin = restraintPluginModule.RestraintPlugin
local Restraint_Server = restraintPluginModule.Restraint_Server
--- code
--- ...
-- setup restraints
local rideSeatPlugin = createRideSeatPlugin(animPlayer)
local function getRestraintsFromModel(model: Model)
local restraintModels = restraintsWithTag()(model)
local restraints = {}
for _, restraintModel in ipairs(restraintModels) do
local seat = restraintModel:FindFirstChildOfClass("Seat")
local seatWrapper = rideSeatPlugin:getSeat(seat)
local restraint = Restraint_Server.new(seatWrapper, restraintModel)
-- setup restraint plugins
-- ...
table.insert(restraints, restraint)
end
return restraints
end
local restraintPlugin = RestraintPlugin.new(animPlayer, getRestraintsFromModel)
animPlayer.RestraintPlugin = restraintPlugin -- add to animation player
Example Code (Client)
-- init
local restraintPluginModule = plugins.restraint
local RestraintPlugin = restraintPluginModule.RestraintPlugin
local Restraint_Client = restraintPluginModule.Restraint_Client
--- code
--- ...
-- setup restraints
local rideSeatPlugin = createRideSeatPlugin(animPlayer)
local function getRestraintsFromModel(model: Model)
local restraintModels = restraintsWithTag()(model)
local restraints = {}
for _, restraintModel in ipairs(restraintModels) do
local seat = restraintModel:FindFirstChildOfClass("Seat")
local seatWrapper = rideSeatPlugin:getSeat(seat)
local restraint = Restraint_Client.new(seatWrapper, restraintModel)
-- setup restraint plugins
-- ...
table.insert(restraints, restraint)
end
return restraints
end
local restraintPlugin = RestraintPlugin.new(animPlayer, getRestraintsFromModel)
animPlayer.RestraintPlugin = restraintPlugin -- add to animation player