Hey! I have a cutscene, i want to know how to make it play the first time the player ever join the game, when he is new. This is my first to second time making a thread here, please tell me if I need to provide script! Thanks in advance!
Probably the best tool for this would be a DataStore:
What I’d do is save a value (probably their UserID) into the store once the player sees your cutscene. That way, when they join your game, you can use the same value (their UserID) to check if they’ve been there before:
If the value exists, they have, so don’t show the cutscene;
If not, they haven’t, so go ahead and show it (at which point you’d save their ID in the store).
Not exactly a professional scripter but I think you could use CFrame
to position the camera and Vector3
to move the camera.
local camera = game.Workspace.Camera
camera.CFrame = CFrame.new(camera.Position) + Vector3.new(0, 1.25, 0)
If a player is new, I’d say just have a bool inserted into them once they join and keep that bool in the player using datastore. The data store would check for the bool every time and if it finds it, the bool cancels
Couldn’t you also do a PlayerAdded
event to show the cut scene first?
That method would work, but the post isn’t asking how to do it, it’s about how to it with specific circumstances
Yes, you could, but it would play every time they joined. The poster is asking for this scene to play ONLY on the first time the player plays the game, and never again. The Camera can also only be accessed from a local script. So the PlayerAdded
event would need to fire a RemoteEvent or even a RemoteFunction for more fluidity in the startup introduction process
If you want it to only play when the player plays the game for the first time, then use a datastore. This will be set to true or a random value once the cutscene is over and the next time the player visits the game, they will not see it again. When the player is added, if the value is set to false, then it could fire the client using a remote event and make it run the cutscene, or just clone a local script in the client. I am from my phone currently, so I cannot give the best response. Apologies.
If you have litterally any DataStore in your game this will be really easy.
Heres my example:
-- (this is in a server script)
local CoinsDataStore = game:GetService("DataStoreService"):GetDataStore("Coins") -- our generic datastore
-- *Coins Data store is just an example of some datastore that might be in your game already
game.Players.PlayerAdded:connect(function(Player)
local CoinData = CoinsDataStore:GetAsync(Player.UserId)
local Coins = Instance.new("IntValue")
Coins.Name = "Coins"
local NewPlayer = false -- variable to tell whether player is new
if CoinData ~= nil then -- data exists, player has been here before
Coins.Value = CoinData
else -- data does not exist, player is new
NewPlayer = true
CoinsDataStore:SetAsync(Player.UserId, 0) -- start new data
end
if NewPlayer = true then
-- start tutorial, cutscene, or whatever
end
end)
Breaking Down
What you’ll need to do:
- A data store which checks whether the player is a newcomer – this is a boolean.
- Camera CFrame manipulations, the cutscene itself is a function
- The starting signal would be
PlayerAdded
, add up a remote from client, to make sure it’s starting up correctly(not starting midway when they finish loading).
Happy Birthday @Operatik.
To add on to Operatik. When a player joins the game, you should already be checking a datastore for data. Obviously if the data doesn’t exist then this player has joined for the first time ever since you have to instantiate it.
You can argue that it’s possible the player has played before, but you did a wipe so that’s why there’s no data. And you wouldn’t want the intro to play here.
But despite that you actually do want the intro to play here.
Camera Manipulation is key to a good cutscene / intro. What I did was do some simple logic on the camera using the TweenService to interpolate the camera between two parts. A collection of parts in my case is considered a “track” and the camera follow this track where each part in the track is a “node”.
It works really well, and by modifying the tween you can get different camera effects. I’m very pleased with how it turned out
Edit: After some post post proof reading (see what I did there?) I’ve realized that if you wanted to play a cutscene AFTER checking the datastore, you would indeed need to use PlayerAdded. But for an intro, you can just play it right on out if it’s something that will play everytime you join the game.
Contrary to what Operatik says, the starting signal actually doesn’t have to be PlayerAdded
.
As long as you load in all assets to your entire scene inside of “Replicated First” or run a script inside of “Replicated First” that waits for assets inside of “Replicated Storage” you can actually play your intro any time. This is actually how the intro in the video works. In fact the terrain water is generated, the ship is created, and the track already exists inside of the script. So I’ve disabled Roblox’s default loading screen and replaced it entirely with my intro and custom GUI.
(Yes, loading in terrain defeats the purpose of Replicated First.) Ultimately the example I chose to explain was intro’s, but generally my module lets me play a cutscene whenever I want and has effects specifically for that purpose.
I’m eager to see what you come up with
That is correct. My reason for creating a “NewPlayer” variable was just for extra usefulness in case you have any other “new player” programs you want to run later in the script. Checking whether they had played or not (CoinData ~= nil) was unnecessary for the OP, I think I just added it to continue the generic datastore code’s function.