代码批量制作prefab

Posted xiaogeformax

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了代码批量制作prefab相关的知识,希望对你有一定的参考价值。

代码批量制作prefab

在unity的游戏中,美工制作的大量的游戏模型需要我们去处理,通常都是需要制作成prefab之后,再制作成assetBundle包来得到相应的物体。在这篇博客里面我们简单的讲解下批量快速制作成prefab的过程。

先生成菜单和鼠标右键快捷方式

[MenuItem("GameObject/生成一般模型Prefab", false, 0)]

这个就可在unity的引擎上面生成了菜单。

对选中的物体进行处理

GameObject[] objs = Selection.gameObjects;

如果选中了多个,就对其依次进行处理。

分别对单个进行处理

绑定BodyBindTransform脚本

我们主要是对人物模型,以及游戏npc进行处理,所以,需要绑定我们特定的脚本。在其他的使用中,也可以根据需要,自己添加需要的脚本。

 GameObject obj = objs[index];

            BodyBindTransform bodybind = obj.GetComponent<BodyBindTransform>();
            if (bodybind == null)
                bodybind = obj.AddComponent<BodyBindTransform>();
            bodybind.BindBody();

添加碰撞体

因为是人物的prefab,该有的碰撞体还是要有的,下面为其添加合适的碰撞体,方便依次去添加,并且快速的调整了碰撞体的大小。可以极大的提高工作的效率。

Collider col = obj.GetComponentInChildren<Collider>();
            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<CapsuleCollider>();
                Rigidbody rig = box.AddComponent<Rigidbody>();
                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进行设置

对其中的SkinnedMeshRenderer进行一些设置。
EditorUtility.SetDirty(obj)这个函数EditorUtility.SetDirty :这个函数告诉引擎,相关对象所属于的Prefab已经发生了更改。方便,当我们更改了自定义对象的属性的时候,自动更新到所属的Prefab中。

SkinnedMeshRenderer[] skins = obj.GetComponentsInChildren<SkinnedMeshRenderer>();
            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<Animator>();
        if (anim != null)
        
            anim.applyRootMotion = true;
            anim.cullingMode = AnimatorCullingMode.AlwaysAnimate;
            if (anim.runtimeAnimatorController == null)
            
                Debug.LogError("状态机为空");
                return false;
            
        
        return true;
    

设置路径和制作成prefab

这个也是最重要的制作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<BodyBindTransform>();
            if (bodybind == null)
                bodybind = obj.AddComponent<BodyBindTransform>();
            bodybind.BindBody();

            Collider col = obj.GetComponentInChildren<Collider>();
            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<CapsuleCollider>();
                Rigidbody rig = box.AddComponent<Rigidbody>();
                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<SkinnedMeshRenderer>();
            //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);
        
    

以上是关于代码批量制作prefab的主要内容,如果未能解决你的问题,请参考以下文章

Unity3d学习 预设体(prefab)的一些理解

批量创建prefab

unity中怎么控制生成的prefab位置

10.预制体

Untiy3D学习笔记记录

为Unity3D创建素材(3):预设物体(Prefab)