Skip to content

Instantly share code, notes, and snippets.

@k-okawa
Last active November 5, 2021 09:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save k-okawa/fda0da9bf9c557388b54c226e761b6a6 to your computer and use it in GitHub Desktop.
Save k-okawa/fda0da9bf9c557388b54c226e761b6a6 to your computer and use it in GitHub Desktop.
LinkXmlGenerator.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Xml;
using UnityEditor;
using UnityEngine;
public class LinkXmlGenerator {
Dictionary<Type, Type> m_TypeConversion = new Dictionary<Type, Type>();
HashSet<Type> m_Types = new HashSet<Type>();
// ---追加---
HashSet<Assembly> m_Assemblies = new HashSet<Assembly>();
// ----------
///<Summary>link.xmlに登録する型を追加する</Summary>
public void AddType(Type type) {
if (type == null)
return;
AddTypeInternal(type);
}
///<Summary>link.xmlに登録する型を追加する</Summary>
public void AddTypes(params Type[] types) {
if (types == null)
return;
foreach (var t in types)
AddTypeInternal(t);
}
///<Summary>link.xmlに登録する型を追加する</Summary>
public void AddTypes(IEnumerable<Type> types) {
if (types == null)
return;
foreach (var t in types)
AddTypeInternal(t);
}
// ---追加---
public void AddAssembly(Assembly assembly) {
if (assembly == null)
return;
m_Assemblies.Add(assembly);
}
// ---------
private void AddTypeInternal(Type t) {
if (t == null)
return;
Type convertedType;
if (m_TypeConversion.TryGetValue(t, out convertedType))
m_Types.Add(convertedType);
else
m_Types.Add(t);
}
///<Summary>代替する型を指定する。エディターとランタイムで利用する型が違う場合に使用</Summary>
public void SetTypeConversion(Type a, Type b) {
m_TypeConversion[a] = b;
}
///<Summary>link.xmlに登録するアセットを追加する</Summary>
public void AddAsset(string assetpath) {
var assets = AssetDatabase.GetDependencies(assetpath);
List<Type> types = new List<Type>();
foreach (var asset in assets) {
var type = AssetDatabase.GetMainAssetTypeAtPath(asset);
if (type == typeof(GameObject)) {
var obj = (GameObject) AssetDatabase.LoadAssetAtPath(asset, typeof(GameObject));
try {
types.AddRange(obj.GetComponentsInChildren<Component>(true).Select(c => c.GetType()));
}
catch {
Debug.LogError($"missing script: {asset}");
}
} else {
types.Add(type);
}
}
AddTypes(types);
}
///<Summary>link.xmlに登録するアセットを追加する</Summary>
public void AddAssets(string[] assetPaths) {
foreach (var assetPath in assetPaths)
AddAsset(assetPath);
}
///<Summary>link.xmlファイルを保存する</Summary>
public void Save(string path) {
var assemblyMap = new Dictionary<Assembly, List<Type>>();
foreach (var t in m_Types) {
var a = t.Assembly;
List<Type> types;
if (!assemblyMap.TryGetValue(a, out types))
assemblyMap.Add(a, types = new List<Type>());
types.Add(t);
}
XmlDocument doc = new XmlDocument();
var linker = doc.AppendChild(doc.CreateElement("linker"));
foreach (var k in assemblyMap) {
if (k.Key.FullName.Contains("UnityEditor"))
continue;
// ---追加---
if (m_Assemblies.Any(itr => itr.FullName == k.Key.FullName))
continue;
// ----------
var assembly = linker.AppendChild(doc.CreateElement("assembly"));
var attr = doc.CreateAttribute("fullname");
attr.Value = k.Key.FullName;
if (assembly.Attributes != null) {
assembly.Attributes.Append(attr);
foreach (var t in k.Value) {
var typeEl = assembly.AppendChild(doc.CreateElement("type"));
var tattr = doc.CreateAttribute("fullname");
tattr.Value = t.FullName;
if (typeEl.Attributes != null) {
typeEl.Attributes.Append(tattr);
var pattr = doc.CreateAttribute("preserve");
pattr.Value = "all";
typeEl.Attributes.Append(pattr);
}
}
}
}
// ---追加---
foreach (var assembly in m_Assemblies) {
var asmNode = linker.AppendChild(doc.CreateElement("assembly"));
var attr = doc.CreateAttribute("fullname");
attr.Value = assembly.FullName;
if (asmNode.Attributes != null)
asmNode.Attributes.Append(attr);
}
// ----------
doc.Save(path);
}
}
var generator = new LinkXmlGenerator();
// UnityEditor.Animations.AnimatorControllerを取得してしまうので、RuntimeAnimatorControllerに変更
generator.SetTypeConversion(typeof(UnityEditor.Animations.AnimatorController), typeof(RuntimeAnimatorController));
// AssetBundleNameを持つアセットを全て取得して、LinkXmlGeneratorに登録する。
foreach (var bundleName in AssetDatabase.GetAllAssetBundleNames()) {
var assetPaths = AssetDatabase.GetAssetPathsFromAssetBundle(bundleName);
generator.AddAssets(assetPaths);
}
// タイムライン関連を追加
Assembly asm = Assembly.Load("Unity.Timeline");
generator.AddAssembly(asm);
// link.xmlファイルを保存
generator.Save("Assets/link.xml");
AssetDatabase.Refresh();
@k-okawa
Copy link
Author

k-okawa commented Nov 5, 2021

本家様
https://gist.github.com/tsubaki/2ce4ed3ef178f5030b55439d9a10caf3

アセンブリを丸々指定したいときのためにAddAssembly関数を追加

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment