Using Cross-Scene Reference by Script
Before going straight into accessing a Cross-Scene Reference in C#, let's be familiar on how to draw a Target Field in a command using CommandGUI
first.
We will create a command that will print the name of the GameObject specified in the Target Field.
Create a new command script by opening the Assets menu and choose Create -> Sequine -> C# Command Script. Name the new file to LogGameObjectCommand (optional).
Creating a Target Field
To create a Target Field, let's first create a public TargetObject<T>
field that will store the reference, where T
is the type of the Object that we want to target.
To draw a Target Field in our command, we call CommandGUI.DrawTargetObjectField
method. If you've read Creating Custom Command Type, then you may have been familiar with the parameters.
A Target Field, as explained in Cross-Scene System, have 3 different ways to assign the actual Object. But no matter which way we use to assign, to get the actual Object, then we can use the GetObject
method.
...
[System.Serializable]
[RegisterCommand("Custom/Log GameObject", typeof(SequineFlowCommandData))]
public class LogGameObjectCommand : Command {
public override float nodeWidth => 300;
public TargetObject<GameObject> gameObjectToLog;
public override void Execute(CommandExecutionFlow _flow) {
if (gameObjectToLog != null) {
var value_gameObjectToLog = gameObjectToLog.GetObject();
if (value_gameObjectToLog != null) {
Debug.Log("The name is: " + value_gameObjectToLog.name);
}
}
Exit();
}
#if UNITY_EDITOR
public override void Editor_OnDrawContents(Vector2 _absPosition) {
CommandGUI.DrawTargetObjectField("GameObject to Log", ref gameObjectToLog);
}
#endif
}
By now, we should've been able to simply set a GameObject from the hierarchy to the GameObject to Log
field.
Play It
Now let's try to assign the target and play it.
Using a Target Field in MonoBehaviour / ScriptableObject
In Command, TargetObject<T>
's 3 alternative ways of targetting an object was specifically made to reduce redundancy of the available commands. Imagine if Sequine made dedicated commands for each of them, then each command type should be duplicated 3 times as different command types. That's why we wrapped it as a dropdown in a single command.
However, if we are going to target an object in a MonoBehaviour
or a ScriptableObject
, then there's no need to have such dropdown.
If we want to target a Direct Object, then we can just declare a public or serialized field like we normally do.
If we want to target with a Legacy Cross-Scene Binder, then we can also just declare a public or serialized field, but with the binder asset type as the field type. Read Using Cross-Scene Binding (Legacy) by Script
Now, if we want to target a Cross-Scene Reference, then instead of declaring an Object field, we declare a GUID field, specifically SerializableGUID
. To make it editable in the Inspector, we put [CrossSceneRef]
attribute.
We can also put a System.Type
parameter in the `CrossSceneRef`` attribute to define the type of our target object.
using UnityEngine;
using Calcatz.CookieCutter;
public class CrossSceneRefExample : MonoBehaviour {
[CrossSceneRef(typeof(MeshRenderer))]
public SerializableGUID meshRendererTarget;
}
To access the object in runtime, we can use CrossSceneRefsUtility.GetObject
method, specifying the GUID in the parameter.
...
public class CrossSceneRefExample : MonoBehaviour {
[CrossSceneRef(typeof(MeshRenderer))]
public SerializableGUID meshRendererTarget;
private void Start() {
var meshRendererObject = CrossSceneRefsUtility.GetObject(meshRendererTarget);
Debug.Log(meshRendererObject.name);
}
}
Manually Mark a Component as Cross-Scene
Cross-scene object references are contained in a dictionary.
In the background, Sequine automatically add an object as a cross-scene object when we drag and drop it.
While it's convenient to just drag and drop it, we can also manually add or remove an object from the cross-scene objects registry, by right clicking the component.