This guide covers a lot of ground, so don't feel discouraged if it's too much. You're free to ask for help over in the Bonelab Discord Server, or try out some other guides first while you get your footing. Best of luck!
This guide will cover 3 very useful methods you can use in your logic:
System.Type.GetType
UnityEngine.Object.FindObjectOfType
- used to filter for specific components.SLZ.Marrow.Utilities.ObjectPathExtensions
- used to generate a path in the hierarchy, which is covered specifically in the ObjectPathExtensions guide.
About FindObjectOfType
Unity provides us with a method called FindObjectOfType
that we can use to search for specific components. In this guide, weâll use it to locate the PlayerMarker
as an example!
Thatâs this fella if you were wondering - it marks the playerâs spawn point.
Getting the Type
Start by making a new UltEventHolder
, searching System.Type
into the static method type picker and clicking on the GetType
override that takes 3 arguments:
I ticked throwOnError
so that we get an error in the console if it doesnât work, and also ticked ignoreCase
because case sensitivity is irrelevant.
Now find out what the name of the type we need is. If you have ExtendedSDK installed into your project, we can snatch it from the dummy script. Switch the search to In Packages along the top of your project window, and search PlayerMarker
:
Note
Not all ExtendedSDK scripts will be underneath your projectâs package cache. If you canât find the script, try switching the search filter to âIn Assetsâ or âAll.â
Great! Click the PlayerMarker script and have a look at it in the inspector.
Start by taking the namespace and class name from the code. Look for namespace
in the code and copy the text afterwards. Then look for public class
and steal the class name that follows, leaving out anything after the colon.
Also make note of the assembly - weâll need this in a moment.
Great! Putting the namespace in-front of the class name will give us the full name of your class, which is what we will need in a minute. Combine like so:
Still can't find the class you need?
It may be an engine type, which means it wonât be part of your project.
In this case, classes, namespaces and assemblies can be found on the Unity scripting reference.
Opening a page for any of the class we can find all the info we need.
If we feed the classes full name into the typeName
field, and invoke the UltEventHolder
, weâll get an error:
Right now, this function is trying to look for SLZ.Marrow.SceneStreaming.PlayerMarker
underneath UltEvents. To fix this, we need to also give it the correct assembly name from earlier.
Simply add a comma and type the assembly name, like so:
SLZ.Marrow.SceneStreaming.PlayerMarker, SLZ.Marrow
Now invoke the UltEventHolder and youâll see that no errors appear in the console. Sweet!
Using FindObjectOfType
Now that we have the type, we can filter through the scene for an object that matches it.
Add a new action with UnityEngine.Object.FindObjectOfType
. We can use our return value from the previous step, and just like that, itâll find the first component in the scene (in this case our PlayerMarker
!)
Add a GameObject
with your component on it into the scene so that we can test it in editor. I went ahead and inserted a PlayerMarker
into mine.
If we use Debug.Log
to output to the console and invoke our UltEvent
now, you should see that it successfully found the PlayerMarker
in the scene!
Going from Transform to Component
We can use ObjectPathExtensions.ObjectPath to get the Transform
that belongs to our component, and then use Transform.SetParent
to parent underneath the player marker.
In this case we have a component, so make sure you select the overload that takes in a Component!
Feed the return value from FindObjectOfType
into ObjectPath
. Since thereâs no way to cast Object
to Component
in UltEvents, youâll need the to use the Debug menu to do this.
See Using GetComponent with methods that don't take a generic Component (THE RED) for info on exploiting the debug menu for this purpose!
This is perfect! Now that we have an exact path to the player marker, we can feed it into Transform.Find
to convert our path into a Transform, then parent underneath it to get the location of the Player Marker.
As described in the ObjectPathExtensions guide, we will use string.Format
to add a /
to the start of the path. Thisâll tell Transform.Find
to look underneath the root of the scene, and is very important!
The following example will show the final logic being used to locate a player marker in the scene, parent something underneath it, and then re-center:
In summary:
- Use
GetType
to Retrieve thePlayerMarker
type. - Use the type to find the first
PlayerMarker
component in the scene. - Use ObjectPath to get the path of the
PlayerMarker
(example return value:Gameplay/Player Marker
). - Use
string.Format
to add a/
to the start of our path. - Use
Transform.Find
to get ourTransform
from its path. Adding a/
to the front means that weâll search under the root of the scene, instead of underneath the Transform we provide! - Use
SetParent
to re-parent underneath the Player Marker. - Use
SetLocalPositionAndRotation
to re-center in the middle of the Player Marker.