在unity的游戏中,美工制作的大量的游戏模型需要我们去处理,通常都是需要制作成prefab之后,再制作成assetBundle包来得到相应的物体。在这篇博客里面我们简单的讲解下批量快速制作成prefab的过程。
[MenuItem("GameObject/生成一般模型Prefab", false, 0)]
这个就可在unity的引擎上面生成了菜单。
GameObject[] objs = Selection.gameObjects;
如果选中了多个,就对其依次进行处理。
我们主要是对人物模型,以及游戏npc进行处理,所以,需要绑定我们特定的脚本。在其他的使用中,也可以根据需要,自己添加需要的脚本。
GameObject obj = objs[index];
BodyBindTransform bodybind = obj.GetComponent();
if (bodybind == null)
bodybind = obj.AddComponent();
bodybind.BindBody();
因为是人物的prefab,该有的碰撞体还是要有的,下面为其添加合适的碰撞体,方便依次去添加,并且快速的调整了碰撞体的大小。可以极大的提高工作的效率。
Collider col = obj.GetComponentInChildren();
if (col == null)
{
GameObject box = new GameObject("BoxCollider");
box.transform.SetParent(obj.transform);
box.transform.localPosition = Vector3.zero;
box.transform.localEulerAngles = Vector3.zero;
box.transform.localScale = Vector3.one;
CapsuleCollider collier = box.AddComponent();
Rigidbody rig = box.AddComponent();
rig.isKinematic = true;
rig.freezeRotation = true;
rig.useGravity = false;
collier.center = new Vector3(0, 1.1f, 0);
collier.radius = 0.5f;
collier.height = 2.0f;
collier.direction = 1;
collier.isTrigger = true;
Transform effet_chest = bodybind.GetBindParent("effect_chest");
box.transform.SetParent(effet_chest.parent);
}
对其中的SkinnedMeshRenderer进行一些设置。
EditorUtility.SetDirty(obj)这个函数EditorUtility.SetDirty :这个函数告诉引擎,相关对象所属于的Prefab已经发生了更改。方便,当我们更改了自定义对象的属性的时候,自动更新到所属的Prefab中。
SkinnedMeshRenderer[] skins = obj.GetComponentsInChildren();
for (int i = 0; i < skins.Length; i++)
{
GameObject skinmesh = skins[i].gameObject;
SkinnedMeshRenderer mesh = skins[i];
mesh.receiveShadows = false;
mesh.useLightProbes = false;
mesh.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
EditorUtility.SetDirty(obj);
}
Transform effect_root = obj.transform.Find("effect_root");
if (effect_root != null)
effect_root.localEulerAngles = Vector3.zero;
public static bool CheckAnimatorOk(GameObject go)
{
Animator anim = go.GetComponent();
if (anim != null)
{
anim.applyRootMotion = true;
anim.cullingMode = AnimatorCullingMode.AlwaysAnimate;
if (anim.runtimeAnimatorController == null)
{
Debug.LogError("状态机为空");
return false;
}
}
return true;
}
这个也是最重要的制作prefab的代码,调用了unity自带的函数。
PrefabUtility.CreatePrefab(path, go, ReplacePrefabOptions.Default);
下面是全部的代码,其中CheckAnimatorOK函数在本文已经给出了,后面的CreatePrefabInternal函数就是的内容就是上文的制作prefab的函数。
[MenuItem("GameObject/生成一般模型Prefab", false, 0)]
public static void CreateNormalPrefabByFbx()
{
GameObject[] objs = Selection.gameObjects;
for (int index = 0; index < objs.Length; index++)
{
GameObject obj = objs[index];
BodyBindTransform bodybind = obj.GetComponent();
if (bodybind == null)
bodybind = obj.AddComponent();
bodybind.BindBody();
Collider col = obj.GetComponentInChildren();
if (col == null)
{
GameObject box = new GameObject("BoxCollider");
box.transform.SetParent(obj.transform);
box.transform.localPosition = Vector3.zero;
box.transform.localEulerAngles = Vector3.zero;
box.transform.localScale = Vector3.one;
CapsuleCollider collier = box.AddComponent();
Rigidbody rig = box.AddComponent();
rig.isKinematic = true;
rig.freezeRotation = true;
rig.useGravity = false;
collier.center = new Vector3(0, 1.1f, 0);
collier.radius = 0.5f;
collier.height = 2.0f;
collier.direction = 1;
collier.isTrigger = true;
Transform effet_chest = bodybind.GetBindParent("effect_chest");
box.transform.SetParent(effet_chest.parent);
}
SkinnedMeshRenderer[] skins = obj.GetComponentsInChildren();
//if (skins.Length != 1)
//{
// Debug.LogError("skin mesh 的数量不符合" + obj.name);
// continue;
//}
for (int i = 0; i < skins.Length; i++)
{
GameObject skinmesh = skins[i].gameObject;
SkinnedMeshRenderer mesh = skins[i];
mesh.receiveShadows = false;
mesh.useLightProbes = false;
mesh.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
EditorUtility.SetDirty(obj);
}
Transform effect_root = obj.transform.Find("effect_root");
if (effect_root != null)
effect_root.localEulerAngles = Vector3.zero;
if (!CheckAnimatorOk(obj)) return;
string prefabpath = tempPrefabFolderPath + obj.name + ".prefab";
CreatePrefabInternal(obj, prefabpath);
}
}