Hi, forgive me for my bad English, I’m not a native speaker but I’d be happy to help the community.
Synchronized Scenes have a lot of potential, but I don’t see people using them a lot, and I understand that they are rather hard and ANNOYING to deal with, talking from experience.
Today I decided to create a simplified guide on how to use Synchronised Scenes for your resources!
Helpful Resources
First of all, these resources I’ve found are going to be of GREAT HELP to you if you’re dealing with synchronized scenes.
Synchronised Animations List - This is very helpful! This contains a lot of synchronized scenes (not all). It gives you the index of the animations and all of the objects required for it.
You may ask, how do I get the animation from its index?
You get it from this animation list right here: Updated Animations List
It is formatted in the format:
[index] [anim_dict] [anim] [duration]
Yes! It even gives you the duration, so no need to use GetAnimDuration anymore!
Let’s get into the action!
Preperation
The main natives we’re going to use are:
NetworkCreateSynchronisedScene
NetworkAddPedToSynchronisedScene
NetworkAddEntityToSynchronisedScene
NetworkAddSynchronisedSceneCamera
NetworkStartSynchronisedScene
NetworkStopSynchronisedScene
Explanation
This is going to create a handle/id for your scene, it returns an id that you have to store as a variable to be able to use it effectively
This is going to register a new ped (the player, or another ped) in the scene and assign it an animation to play during the scene.
This will add a new entity, which is usually an object, to your synchronized scene! Note that the object has to be created and loaded by you beforehand… duh
This creates a camera effect for the player, like the ones we all know which is used in GTAO by Rockstar.
As the name suggests, this starts the scene after you’ve prepared it using all of the previously mentioned natives
This stops the synchronized scene, I suggest you stop the scene after the duration of it ends (using the GetAnimDuration native, or the listed duration in the Animations file, but you may also use it for example if you are checking if the player is dead, and he died, then you could stop the synchronized scene immediately
Examples
In this example, I’m going to create an advanced drilling enter, synchronized scene.
RegisterCommand("startscene", function()
while not HasAnimDictLoaded("anim_heist@hs3f@ig9_vault_drill@drill@") do
RequestAnimDict("anim_heist@hs3f@ig9_vault_drill@drill@")
Wait(1)
end
while not HasModelLoaded(GetHashKey('hei_prop_heist_drill')) do
RequestModel(GetHashKey('hei_prop_heist_drill'))
Wait(1)
end
while not HasModelLoaded(GetHashKey('hei_p_m_bag_var22_arm_s')) do
RequestModel(GetHashKey('hei_p_m_bag_var22_arm_s'))
Wait(1)
end
local ped = PlayerPedId()
local pedCoords = GetEntityCoords(ped) -- I suggest you save the coords in the beginning, and use them for all of the following scenes because it seems to cause problems if you use the current coords every time
local pedRotation = GetEntityRotation(ped)
local drill = CreateObject(GetHashKey('hei_prop_heist_drill'), pedCoords,true,true,true) -- creating the drill's object
local bag = CreateObject(GetHashKey('hei_p_m_bag_var22_arm_s'), pedCoords,true,true,true) -- creating the bag object
local intro = NetworkCreateSynchronisedScene(pedCoords.xy,pedCoords.z+.17,pedRotation, 2, false, false, -1, 0, 1.0)
-- you may notice I added 0.17 to the z-coordinate. Some scenes make the player go underground, so you may have to add or subtract some of the z-coordinate,
-- the value you need to subtract/add is mentioned in the SceneDirectorSynchedAnim.xml file as "deltaZ".
NetworkAddPedToSynchronisedScene(ped, intro, "anim_heist@hs3f@ig9_vault_drill@drill@", "intro", 1.5, -4.0, 1, 16, 1148846080, 0) -- adding the ped to the scene
NetworkAddEntityToSynchronisedScene(drill, intro, "anim_heist@hs3f@ig9_vault_drill@drill@", "intro_drill_bit", 1.0, 1.0, 1) -- adding the drill to the scene
NetworkAddEntityToSynchronisedScene(bag, intro, "anim_heist@hs3f@ig9_vault_drill@drill@", "bag_intro", 1.0, 1.0, 1) -- adding the entity to the scene
NetworkAddSynchronisedSceneCamera(intro,"anim_heist@hs3f@ig9_vault_drill@drill@",'intro_cam') -- adding the cam
NetworkStartSynchronisedScene(intro) -- starting the scene
Wait(GetAnimDuration("anim_heist@hs3f@ig9_vault_drill@drill@", "intro") * 1000) -- waiting for the scene to finish
NetworkStopSynchronisedScene(intro)
DeleteObject(drill) -- You have to remove the objects or they will fall down and just look wrong
DeleteObject(bag)
end)
This is a simplified synchronized scene that demonstrates the gold collection animation used in the cayo perico heist, I could see some really cool open-source resources being created by this!
RegisterCommand("startscene", function()
local ped = PlayerPedId()
local coords = GetEntityCoords(PlayerPedId())
local rotaion = GetEntityRotation(PlayerPedId())
RequestAnimDict('anim@scripted@heist@ig1_table_grab@gold@male@')
while not HasAnimDictLoaded('anim@scripted@heist@ig1_table_grab@gold@male@') do
Citizen.Wait(1)
end
RequestModel(GetHashKey('hei_p_m_bag_var22_arm_s'))
while not HasModelLoaded(GetHashKey('hei_p_m_bag_var22_arm_s')) do
Citizen.Wait(0)
end
RequestModel(GetHashKey('h4_prop_h4_gold_stack_01a'))
while not HasModelLoaded(GetHashKey('h4_prop_h4_gold_stack_01a')) do
Citizen.Wait(0)
end
local bag = CreateObject(GetHashKey('hei_p_m_bag_var22_arm_s'),coords,true,true,true)
local gold = CreateObject(GetHashKey('h4_prop_h4_gold_stack_01a'),coords,true,true,true)
local intro = NetworkCreateSynchronisedScene(coords.xy,coords.z-.05,rotaion, 2, true, false, -1, 0, 1.0)
NetworkAddPedToSynchronisedScene(ped, intro, "anim@scripted@heist@ig1_table_grab@gold@male@", "enter", 1.5, -4.0, 1, 16, 1148846080, 0)
NetworkAddEntityToSynchronisedScene(bag, intro, "anim@scripted@heist@ig1_table_grab@gold@male@", "enter_bag", 1.0, 1.0, 1)
SetPedComponentVariation(PlayerPedId(),5, 0, 0, 0)
NetworkStartSynchronisedScene(intro)
Citizen.Wait(GetAnimDuration("anim@scripted@heist@ig1_table_grab@gold@male@", "enter")*1000)
NetworkStopSynchronisedScene(intro)
local grabscene = NetworkCreateSynchronisedScene(coords.xy,coords.z-.05,rotaion, 2, true, false, -1, 0, 1.0)
NetworkAddPedToSynchronisedScene(ped, grabscene, "anim@scripted@heist@ig1_table_grab@gold@male@", "grab", 1.5, -4.0, 1, 16, 1148846080, 0)
NetworkAddEntityToSynchronisedScene(bag, grabscene, "anim@scripted@heist@ig1_table_grab@gold@male@", "grab_bag", 1.0, 1.0, 1)
NetworkAddEntityToSynchronisedScene(gold, grabscene, "anim@scripted@heist@ig1_table_grab@gold@male@", "grab_gold", 1.0, 1.0, 1)
NetworkStartSynchronisedScene(grabscene)
Citizen.Wait(GetAnimDuration("anim@scripted@heist@ig1_table_grab@gold@male@", "grab")*1000)
NetworkStopSynchronisedScene(grabscene)
DeleteObject(gold)
local exit = NetworkCreateSynchronisedScene(coords.xy,coords.z-.05,rotaion, 2, true, false, -1, 0, 1.0)
NetworkAddPedToSynchronisedScene(ped, exit, "anim@scripted@heist@ig1_table_grab@gold@male@", "exit", 1.5, -4.0, 1, 16, 1148846080, 0)
NetworkAddEntityToSynchronisedScene(bag, exit, "anim@scripted@heist@ig1_table_grab@gold@male@", "exit_bag", 1.0, 1.0, 1)
NetworkStartSynchronisedScene(exit)
Citizen.Wait(GetAnimDuration("anim@scripted@heist@ig1_table_grab@gold@male@", "exit")*1000)
NetworkStopSynchronisedScene(exit)
DeleteObject(bag)
end)
Useful Tips and Tricks
For some animations to look right, you need exact coords. Most of these animations look like they interact with an object (for example, a keypad) even if the keypad isn’t in the synchronized scene (scripting-wise), usually, getting the coordinates of the keypad itself gives you an animation with the exact dimensions you need! So always think of that when using synchronized scenes.
The end
I hope this was helpful, this is my first time creating a tutorial, so please inform me in the comments if there’s something which is unclear, or if I have any wrong information written down.
Happy coding fellas!