Skip to main content

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).

Log GameObject

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
}

Log Scene GameObject

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.

Log Scene GameObject

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;

}

Target Field in MonoBehaviour

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.

Add or Remove as Cross-Scene