U3D 代码自动化生成定制预置体的旋转问题
1 //定制预置体 2 //要求:1,模型面向U3D的Z轴正向(由MAX导出时是面向U3D的X负向的) 3 //2,增加一些常用挂点,3增加一个圆形阴影片,4,添加包围盒 4 //根据这些要求制作预置休 5 static GameObject CreateCustomPrefab(string fbxResPath, string saveDir, string saveName) 6 { 7 Directory.CreateDirectory(saveDir); 8 var fbx = AssetDatabase.LoadAssetAtPath(fbxResPath, typeof(GameObject)) as GameObject; 9 if (fbx == null) 10 { 11 Debug.LogError("加载FBX失败:" + fbxResPath); 12 return null; 13 } 14 15 //往预置体中添加阴影,挂点等。 16 //注意:必须先将FBX和阴影都实例化出来,设置好层次关系,然后保存为预置体 17 18 ////////////////////////////////////////////////////////////////////////// 19 //制作出的预置体需要对模型朝向进行调整-旋转90度后让它刚好面向U3D的Z轴正向 20 //这个旋转不能施加到预置体的根上,因为进入游戏后,这个值将被人物走路的朝向值覆盖 21 //同样,旋转操作不能直接施加到模型的几何体上,因为它们将在骨骼变换中被覆盖 22 23 //生成根 24 var root = new GameObject(saveName); 25 26 //挂上模型 27 var fbxgo = GameObject.Instantiate(fbx, root.transform); 28 fbxgo.transform.localRotation = Quaternion.Euler(0, 90, 0);//旋转模型,使面向Z轴正向 29 fbxgo.name = "Mesh"; 30 31 //添加阴影 32 var shadow = AssetDatabase.LoadAssetAtPath("assets/res/prefabs/char/shadow.prefab", typeof(GameObject)) as GameObject; 33 var shadowgo = GameObject.Instantiate(shadow); 34 shadowgo.name = "shadow"; 35 shadowgo.transform.SetParent(root.transform); 36 37 //添加包围盒 38 var cap = root.AddComponent<CapsuleCollider>(); 39 cap.height = GameConst.charCapsuleHeight; 40 cap.radius = GameConst.charCapsuleRadius; 41 cap.center = new Vector3(0, cap.height / 2 -0.1f, 0); 42 43 //添加挂点,注意:这些挂点在未优化的FBX层级中已存在了(由MAX导出时,这些挂点选择与否都会导出,原因不明) 44 var fbxDir = Path.GetDirectoryName(fbxResPath); 45 var fpath = fbxDir + "/linkpts.txt"; 46 if (!File.Exists(fpath)) 47 { 48 EditorUtility.DisplayDialog("缺少挂点配置文件", fbxResPath, "ok"); 49 } 50 else 51 { 52 var sr = new StreamReader(File.OpenRead(fpath), Encoding.ASCII); 53 var longStr = sr.ReadToEnd(); 54 var dats = longStr.Split('\"'); 55 56 for (var i = 0; i < dats.Length; ++i) 57 { 58 if (dats[i] == "" || dats[i] == "\r\n") 59 continue; 60 var subdat = dats[i].Split(' '); 61 var lpt = new GameObject(subdat[0]); 62 63 //因为模型缩放了,挂点位置也要缩放 64 var fx = GameConst.modelFileScale * float.Parse(subdat[1]); 65 var fy = GameConst.modelFileScale * float.Parse(subdat[2]); 66 var fz = GameConst.modelFileScale * float.Parse(subdat[3]); 67 68 lpt.transform.position = new Vector3(fx, fy, fz); 69 lpt.transform.SetParent(root.transform); 70 } 71 } 72 73 74 var pb = PrefabUtility.CreatePrefab(saveDir + saveName, root); 75 76 //删除场景中生成的模型和阴影实例 77 GameObject.DestroyImmediate(root); 78 GameObject.DestroyImmediate(fbxgo); 79 GameObject.DestroyImmediate(shadowgo); 80 81 return pb; 82 }