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.
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
・ 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
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.
Ich wollte Informationen extrahieren, die für etwas verwendet werden könnten.
("Etwas" hier kann ein internes Tool sein.)
Nach dem Erstellen mit ADX2 Bei Ausführung über das Menü in Unity
Generieren Sie eine .assets-Datei, die so aussieht. Es wird so viele wie die Anzahl der Cue-Sheets gemacht.
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.)
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 ...)
Verwenden Sie Python, um XML zu analysieren. Wählen Sie die erforderlichen Informationen mit Python und Generieren Sie den Code, der das ScriptableObject erstellt.
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
--Ü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.)
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 ();
}
}
}
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");
}
}
}
}
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.
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