Here I have a camera, and I would like to
make it follow me as I move around the world Here’s how I would go about doing so Well… before I do that, I also have this particle
emitter that I want to lock onto the player, so I can fill the world with particles, without
actually having to spawn a tonne of them This will be a little simpler,
so let’s do that one first Now, this is just a gameobject, with a
particle system with these settings applied So, we just need to write some code
to make it follow the local player With the object selected, I’m going to
go ‘create component, udon behaviour’, and now it’s time to create a script to
go inside this udon behaviour component I’m going to come down to my project window, and ‘right click, create, vrchat,
udon, udon graph program asset’, and I’m going to call it ‘Object Follower Script’ and then I’m going to open up the udon graph Now that we’re in the graph,
it’s time to write our code Now, unfortunately, we are unable
to attach our object to our player So, we instead want to update its
position to be where the player is And if we do this often enough, the object
will appear to be attached to the player So, I’m going to come over to my
graph and ‘right-click, create node’ (the shortcut for this is spacebar) and go ‘transform, SetPositionAndRotation’ Whenever this node is called, it
will set this transform’s position and rotation to be the same as the
vector3 and quaternion shown here As for the instance slot, this will default
to this gameobject, so we can leave it blank So, we just need to say where
we want it to teleport to As we want it to teleport to the local player, I’m going to go create node,
‘networking, get localplayer’ I’m then going to put the resulting player api, into a ‘playerApi, get position’ node.
And then plug that into the position slot I’m then also going to plug the playerApi
into a ‘playerApi, get rotation’ node, and plug that into the rotation slot So now, whenever this node is called,
it will grab the local player, grab its position and rotation, and set
the transform of this object to be the same Now we just need to say when
we want this node to be called I’m just go create node, ‘event update’, and plug it into the arrow slot of
the ‘set position and rotation’ node So now, once every frame, it will update
the position and rotation of the transform, to match that of the local player By the way, if we replace the
‘playerApi, get position’ node with a ‘playerApi, get tracking data’ plugged into
a ‘PlayerApiTrackingData, get position’ node, we can then also get the position of the
player’s headset, or either of their hands This node does also work for
non-humaniod avatars, and desktop players Okay, so coming back to what
we had, while this would work, there is an optimization that we should do When we play this ‘networking,
get localplayer’ node, we are essentially going to the networking
script, and asking what the local player is And we are doing this once every frame Instead, we really should ask what the
local player is when the game starts, and then store that value, so we don’t have
to keep asking who the local player is, as the local player will never change So, to do that, I’m going to
come up to my variables tab and create a VRCPlayerApi, and
I’m going to call it localPlayer I’m then going to drag and drop it into our scene
while holding ctrl, to get a node that will set it I’m then going to plug our ‘networking,
get local player’ node into it So, we just need to say when we want
this node to play, so I’m going to go create node ‘event start’, and
plug it into the arrow slot. So now when we load into the world, it
will set our variable to be the localPlayer Now that we have the local player,
we can replace our ‘networking, get local player’ node, with our new variable Awesome! So now if we hit compile and
come back into our scene view We want to select our gameObject,
and drag and drop our udon script, into the udon behaviour component slot And now if we were to test this… We can see that as the player moves
around, so to does the particle emitter Awesome! Okay, now this works all well and
good for our particle emitter, but if we were to apply this script to our camera, we can see that it gets locked to our
feet, instead of floating in front of us This is because the script changes
the location of the object to line up with the players origin point,
which is position at the player’s feet So, we just need a way to create an offset Now, I debated about showing how to code this
in with using a vector3 and multiplying it with the rotation of the player, but
by far the easiest way to do this, is to make the camera a child of an
empty gameObject with this script on it Then you can offset the camera,
and it should keep that offset So, I’m just going to come up into my
hierarchy and create an empty gameObject I’m going to call it ‘player follower’,
and I’m gonna add our udon script to it Then, I just want to drag and drop my camera on it,
to make it a child of it I’m then going to reset its position
and rotation, and give it a rough offset And now if I were to play test this… Now that the game is running, we can fine
tune its location to be where we want it to be Once your happy with where the object is, you can just going hit this
dropdown menu and go copy component Then I’m going to stop playing... And now that we have stop playing, we will
see the values reset to what they were, but we can now use the dropdown menu and go 'paste
component values', to get what we had before And now when we playtest this again… We should see the camera having
the offset that we just made Awesome! Okay, so we now have our camera offset from
the player, but this is all happening locally What if we wanted this to work globally? So that the camera followed a
particular player in the scene Well, if we were to open up the udon graph… The way we have set up this script, is that the camera will follow whatever playerApi
the variable ‘local player’ is set to If we were to change its name to something more
appropriate like ‘target player’, we can see that we just need to change the target player, to
change what player’s position it is referencing Now, you could select what player you want
it to follow a number of different ways, but for this tutorial, the simplest method
is just to use the owner of this object So, if I were to replace the
‘networking, get localPlayer’ node with a ‘networking, get owner’ node, now the
object will follow the owner of the object, instead of the local player However, currently it only checking what
player is the owner, when the game starts If the owner of the object
changed it wouldn’t update, and if the owner left it would crash the script So, I also want to go create node
‘event, onOwnershipTransferred’, and plug that into the arrow slot So now whenever the owner changes, it will
update the target player to the new owner Awesome! Also, as a side note, as we don’t currently
have any ways for the owner to change, this will just default to the instance owner Now with that setup, it’s time to test this I’m just going to hit compile and build and test
with 3 instances, to test out the networking Now that we’re in the world, we can see that the
object follows the instance owner for all players If I were to close the instance
with the current owner, we can see that it changes the target
player to the new owner of the object So, hopefully you found this helpful. Feel free to leave a like on
the video is you liked it, leave a comment down below
if you have any questions, and feel free to check out some of my
other tutorials that I have on the channel. But until next time... BYE!