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 /
This question was closed Jul 04, 2016 at 08:13 AM by Fire_Cube for the following reason:

The question is answered, right answer was accepted

avatar image
0
Question by Fire_Cube · Jul 03, 2016 at 10:29 AM · scripting problembugscriptableobjectassetdatabasetype

ScriptableObject.CreateInstance(Type T) keep crashing

Hey, I stuck with this for a good moment now, somewhere in my code, I have this :

 if (!_instance.ContainsKey(T) || _instance[T] == null)
         {
 #if UNITY_EDITOR
             _instance[T] = (DataHolder)ScriptableObject.CreateInstance(T);
             Debug.Log(T.Name);
             return null;
             /*if (!Directory.Exists(Application.dataPath + "/DataHolders"))
                 Directory.CreateDirectory(Application.dataPath + "/DataHolders");*/
             AssetDatabase.CreateAsset(_instance[T], "Assets/DataHolders/" + _instance[T].pathToBase + ".asset");
             AssetDatabase.SaveAssets();
 #else
             t = LoadLast(T);
 #endif
         }

But it crash everytime on the ScriptableObject.CreateInstance(T). T is a class extending DataHolder. _instance is a Dictionary pathToBase is a simple string.

I've already use this code with another class, and it worked, so i don't understand. I used the debug class around those lines to see where it stuck, all work until this, and i don't get why.

Any help would be very pleasant.

thanks, FireCube

EDIT : there's the DataHolder class :

 //Code written by Etienne Desrousseaux, alias FireCube, for the updater package.
 //
 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 using System;
 using System.IO;
 using Crypting;
 #if UNITY_EDITOR
 using UnityEditor;
 #endif
 
 public class DataHolder : ScriptableObject
 {
     public static List<DataHolder> dataBases = new List<DataHolder>();
 
     public const string pathToBases = "Data";
 
     public string pathToBase
     {
         get
         {
             return GetType().ToString();
         }
     }
 
     public static Dictionary<Type, DataHolder> _instance = new Dictionary<Type, DataHolder>();
 
     public static T getInstance<T>() where T : DataHolder
     {
         T t = null;
         if (_instance.ContainsKey(typeof(T)))
             t = (T)_instance[typeof(T)];
         if (t == null)
         {
 #if UNITY_EDITOR
             t = CreateInstance<T>();
 
             AssetDatabase.CreateAsset(t, "Assets/DataHolders/" + t.pathToBase + ".asset");
             AssetDatabase.SaveAssets();
 #else
             t = LoadLast(typeof(T));
 #endif
         }
         _instance[typeof(T)] = t;
         return t;
     }
 
     public static DataHolder GetInstance(Type T)
     {
         if (!_instance.ContainsKey(T) || _instance[T] == null)
         {
 #if UNITY_EDITOR
             _instance[T] = (DataHolder)ScriptableObject.CreateInstance(T);
             Debug.Log(T.Name);
             return null;
             /*if (!Directory.Exists(Application.dataPath + "/DataHolders"))
                 Directory.CreateDirectory(Application.dataPath + "/DataHolders");*/
             AssetDatabase.CreateAsset(_instance[T], "Assets/DataHolders/" + _instance[T].pathToBase + ".asset");
             AssetDatabase.SaveAssets();
 #else
             t = LoadLast(T);
 #endif
         }
         return _instance[T];
     }
 
 #if UNITY_EDITOR
     public void open()
     {
         Selection.activeObject = this;
     }
 #endif
     /// <summary>
     /// Load the last data holder of this type that have already been downloaded
     /// </summary>
     /// <param name="T">the type, must extend DataHolder class</param>
     /// <returns>the data holder loaded from last </returns>
     public static DataHolder LoadLast(Type T)
     {
         DataHolder dh = null;
 
         string path = Application.dataPath + "/" + pathToBases + "/" + ((DataHolder)CreateInstance(T)).pathToBase;
 
         if (File.Exists(path))
         {
             AssetBundle ab = AssetBundle.LoadFromMemory(
                 File.ReadAllBytes(path)
                     .Decrypt(
                     SimpleConfig.getLine("pass", "UpdaterData")));
             dh = (DataHolder)ab.LoadAsset(T.Name, T);
         }
 
         return dh;
     }
 
     /// <summary>
     /// Download and save to disk a data holder, debug parameter exist for UNITY_EDITOR only
     /// </summary>
     /// <param name="T">the type for which we want to download the base</param>
     /// <param name="onDone">the function to be executed when the download is finished</param>
     /// <param name="onError">the function to be executed if an error happen durring the download, the saving to disk or when loading the base</param>
     /// <param name="onUpdate">the function to be executed every <paramref name="updateRate"/>, sending the progress</param>
     /// <param name="updateRate">the rate at which <paramref name="onUpdate"/> is called</param>
     public static IEnumerable DownloadDataHolder(Type T, Action<DataHolder> onDone = null, Action<string> onError = null, Action<float> onUpdate = null, float updateRate = 0.05f
 #if UNITY_EDITOR
         , bool debug = false//reduce size on build
 #endif
         )
     {
         bool update = onUpdate != null;
 
         string url = SimpleConfig.getLine("website", "UpdaterData") + "/" + T.Name + ".dat";
         WWW www = new WWW(url);
 #if UNITY_EDITOR
         if (debug)
             Debug.Log("Start downloading " + url + "\nCorresponding Data Holder is " + T.FullName);
 #endif
         if (update)
         {
             while (!www.isDone)
             {
                 yield return new WaitForSeconds(updateRate);
                 Action<float> temp = onUpdate;
                 if (temp != null)
                 {
                     temp(www.progress / 3);
                 }
             }
         }
         else
             yield return www;
 
         if (!string.IsNullOrEmpty(www.error))
         {
             Debug.LogError("Error while downloading data holder : " + www.error + "\ncalling error function");
             Action<string> temp = onError;
             if (temp != null)
                 temp("Error while downloading data holder : " + www.error);
         }
         else
         {
 #if UNITY_EDITOR
             if (debug)
                 Debug.Log("Done downloading " + url + "\n" + www.bytesDownloaded + " bytes downloaded");
 #endif
             byte[] data = www.bytes;
 
             www.Dispose();
 
             byte[] decrypted = data.Decrypt(
                 SimpleConfig.getLine("pass", "UpdaterData"));
 
             string path = Application.dataPath + "/" + pathToBases + "/" + ((DataHolder)CreateInstance(T)).pathToBase;
             bool error = false;
             try
             {
                 File.WriteAllBytes(path, data);
             }
             catch
             {
                 Debug.LogError("Error while writting base to file, calling error function");
                 error = true;
                 Action<string> temp = onError;
                 if (temp != null)
                     temp("Error while writting base to file");
             }
             if (!error)
             {
 #if UNITY_EDITOR
                 if (debug)
                     Debug.Log("Done saving " + T.FullName + " to " + path);
 #endif
 
                 var bundle = AssetBundle.LoadFromMemoryAsync(decrypted);
 
                 if (update)
                 {
                     while (!bundle.isDone)
                     {
                         yield return new WaitForSeconds(updateRate);
                         Action<float> temp = onUpdate;
                         if (temp != null)
                         {
                             temp((bundle.progress + 1) / 3);
                         }
                     }
                 }
                 else
                     yield return bundle;
 
                 var dh = bundle.assetBundle.LoadAssetAsync(T.Name, T);
 
                 if (update)
                 {
                     while (!dh.isDone)
                     {
                         yield return new WaitForSeconds(updateRate);
                         Action<float> temp = onUpdate;
                         if (temp != null)
                         {
                             temp((dh.progress + 2) / 3);
                         }
                     }
                 }
                 else
                     yield return dh;
 
                 Action<DataHolder> temp2 = onDone;
                 if (temp2 != null)
                 {
                     temp2((DataHolder)dh.asset);
                 }
 #if UNITY_EDITOR
                 if (debug)
                     Debug.Log("Done with data holder " + T.FullName);
 #endif
             }
         }
 
     }
 }
 

and the class that call everything is there :

 //Code written by Etienne Desrousseaux, alias FireCube, for the updater package.
 //
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Reflection;
 using System.Text.RegularExpressions;
 using UnityEditor;
 using UnityEngine;
 
 public class DataHolderWindow : EditorWindow
 {
     List<Type> types;
     
     void OnGUI()
     {
         if (types == null)
             types = new List<Type>(FindDerivedTypes(typeof(DataHolder).Assembly, typeof(DataHolder)));
         foreach (var T in types)
         {
             if (GUILayout.Button(Regex.Replace(T.ToString(), "([A-Z])", " $0")))
             {
                 open(T);
             }
         }
     }
     void open(Type T)
     {
         MethodInfo m = T.BaseType.GetMethod("GetInstance");
         object j = m.Invoke(null, new object[] { T });
         //T.GetMethod("open").Invoke(j, null);
     }
 
     public IEnumerable<Type> FindDerivedTypes(Assembly assembly, Type baseType)
     {
         return assembly.GetTypes().Where(t => t != baseType &&
                                               baseType.IsAssignableFrom(t));
     }
 
     [MenuItem("Updater/Data Holder List")]
     static void Init()
     {
         DataHolderWindow window = GetWindow<DataHolderWindow>();
         window.titleContent.text = "Data Bases List";
         window.Show();
     }
 }

The Debug are still in there

Thx

NEW EDIT :

I found the problem, but first, here's my Demo class, that is the one that should open and create :

 //Auto generated resource data holder the 7/3/2016
 //Using the Updater package
 using UnityEngine;
 
 public class Demo : DataHolder
 {
 
     #region fields
     public static new string name
     {
         get { return instance._name; }
         set { instance._name = value; }
     }
     public string _name;
 
     public static GameObject prefab
     {
         get { return instance._prefab; }
         set { instance._prefab = value; }
     }
     public GameObject _prefab;
 
     public static float speed
     {
         get { return instance._speed; }
         set { instance._speed = value; }
     }
     public float _speed;
 
 
     #endregion
 
     public static Demo instance
     {
         get { return getInstance<Demo>(); }
     }
 
     [InspectorCallable]
     public void Reset()
     {
         name = "";
         prefab = null;
         speed = 5f;
     }
 }

The problem is, indeed, the function Reset. Unity freeze when it's not commented, but all is good if it is commented, and i can't explain myself why...

Comment
Add comment
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

2 Replies

  • Sort: 
avatar image
0
Best Answer

Answer by Bunny83 · Jul 03, 2016 at 11:11 AM

There are a few things that are required for CreateInstance to work are:

  • Your base class (DataHolder) has to be derived from ScriptableObject

  • Your actual concrete class has to be placed in a file that matches the classname.

both of those points are missing in your question, so we can't really tell what you did wrong.

If everything is right then there must be something wrong inside your concrete class. However your class is missing as well so again we can't help you.

Comment
Add comment · Show 2 · 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 Bunny83 · Jul 03, 2016 at 11:18 AM 0
Share

ps: You should be more concrete what kind of "crash" you experienced. Does the editor just freeze, do you receive a crash report or does it just close without any message?

If the editor freezes there could be an infinite loop somewhere inside your class.

avatar image Fire_Cube · Jul 03, 2016 at 12:02 PM 0
Share

ok, sorry if I wasn't precise enough, the DataHolder class is derived directly from scriptable object (only), and the crash type is just a freeze, with no more responses from the program. The file name is DataHolder.cs, and the class is DataHolder

I add the whole code now

avatar image
0

Answer by Fire_Cube · Jul 04, 2016 at 08:13 AM

Ok, look's like I was just unlucky, this only happen with Reset, or probably some special functions...

Comment
Add comment · 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

Follow this Question

Answers Answers and Comments

57 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 avatar image

Related Questions

Why unity can't create/save asset (ScriptableObject ) at runtime ? 1 Answer

Instantiate ScriptableObject with a random asset from List 1 Answer

How can I create, via script, a hidden subasset (ScriptableObject) that is editor-only and invisible in Project view? 1 Answer

How to create custom asset icons for ScriptableObject instances 2 Answers

AnimationCurve not saved correctly in custom ScriptableObject 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