- Home /
Custom Inspector - break link between duplicate fields?
I created a custom inspector that lets me duplicate an entry in a list. I have two problems.
(1) Entry 2 points to entry 1 in memory, so if I make a change to entry 1 the change is also made to entry 2.
(2) The entry I'm duplicating is a class with lots of sub-classes. Because of this, if I use new, it needs to be in a way that doesn't require me to write out a hundred fields.
If I use the default inspector to make a change to a value in a field, the link between the two entries is severed. This is what I'm trying to achieve w/o having to make a change in the default inspector. EditorUtility.SetDirty doesn't make a difference.
Is there a way to copy entry 1, bring over all of the data in entry 1 to entry 2, and sever the link between them? I suspect I need to use New. If I do need to use new, I'm not sure how to do this without re-adding the data in each field one by one.
Here is a snippet of my code:
CharacterValues.cs: Data for the item (original has more more data)
using UnityEngine;
using System;
using System.Collections.Generic;
[Serializable]
public class CharacterValues
{
public string nameOfItem;
public int itemGUID;
public List<Actions> characterActions = new List<Actions>();
}
Character.cs (Use this to store copy of a specific item's data)
using UnityEngine;
public class Character: ScriptableObject
{
public CharacterValues CharacterInfo;
}
CharacterEditor.cs (custom inspector that displays fields for an item)
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Reflection;
[CanEditMultipleObjects]
[CustomEditor(typeof(Character))]
public class CharacterInspector : Editor
{
private Character character;
private Database database;
private List<Actions> characterActions;
// assign currently open template to inspector
void OnEnable()
{
// get the database (store copy & pasted objects)
GameObject gameObject = GameObject.Find("Databases");
database = gameObject.GetComponent<Database>();
// get template
character = (Character)target;
}
// UPDATE
public override void OnInspectorGUI()
{
// show existing inspector
base.OnInspectorGUI();
// A bunch of code is here. action = an Actions entry in a list.
// Copy
if (GUILayout.Button("Copy"))
database.copiedActionNode = action;
// Paste
if (GUILayout.Button("Paste"))
{
if (database.copiedActionNode != null)
characterActions.Insert(actionID+1, database.copiedActionNode);
}
EditorUtility.SetDirty(character);
}
Answer by Dave-Carlile · Jun 07, 2013 at 08:25 PM
You need to clone the nested objects so you have a separate copy. I believe you should be able to use Object.Instantiate to do this, but you'll need to do this for each object reference. I usually create a method that I can call that will return a clone, making sure it creates new instances of nested objects/arrays, and calls the clone method on each of those.
Another way to make a copy which may work since you're dealing with serializable objects is to serialize the object you want to clone to a memory stream, then deserialize it into a new instance. It should be possible to write a generic function to handle this.
I've tried the following snippets, but they don't work. Each action is a class full of variables. Could this be the problem?
Actions newAction = Instantiate(database.copiedActionNode);
Actions newAction =(Actions)Instantiate(database.copiedActionNode);
Actions newAction = Instantiate(database.copiedActionNode) as Action;
Action newAction = new Action();
If I test-play the game, the fields disconnect and are no longer linked. This is what I'm trying to achieve without having to play the game.
Your answer
Follow this Question
Related Questions
A node in a childnode? 1 Answer
Trying to Create Default List in Custom Inspector 1 Answer
Javascript Enum Write List 0 Answers
List Insert() returns Argument is out of range 2 Answers
I neet to make like a Hyper Procedural Dynamic List on Unity 2 Answers