我有一个可编写字符的对象,并且其中有几种方法。像GetDate,GetAge(在此未显示)。我在那里创建了一个构造函数,但是我不知道如何通过构造函数创建该ScriptableObject的实例。这就是我要做的。
我试图只在检查器中键入值,但是没有在构造函数中运行方法。
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.
}
}
我想通过此构造创建此可脚本编写对象的实例。像
Character char("x", "y", "z", true);
或者当我在Unity Inspector中键入必填字段时,它将运行诸如全名string.format
之类的所有方法。
答案 0 :(得分:3)
您不能使用构造函数来创建新的ScriptableObject实例(很像单一行为)。 所以您需要使用Unity API方法
我添加了一个工作样本
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;
}
}
这是创建角色的类
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;
}
}
答案 1 :(得分:2)
不,不是那样。尚不清楚为什么必须使用ScriptableObject
而不是使用简单的类(we came from this question)来配置这些字符,例如在检查器中或使用例如
new Character("abc", "xyz", "kfk", true);
但是您可以使用某种工厂方法,例如
[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);
}
}
或例如在
private void OnEnable()
{
fullName = $"{firstName} {middleName} {lastName}";
}
所以游戏开始时就在那里。
如果您真的想在同时中输入这些名称,则不会通过实现Custom Inspector
来使用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
或者使用#if UNITY_EDITOR
,当然也可以将CharacterEditor
放在完整的单独脚本中,然后将其放在名为Editor
的文件夹中。在这两种情况下,都会在构建中删除相应的代码。