Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by MattSawrey · Aug 23, 2016 at 07:56 PM · serializationscriptableobjectreferences

How to store references between scriptableobject assets

I have a scriptableobject. I would like it to be able to contain a reference to another scriptableobject within it, and for this reference to be stored throughout development. Currently, the reference is being stored during an editor session, but as soon as I close and re-open unity, the reference has disappeared.

Is it not possible to serialise references to other scriptableobjects? And if it is not, is there a way that I can go about achieving the desired connection?

Here's the basic outline of the code:

 [System.Serializable]
 public class DialogueElement : ScriptableObject
 {
 [Serializefield]
 public DialogueElement outputDialogue;
 }
Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image bloeys · Aug 24, 2016 at 03:37 AM 1
Share

Hi,

By default a ScriptableObject should have no problem referencing other ScriptableObjects, so it must be something else. It could be that some of your code is doing something which is breaking those references in someway. Another possibility is that you are not saving properly.

Ideally when dealing with assets and editor stuff in general, you want to call something like EditorUtility.SetDirty when you make a change, which will make sure that unity recognizes the changes made. Now I have tried to replicate what you are facing but could not reproduce what is happening, so for now just make sure you are referencing a SO and are saving correctly, otherwise we would need a bit more code to see where things could break.

Edit: do note that in 5.3 and above, EditorUtility.SetDirty should not be used.

avatar image MattSawrey bloeys · Aug 24, 2016 at 01:49 PM 0
Share

hmm. So when I set the reference in the inspector, there's no issue. The problem occurs when I set the reference in my custom editor that I've built around these assets. It must be something to do with how I'm setting the reference.

Thanks for the response.

avatar image Glurth MattSawrey · Aug 24, 2016 at 03:04 PM 0
Share

I agree with this conclusion.

3 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by bloeys · Aug 24, 2016 at 04:05 PM

Yes I agree with @Glurth, The private static list is probably the problem, but I can't confirm yet since I'm having errors of missing files with the files you provided. For now try making that one public and see what you get.

Edit: Okay so I was finally able to reproduce what was happening. Now for some reason using serialized objects and applying modified and updating doesn't work, but something else worked. Setting the individual dialogues dirty seems to work. You can loop over your dialogues each OnGUI(not really optimal) and make them dirty, or (best option) is wherever you draw the windows in your code, after each dialogue is drawn check if something on it was changed, if so make it dirty.

Another possiblity (which is also a good solution) is whenever you close the window/change scenes just loop over all the dialogues and make them dirty. This should hopefully fix your problems :)

Comment
Add comment · Show 5 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image MattSawrey · Aug 24, 2016 at 04:16 PM 0
Share

Oh, this enum is definitely missing, sorry:

public enum NodeWindowSizes { Small, $$anonymous$$edium, Large }

Thanks for trying.

avatar image bloeys MattSawrey · Aug 24, 2016 at 04:19 PM 0
Share

Not at all, though this is not just what is missing, I'm getting errors about these as well(there might be others as well): Dialogue$$anonymous$$ood and DialogueType

avatar image MattSawrey bloeys · Aug 24, 2016 at 04:20 PM 0
Share

Oh, ha. I do love my enums:

public enum Dialogue$$anonymous$$ood { Happy, Sad, Normal, Shocked }

public enum DialogueType { StoryDriver, GeneralChat, Emotive }

avatar image MattSawrey · Aug 24, 2016 at 09:31 PM 0
Share

You're a hero. SetDirty does the job. I've tried so many things, but it turns out it was that simple. You have my thanks!

avatar image bloeys MattSawrey · Aug 24, 2016 at 09:33 PM 0
Share

You are welcome :) glad that worked! Just please mark this as the answer. All the best!

avatar image
0

Answer by MattSawrey · Aug 24, 2016 at 03:49 PM

So, in the Unity inspector, when I create the reference between two instances of this ScriptableObject by dragging and dropping, how is that reference created? Is there some sort of ID created in the background of Unity for each ScriptableObject?

I ask because this because of my current link of thinking:

In my custom dialogue editor window, the DialogueElements are stored in a list:

     private static List<DialogueElement> dialogues = new List<DialogueElement>();

Here's a method in that editor for creating a new instance of the DialogueElement (Ignore the random number bit, it's just to create a unique file name for now):

     private static void CreateDialogue()
     {
         DialogueElement dialogueElement = DialogueElement.CreateInstance(new Rect(correctedMousePos.x, correctedMousePos.y, DialogueElement.minWidth, DialogueElement.minHeight));
 
         //TODO - Come up with a naming convention
         var randNum = Random.Range(0f, 100f);
         string saveFilePath = dialogueAssetPath + sceneNameText + "/" + randNum + ".asset";
 
         AssetDatabase.CreateAsset(dialogueElement, saveFilePath);
         AssetDatabase.SaveAssets();
 
         DialogueElement newAsset = AssetDatabase.LoadAssetAtPath<DialogueElement>(saveFilePath);
         dialogues.Add(newAsset);
         EditorUtility.SetDirty(window);
     }

And then I have a button to call the following method to save the dialogues when I've made changes:

     private void SaveSceneDialogues()
     {
         UpdateSceneName();
 
         for (int i = 0; i < dialogues.Count; i++)
         {
             if (dialogues[i] != null)
             {
                 //Create an asset from the current dialogue
                 if (!AssetDatabase.Contains(dialogues[i]))
                     AssetDatabase.CreateAsset(dialogues[i], dialogueAssetPath + sceneNameText + "/" + dialogues[i].windowTitle + ".asset");
                 else
                     AssetDatabase.RenameAsset(dialogueAssetPath + sceneNameText + "/" + dialogues[i].windowTitle + ".asset",
                        dialogues[i].windowTitle);
             }
         }
 
         AssetDatabase.SaveAssets();
         EditorUtility.SetDirty(window);
     }

The connections are created with this method that is in the DialogueElement class when an certain event is called from the custom editor window:

 public void SetOutputDialogue(DialogueElement outputDialogue, Vector2 clickPos)
         {
             if (outputDialogue.windowRect.Contains(clickPos))
             {
                     this.outputDialogue = outputDialogue;
             }
         }
 

My current thinking is that these references might not be being serialized between Unity sessions because the links are created between the DialogueElements that are in the dialogues list, and not between the actual asset files that are created, even though the links do appear in the asset files that are created, they just disappear between Unity sessions.

That might be nonsense though, but I'm struggling to find information on this.

I'm including the two classes so that anyone awesome enough to help out can try the editor and see it for themselves. If you include the two scripts in a project, you should be able to recreate the issue, providing that you create the following filepath:

Assets/Resources/Dialoguelink text

Thanks in advance for any help!

Matt


files.zip (5.8 kB)
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Glurth · Aug 24, 2016 at 03:55 PM 0
Share

$$anonymous$$ay I suggest you append this to your question as an edit, rather than as an answer?

avatar image
0

Answer by Glurth · Aug 24, 2016 at 04:02 PM

In my custom dialogue editor window, the DialogueElements are stored in a list:

   private static List dialogues = new List();

Ah, I think we were assuming this data was in a monobehvior object somewhere, and thus automatically serialized to disk. A private Editor class member is NOT going to be saved to disk.

For this situation, you may want to take a look at: https://docs.unity3d.com/ScriptReference/AssetDatabase.GUIDToAssetPath.html and https://docs.unity3d.com/ScriptReference/AssetDatabase.AssetPathToGUID.html

These are useful for manually loading and saving particular assets. You'll still need to store the list of GUID's somewhere, I would think. I'm not quite clear on whats going on with the array initialization in your code, so cannot be more specific in my suggestion.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image MattSawrey · Aug 24, 2016 at 04:17 PM 0
Share

Okay, thanks. I'll look into this and let you know how I get on.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

56 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

[Solved]How to serialize Dictionary with Unity Serialization System 6 Answers

Difference between assigning a value in inspector and with a custom editor script 1 Answer

Referencing a ScriptableObject asset programatically 0 Answers

ScriptableObject asset loses reference after restarting Unity 1 Answer

Serializing ScriptableObject into scene without writing to asset 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges