Erstellen Sie ScriptableObject in Python, wenn Sie ADX2 erstellen

Einführung

In Unity sowohl im Editor als auch zur Laufzeit Ich wollte auf verschiedene Informationen zu ADX2 zugreifen.

Dieser Artikel ist wahrscheinlich etwas schwieriger (fehlende Erklärung).

Wenn es nur der Name der Warteschlange ist, der vorherige Artikel Einführung nützlicher Skripte wie das Kopieren in Unity beim Erstellen von ADX2 Bitte auch.

der Begriff

Über ScriptableObject

kan_kikuchis Seite Was ist ein skriptfähiges Objekt? [Einheit] [skriptfähiges Objekt]

ADX2 Sound Middleware ADX2LE kann kostenlos verwendet werden (Bedingungen gelten)

ptyhon Hier

Informationen für wen?

・ Personen, die Code schreiben möchten, der ScriptableObject generiert ・ Leute, die die XML-Ausgabe von ADX2 irgendwie nutzen wollen ・ Personen, die XML mit Python analysieren und C # -Code generieren möchten

Warum hast du es geschafft?

Erhalten Sie Informationen, die mit der ADX2-Standardmethode etwas schwierig abzurufen sind

Es gibt Informationen, die von der Acb-Funktion zum Zeitpunkt der Ausführung und über die zum Zeitpunkt der Erstellung ausgegebene cs-Datei abgerufen werden können. Ich wollte nur die notwendigen Informationen an einem Ort verwalten.

Informationen, die nicht direkt abgerufen werden können

Ich wollte Informationen extrahieren, die für etwas verwendet werden könnten.

("Etwas" hier kann ein internes Tool sein.)

Was kann ich tun?

Nach dem Erstellen mit ADX2 Bei Ausführung über das Menü in Unity

image.png

Generieren Sie eine .assets-Datei, die so aussieht. Es wird so viele wie die Anzahl der Cue-Sheets gemacht.

Einfach aus dem Programm zu bedienen

Wenn Sie auf dieses generierte ScriptableObject aus dem Unity-Objekt verweisen, können Sie die ACB-Informationen von ADX2 in jeder Situation verarbeiten. Da es zur Erstellungszeit automatisch aktualisiert wird (Menübedienung ist erforderlich *), können Fehler bei der Informationsübertragung reduziert werden.

("Jede Szene" bezieht sich hier auf den Zeitpunkt der Ausführung, des Editors, des Builds usw.)

Verwendung von Kommentaren

Außerdem können Kommentare und andere "Kommentare" zu jeder Warteschlange für diejenigen hinzugefügt werden, die nur Unity berühren. Sie können es in der Editor-Erweiterung sehen, daher scheint es gut, verschiedene Kommentare zu verwenden

Zum Beispiel "Temporäre Daten" oder "Aktualisierungsdatum" (ADX2-> Einseitiger Kommentar zu Unity, daher nicht bidirektional ...)

Analysiere XML mit Python

Verwenden Sie Python, um XML zu analysieren. Wählen Sie die erforderlichen Informationen mit Python und Generieren Sie den Code, der das ScriptableObject erstellt.

Über AISAC

Ich möchte den Namen des AISAC-Steuerelements kennen, aber wenn ich mich auf das globale AISAC beziehe, wird es nicht in XML ausgegeben Als Namenskonvention Name @ Kontrollname Angenommen

image.png

ADX2-Build-Einstellungen in AtomCraft

--Überprüfen Sie die XML-Ausgabe "acb_info"

Aufruf von Python im Postprozess (Die Dateinamen unterscheiden sich hier geringfügig, werden jedoch auf dieselbe Weise aufgerufen.)

image.png

ScriptableObject-Klasse

Wenn Sie die erforderlichen Informationen hinzufügen, sollte es zweckmäßig sein, die Informationen aus XML in Unity zu verwenden.

 ADXAcbData.cs


using System;
using System.Collections.Generic;
using UnityEngine;

namespace MyDearest {
	[CreateAssetMenu (menuName = "Sound/ADX Acb Data")]
	public class ADXAcbData
		: ScriptableObject
	{
		[Serializable]
		public class CueData {
			public string Name = "";
			public List<string> BlockNames = new List<string> ();
			public List<string> AisacNames = new List<string> ();
			public string Comment = "";
			public string UserData = "";
		}
		public string Name = "";
		public List<CueData> Cues = new List<CueData> ();

		private List<string> _cueNames = new List<string> ();
		/// <summary>
		///Gibt eine Liste der Warteschlangennamen zurück
		/// </summary>
		/// <returns></returns>
		public string[] CueNames () {
			if (_cueNames.Count > 0) return _cueNames.ToArray ();
			foreach (CueData cuedata in Cues) {
				_cueNames.Add (cuedata.Name);
			}
			return _cueNames.ToArray ();
		}
	}
}

Code, der ein ScriptableObject erstellt

Da es um die Anzahl der Daten länger wird, wird hier nur eine Warteschlange weggelassen.

AcbDataCreators.cs


using UnityEngine;
using UnityEditor;
namespace MyDearest {
	public static class AcbDataCreator {
		[MenuItem ("Sound/CreateAcbData")]
		private static void Create () {
			{
				ADXAcbData acb = ScriptableObject.CreateInstance<ADXAcbData> ();
				acb.Name = "BGM";
				{
					ADXAcbData.CueData cueData = new ADXAcbData.CueData ();
					cueData.Name = "Chronos";
					acb.Cues.Add (cueData);
				}
				AssetDatabase.CreateAsset (acb, "Assets/MyDearest/Chronos/Data/Sound/BGM.asset");
			}
		}
	}
}

Generieren Sie eine Unity CS-Datei mit Python

So erstellen Sie ein ScriptableObject für Unity

Ich wünschte, ich könnte ein ScriptableObject direkt aus Python erstellen, aber ich wusste nicht wenig über die YAML-Informationen von Unity Ich mache den Quellcode des Menüs, um ScriptObject mit Einheit zu machen.

Es ist etwas schwer zu erkennen, da der Code gleichzeitig mit der Analyse generiert wird, aber ich frage mich, ob es leicht zu verstehen ist, was Sie tun.

Bitte korrigieren Sie den Pfadnamen entsprechend.

adx2xml_to_str_cs.py


#print("Erstellen Sie ScriptableObject aus der ADX2-XML-Ausgabe C.#Code generieren")

import xml.etree.ElementTree as ET
import os

g_currentCueName = ""  #Name der Warteschlange
g_currentCueSheetName = "" #Name des Warteschlangenblatts


def writeHeader(outstr):
    outstr += "using UnityEngine;\n"
    outstr += "using UnityEditor;\n"
    outstr += "namespace MyDearest {\n"
    outstr += "	public static class AcbDataCreator {\n"
    outstr += "		[MenuItem (\"Window/MDSound/CreateAcbData\")]\n"
    outstr += "		private static void Create () {\n"

    return outstr

def writeFooter(assetoutpath,outstr):
    outstr += "\t\t\t\t\tacb.Cues.Add (cueData);\n"
    outstr += "\t\t\t\t}\n"
    outstr += "\t\t\t\tEditorUtility.SetDirty (acb);\n"
    outstr += "\t\t\t}\n"
    outstr += "\t\t}\n"
    outstr += "\t}\n"
    outstr += "}\n"

    return outstr
        
def printOrcaName(nest,child,xmlpath,outpath,assetoutpath,outstr):
    global g_currentCueName,g_currentCueSheetName
    nestspacestr = ""
    for i in range(nest):
        nestspacestr +=" "
    
    if(child.get("OrcaType") == "CriMw.CriAtomCraft.AcCore.AcOoCueSheet"):        
        print("Name des Warteschlangenblatts" + child.get("OrcaName"))   #Cue-Sheet

        if(g_currentCueSheetName != "" and g_currentCueSheetName != child.get("OrcaName")):   #Nur wenn sich das Cue Sheet ändert
            outstr += "\t\t\t\t\tacb.Cues.Add (cueData);\n"
            outstr += "\t\t\t\t}\n"
            outstr += "\t\t\t\tEditorUtility.SetDirty (acb);\n"
            outstr += "\t\t\t}\n"


        g_currentCueSheetName = child.get("OrcaName")
        g_currentCueName = ""
        outstr += "\t\t\t{\n"        
        outstr += "\t\t\t\tADXAcbData acb = (ADXAcbData)AssetDatabase.LoadAssetAtPath (\"" + assetoutpath + g_currentCueSheetName + ".asset\", typeof (ADXAcbData));\n"
        outstr += "\t\t\t\tif (acb == null) {\n"
        outstr += "\t\t\t\t        acb = ScriptableObject.CreateInstance<ADXAcbData> ();	//Machen Sie, wenn nicht\n"
        outstr += "\t\t\t\t        AssetDatabase.CreateAsset (acb, \"" + assetoutpath + g_currentCueSheetName + ".asset\");\n"
        outstr += "\t\t\t\t        acb = (ADXAcbData)AssetDatabase.LoadAssetAtPath (\"" + assetoutpath + g_currentCueSheetName + ".asset\", typeof (ADXAcbData));\n"
        outstr += "\t\t\t\t}\n"
        outstr += "\t\t\t\tacb.Cues.Clear ();\n"
        outstr += "\t\t\t\tacb.Name = \"" + g_currentCueSheetName + "\";\n"
    if(child.get("OrcaType") == "CriMw.CriAtomCraft.AcCore.AcOoCueFolder"):
        print(nestspacestr + "Name des Warteschlangenordners" + child.get("OrcaName"))
    if(child.get("OrcaType") == "CriMw.CriAtomCraft.AcCore.AcOoCueSynthCue"): #Warteschlange
        print(nestspacestr + "Name der Warteschlange" + child.get("OrcaName"))

        if(g_currentCueName != "" and g_currentCueName != child.get("OrcaName")):   #Schließen, wenn sich die Warteschlange ändert
            outstr += "					acb.Cues.Add (cueData);\n"
            outstr += "				}\n"

        g_currentCueName = child.get("OrcaName")
        outstr += "				{\n"
        outstr += "					ADXAcbData.CueData cueData = new ADXAcbData.CueData ();\n"
        outstr += "					cueData.Name = \"" + g_currentCueName + "\";\n"
        
        if 'UserData' in child.attrib:
            outstr += "					cueData.UserData = @\"" + child.get("UserData") + "\";\n"
        if 'Comment' in child.attrib:
            outstr += "					cueData.Comment = @\"" + child.get("Comment") + "\";\n"
            
    if(child.get("OrcaType") == "CriMw.CriAtomCraft.AcCore.AcOoAisac"):
        print(nestspacestr + "AISAC-Kontrollname" + os.path.basename(child.get("AisacControl")))
        outstr += "					cueData.AisacNames.Add (\"" + os.path.basename(child.get("AisacControl")) + "\");\n"
    if(child.get("OrcaType") == "CriMw.CriAtomCraft.AcCore.AcOoAisacLink"):
        print(nestspacestr + "AISAC-Kontrollname" + os.path.basename(child.get("LinkAisac")).split('@')[1])  # Distance@Mit einer Namenskonvention wie Entfernung@Hinter dem Kontrollnamen((Weil LinkAisac kein AisacControl hat)
        outstr += "					cueData.AisacNames.Add (\"" + os.path.basename(child.get("LinkAisac")).split('@')[1] + "\");\n"
    if(child.get("OrcaType") == "CriMw.CriAtomCraft.AcCore.AcOoBlock"):
        print(nestspacestr + "Blockname" + child.get("OrcaName"))
        outstr += "					cueData.BlockNames.Add (\"" + child.get("OrcaName") + "\");\n"

    return outstr

#Generieren Sie skriptfähigen Code zur Objektgenerierung, indem Sie XML analysieren
def conv(xmlpaths,outpath,assetoutpath):
    outstr = "";    
    outstr = writeHeader(outstr)

    for xmlpath in xmlpaths:
        tree = ET.parse(xmlpath) 
        root = tree.getroot()
        for child in root:
            for child1 in child:
                for child2 in child1:
                    for child3 in child2:
                        outstr = printOrcaName(0,child3,xmlpath,outpath,assetoutpath,outstr)
                        for child4 in child3:
                            outstr = printOrcaName(1,child4,xmlpath,outpath,assetoutpath,outstr)
                            for child5 in child4:
                                outstr = printOrcaName(2,child5,xmlpath,outpath,assetoutpath,outstr)
                                for child6 in child5:
                                    outstr = printOrcaName(3,child6,xmlpath,outpath,assetoutpath,outstr)
                                    for child7 in child6:
                                        outstr = printOrcaName(4,child7,xmlpath,outpath,assetoutpath,outstr)


    outstr = writeFooter(assetoutpath,outstr)
    
    print(outstr)
    with open(outpath,"w",encoding="utf-8") as f:
        f.write(outstr)

#Ausgabeziel erstellen (keine mehrschichtige Ausgabe)
adx2outputpath = "C:/MyDearest/CraftData/OculusAdxTest/PC/"
#Zu analysierende XML-Liste
cuesheetXmlNames = [adx2outputpath + "BGM_acb_info.xml",
                 adx2outputpath + "SE_acb_info.xml",
                 adx2outputpath + "VOICE_acb_info.xml"]

#Geben Sie den Speicherort der tatsächlichen Konvertierung und der generierten CS-Datei sowie den Speicherort der von der generierten Datei generierten Assets an
conv(cuesheetXmlNames,
     "C:/MyDearest/github/Chronos/Assets/MyDearest/Sound/Editor/AcbDataCreator.cs",
     "Assets/MyDearest/Chronos/Data/Sound/")

Es tut mir Leid Die rekursive Analyse von XML ist etwas enttäuschend und chaotisch, aber bitte fügen Sie ihn entsprechend der Komplexität der Daten hinzu.

abschließend

Als Anwendung Es ist einfach, XML zu analysieren und eine Textdatei zu erstellen Es kann auch zu Überprüfungszwecken, zur Versionsverwaltung und zur Zusammenarbeit mit ci-Tools verwendet werden.

Der Code hier wird aber nicht unterstützt, aber zum Beispiel

Ich denke, ich kann es herausnehmen. Wenn Sie jedoch alle blind herausnehmen, ist dies sehr groß und schwierig zu handhaben, und die Daten werden aufgebläht. Ich finde es gut, nur die notwendigen Informationen abrufen zu können.

Es kann in Zukunft zum Zwecke des Ersetzens von Daten beim Erstellen oder des Löschens von Debug-Informationen verwendet werden (obwohl ich es noch nicht ausprobiert habe).

Es kann auch eine automatische Generierung erfolgen, indem Informationen zum Zeitpunkt der Erstellung in die Cloud hochgeladen und von dort aus nach Updates gesucht werden.

Recommended Posts

Erstellen Sie ScriptableObject in Python, wenn Sie ADX2 erstellen
Erstellen Sie Spatia Lite in Python
Erstellen Sie eine Funktion in Python
Erstellen Sie ein Wörterbuch in Python
Achtung bei os.mkdir in Python
Vorsichtsmaßnahmen bei der Verwendung von Pit mit Python
Erstellen Sie einen DI-Container mit Python
Verhalten beim Auflisten in Python heapq
Erstellen Sie eine Binärdatei in Python
Erstellen Sie Google Mail in Python ohne Verwendung der API
Erstellen Sie eine Python-Projektdokumentation in Sphinx
Erstellen Sie eine zufällige Zeichenfolge in Python
Bei Verwendung regulärer Ausdrücke in Python
Beim Schreiben eines Programms in Python
Erstellen und lesen Sie Messagepacks in Python
Wenn Sie mehrere Schlüssel in Python-Sortierung angeben
Erstellen Sie Ihre eigenen Linux-Befehle in Python
Vorsichtsmaßnahmen beim Beizen einer Funktion in Python
[LLDB] Erstellen Sie Ihren eigenen Befehl mit Python
Erstellen Sie eine einfache GUI-App in Python
Erstellen Sie Qt-Designerteile mit Python (PyQt)
Wenn Sie sich die Speichernutzung in Python 3 ansehen
[GPS] Erstellen Sie eine kml-Datei mit Python
[Tipps] Leicht lesbares Schreiben beim Verbinden von Funktionen in Python
Quadtree in Python --2
Wenn der Codec das Byte nicht dekodieren kann, wird es in Python angezeigt
Python in der Optimierung
Metaprogrammierung mit Python
Erstellen Sie in 1 Minute eine Vim + Python-Testumgebung
Python 3.3 mit Anaconda
Geokodierung in Python
SendKeys in Python
Erstellen Sie eine GIF-Datei mit Pillow in Python
Metaanalyse in Python
Erstellen einer Umgebung, die Python mit Eclipse verwendet
Unittest in Python
Ich möchte mit Python ein Fenster erstellen
Erstellen Sie in Python ein Diagramm der Standardnormalverteilung
Wenn ich matplotlib in Python versuche, heißt es'cairo.Context '.
So erstellen Sie eine JSON-Datei in Python
Erstellen Sie automatisch Wort- und Excel-Berichte mit Python
Epoche in Python
Erstellen Sie eine virtuelle Umgebung mit conda in Python
Zwietracht in Python
Deutsch in Python
DCI in Python
Quicksort in Python
Vorsichtsmaßnahmen beim Umgang mit Kontrollstrukturen in Python 2.6
nCr in Python
N-Gramm in Python
Hinweis zur Codierung bei LANG = C in Python
Programmieren mit Python
Plink in Python
Konstante in Python
Erstellen Sie ein Bild mit Zeichen mit Python (Japanisch)
Zeichenkodierung beim Umgang mit Dateien in Python 3
Denken Sie daran, eine Python 3-Umgebung in einer Mac-Umgebung zu erstellen