Cross reference gameobjects between scenes

Hello

We are using multiple scene editing in our game so different devs can work on different parts. We really could do with being able to cross reference gameobjects that have certain scripts on them though and was wondering if anyone had any ideas for a solution?

Say I have a Task.cs script attached to a gameobject in “SceneA”. It has a property for another Task, let’s call it TargetTask. Now I can allow cross scene references in the editor with “preventCrossSceneReferences = false” and when I drag and drop a Task from “SceneB” onto TargetTask it’s assigned properly. What I’d like to do is somehow save this data and when the game runs properly it’s restored.

I understand why the reference doesn’t save so doing something like saving the name of the gameobject and restoring it from a name, or via a unique ID, would be fine. I’m just not sure how I go about doing that?

What complicates things a little is that I have a lot of different scripts inheriting from my base Task that will have other Task fields that need saving and I don’t want to have to write a serializeable class for every one. Is there a way to do it with a custom attribute like?

[SerializeAsString]
Task TargetTask;

Failing that, is there a way to tell when a GameObject is dropped onto the TargetTask field so I can grab the name of it and store that?

Any ideas?

Thanks!

Sounds like something you could do with ISerializationCallbackReceiver. Have Task implement it, and use the serialization callbacks to handle that.

You probably wouldn’t have a Task field, though. You’d end up with a TaskWrapper. So you’d have a public TaskWrapper, and TaskWrapper would do something like:

[Serializable]
public class TaskWrapper : ISerializationCallbackReceiver {

    private Task task;
    public string taskID;
    public string taskScene;

    public void OnBeforeSerialize() {
        if (task != null) {
            taskID = task.ID;
            taskScene = task.scene;
        }
    }

    public void OnAfterDeserialize() { }

    public Task GetTask() {
        if (task == null) {
            //recover the task from the ID/scene
        }
        return task;
    }
}

You’ll have to implement a CustomPropertyDrawer for TaskWrapper in order to handle assigning tasks by dragging and dropping. You’d have it display the data about the task, and then show an object field. When the object field’s value change, extract the task from the object field.

1 Like

That’s brilliant thanks, the ISerializationCallbackReceiver is exactly what I was looking for. Will give that a go.

Thanks again.

All working, thanks for your help. It was spot on. I can drag and drop my tasks around and cross reference between scenes and it all looks seamless.

1 Like