Создать экземпляр сценариев объекта через конструктор - PullRequest
0 голосов
/ 13 мая 2019

У меня есть объект Scriptable для персонажа, и у меня есть несколько методов. Как 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.

Ответы [ 2 ]

3 голосов
/ 13 мая 2019

Вы не можете создать новый экземпляр 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;
}


}
2 голосов
/ 13 мая 2019

Нет, не так. До сих пор неясно, почему вы должны использовать ScriptableObject s вместо простого класса ( мы пришли из этого вопроса ), где вы просто настроили бы эти символы, например в инспекторе или используйте, например.

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}";
}

так оно и есть, когда начинается игра.


Если вы действительно хотите, чтобы он был при наборе этих имен в Инспекторе, вы не сможете использовать Пользовательский Инспектор , реализовав 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. В обоих случаях соответствующий код отбрасывается в сборке.


enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...