本文主要原理:
选择模型拆分 成为ab包 然后 根据自己的需要 组合 完成角色换装功能 unity5.x 的换装相对4.x 更新了api 所以更加好用
找了挺多资料的,很多文章都是讲的原理几乎很少代码,相对于我这样的小白根本看不太明白,还是直接上代码直接简单粗暴!大神的世界很难懂!
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.IO;
/// <summary>
/// 创建assetbudles文件
/// </summary>
public class CreateAssetbundles
{
//手动选择fbx 或者 .prefab 角色模型文件 拆分成为 主骨骼+部件的包[武器,头,身体,等等]
[MenuItem("Character Generator/Create Assetbundles")]
static void Execute()
{
foreach (Object o in Selection.GetFiltered(typeof(Object),SelectionMode.DeepAssets))
//foreach (Object o in Selection.objects)
{
if (!(o is GameObject)) continue;
if (o.name.Contains("@")) continue;
if (!AssetDatabase.GetAssetPath(o).Contains("/Model/")) continue;
GameObject characterFBX = (GameObject)o;
string name = characterFBX.name.ToLower();
Debug.Log("****** Creating assetbundles for : " + name + "****** o.name : " + o.name);
// Create a directory to store the generated assetbundles.
if (!Directory.Exists(AssetbundlePath))
{
Directory.CreateDirectory(AssetbundlePath);
}
// Delete existing assetbundles for current character.
string[] existingAssetbundles = Directory.GetFiles(AssetbundlePath);
foreach (string bundle in existingAssetbundles)
{
if ((bundle.EndsWith(".assetbundle") || bundle.EndsWith(".manifest")) && bundle.Contains(name))//"\\Model\\" +
{
File.Delete(bundle);
}
}
GameObject charactorClone = (GameObject)Object.Instantiate(characterFBX);
// we need delete the trashy bones
foreach (SkinnedMeshRenderer smr in charactorClone.GetComponentsInChildren<SkinnedMeshRenderer>())
{
Object.DestroyImmediate(smr.gameObject);
}
charactorClone.AddComponent<SkinnedMeshRenderer>();
Object charactorBasePrefab = GetPrefab(charactorClone, "charactorbase");
// Create the array of bundle build details.
string cloneRes = AssetDatabase.GetAssetPath(charactorBasePrefab);
//Debug.Log(cloneRes);
//unity 5.x 的换装颠覆4.x以前的版本
//相比官方的4.x 收集材质 骨骼 信息 简单粗暴,几乎就是直接把prefab打包 啥都不用管
AssetBundleBuild[] buildMap = new AssetBundleBuild[1];
buildMap[0].assetBundleName = name + "_charactorbase";//打包资源名称
buildMap[0].assetBundleVariant = "assetbundle";//扩展名称
buildMap[0].assetNames = new string[] { cloneRes };//直接打包根骨骼 完整prefab路径 后缀.prefab
BuildPipeline.BuildAssetBundles(Application.dataPath + "/assetbundles",buildMap,BuildAssetBundleOptions.None,EditorUserBuildSettings.activeBuildTarget);
AssetDatabase.DeleteAsset(cloneRes);
// Create assetbundles for each SkinnedMeshRenderer
foreach (SkinnedMeshRenderer smr in characterFBX.GetComponentsInChildren<SkinnedMeshRenderer>(true))
{
GameObject rendererClone = (GameObject)Object.Instantiate(smr.gameObject);
Object rendererPrefab = GetPrefab(rendererClone, smr.name);
// Save the assetbundle.
string bundleName = name + "_" + smr.name.ToLower();
buildMap = new AssetBundleBuild[1];
buildMap[0].assetBundleName = bundleName;//打包资源名称
buildMap[0].assetBundleVariant = "assetbundle";//扩展名称
string[] assets = new string[1];
assets[0] = AssetDatabase.GetAssetPath(rendererPrefab);
buildMap[0].assetNames = assets;//同理 直接打包部件资源包
BuildPipeline.BuildAssetBundles(Application.dataPath + "/assetbundles", buildMap, 0, EditorUserBuildSettings.activeBuildTarget);
// Delete temp assets.
AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(rendererPrefab));
//到这里整个模型就拆分结束了,剩下的就是加载了
}
}
}
//手动设置资源的AssetBundle的名称和文件扩展名
[MenuItem("Character Generator/SetFileBundleName")]
static void SetBundleName()
{
#region 设置资源的AssetBundle的名称和文件扩展名
UnityEngine.Object[] selects = Selection.objects;
foreach (UnityEngine.Object selected in selects)
{
string path = AssetDatabase.GetAssetPath(selected);
AssetImporter asset = AssetImporter.GetAtPath(path);
asset.assetBundleName = selected.name; //设置Bundle文件的名称
asset.assetBundleVariant = "assetbundle";//设置Bundle文件的扩展名
asset.SaveAndReimport();
}
AssetDatabase.Refresh();
#endregion
}
//替换空Prefab
static Object GetPrefab(GameObject go, string name)
{
Object tempPrefab = PrefabUtility.CreateEmptyPrefab(AssetbundleCreatePath + name + ".prefab");
tempPrefab = PrefabUtility.ReplacePrefab(go, tempPrefab);
Object.DestroyImmediate(go);
return tempPrefab;
}
//打包的文件路径
public static string AssetbundlePath
{
get { return "Assets" + Path.DirectorySeparatorChar + "assetbundles" + Path.DirectorySeparatorChar; }// \ \
}
public static string AssetbundleCreatePath
{
get { return "Assets/assetbundles/"; }
}
/// <summary>
/// 不同平台下StreamingAssets的路径[这里没用到]
/// </summary>
public static string PathUrl
{
//不同平台下StreamingAssets的路径是不同的,这里需要注意一下。
get{
return
#if UNITY_ANDROID
"jar:file://" + Application.dataPath + "!/assets/";
#elif UNITY_IPHONE
Application.dataPath + "/Raw/";
#elif UNITY_STANDALONE_WIN || UNITY_EDITOR
"file://" + Application.dataPath + "/StreamingAssets/";
#else
string.Empty;
#endif
}
}
}