I have a Character Scriptable Object and I have several methods in it. Like GetDate,GetAge (which I am not showing here). I have created a Constructor there, but I don't know how to create an instance of that ScriptableObject through the Constructor. That's what I want to do.
I have tried to just type the values in the inspector but that did not run the methods in the Constructor.
Character.cs
[CreateAssetMenu]
[Serializable]
public class Character : Scriptable Object
{
// Attributes
public string firstName;
public string middleName;
public string lastName;
public string fullName;
public bool isMale;
// Constructor
public Character(string _firstName, string _middleName, string _lastName, bool _isMale)
{
firstName = _firstName;
middleName = _middleName;
lastName = _lastName;
// All The Functions
fullName = string.Format("{0} {1} {2}", firstName, middleName,
lastName);
isMale = _isMale;
// and all the other functions like date calculator.
}
}
I want to create an instance of this Scriptable Object through this Construction. Something like
Character char("x", "y", "z", true);
or when I type the required fields in the Unity Inspector, then it will run all the methods like that full name string.format.
No, not like that. It is still unclear why you have to use ScriptableObjects
instead of having a simple class (we came from this question) where you would simply configure those Characters e.g. in the Inspector or use eg.
new Character("abc", "xyz", "kfk", true);
You could however have some kind of factory method like e.g.
[CreateAssetMenu]
[Serializable]
public class Character : Scriptable Object
{
// Attributes
public string firstName;
public string middleName;
public string lastName;
public string fullName;
public bool isMale;
// Constructor
private void Init(string _firstName, string _middleName, string _lastName, bool _isMale)
{
firstName = _firstName;
middleName = _middleName;
lastName = _lastName;
// All The Functions
fullName = string.Format("{0} {1} {2}", firstName, middleName, lastName);
isMale = _isMale;
// and all the other functions like date calculator.
}
public static Character CreateCharacter(string firstName, string middleName, string lastName, bool isMale)
{
var character = ScriptableObject.CreateInstance<Character>();
character.Init(firstName, middleName, lastName, isMale);
return character;
}
}
or alternatively do it e.g. in
private void OnEnable()
{
fullName = $"{firstName} {middleName} {lastName}";
}
so it is there when the game starts.
If you really want to have it while typing those names in the Inspector you won't come around using a Custom Inspector by implementing Editor
#if UNITY_EDITOR
using UnityEditor;
#endif
public class Character : Scriptable Object
{
...
}
#if UNITY_EDITOR
[CustomEditor(typeof(Character))]
public class CharacterEditor : Editor
{
private SerializedProperty firstName;
private SerializedProperty middleName;
private SerializedProperty lastName;
private SerializedProperty fullName;
// called once when the Object of this type gains focus and is shown in the Inspector
private void OnEnable()
{
firstName = serializedObject.FindProperty("firstName");
middleName= serializedObject.FindProperty("middleName");
lastName= serializedObject.FindProperty("lastName");
fullName= serializedObject.FindProperty("fullName");
}
// kind of like the Update method of the Inspector
public override void OnInspectorGUI()
{
// draw the default inspector
base.OnInspectorGUI();
serializedObject.Update();
fullName.stringValue = $"{firstName.stringValue} {middleName.stringValue} {lastName.stringValue}";
serializedObject.ApplyModifiedProperties();
}
}
#endif
alternatively to using #if UNITY_EDITOR you can ofcourse have the CharacterEditor in a complete separate script and put that one in a folder named Editor. In both cases the according code is stripped of in a build.

You can't create a new ScriptableObject Instance using a constructor (much like a monobehaviour). so you need to use Unity API methods
I have added a working sample
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
[CreateAssetMenu]
[Serializable]
public class Character : ScriptableObject
{
// Attributes
public string firstName;
public string middleName;
public string lastName;
public string fullName;
public bool isMale;
// Constructor
public Character(string _firstName, string _middleName, string _lastName, bool _isMale)
{
firstName = _firstName;
middleName = _middleName;
lastName = _lastName;
// All The Functions
fullName = string.Format("{0} {1} {2}", firstName, middleName,
lastName);
isMale = _isMale;
// and all the other functions like date calculator.
}
public void Initialize(string _firstName, string _middleName, string _lastName, bool _isMale)
{
firstName = _firstName;
middleName = _middleName;
lastName = _lastName;
// All The Functions
fullName = string.Format("{0} {1} {2}", firstName, middleName,
lastName);
isMale = _isMale;
}
}
and here is the class that creates the Character
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class Tester : MonoBehaviour
{
int characterCounter = 0;
// Update is called once per frame
void Update()
{
if(Input.GetMouseButtonDown(0))
{
Character c = CreateMyAsset();
c.Initialize("a", "b", "c", true);
}
}
public Character CreateMyAsset()
{
Character asset = ScriptableObject.CreateInstance<Character>();
string assetName = "Assets/c" + characterCounter + ".asset";
characterCounter++;
AssetDatabase.CreateAsset(asset, assetName);
AssetDatabase.SaveAssets();
EditorUtility.FocusProjectWindow();
Selection.activeObject = asset;
return asset;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With