はじめに
なぜかみつからなかったので投稿.書くほどのことか?と思うが誰かの役に立ちそうなのでメモ.
色の保存はvertexColorでテクスチャではない.なおUnityは初期設定ではobjに記載されたvertexColorを反映できないので,保存した.objファイルを他のunityプロジェクトに流用する際はこの方法は向かない.
環境
- Unity 2019.4
- Windows 10
コード
_.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
public class [classname] : MonoBehaviour
{
//保存対象オブジェクト(unity側で指定してください)
GameObject model;
// この関数を実行で保存.ボタンの関数等に設定してください
public void objSaveButtonFunc(){
Mesh mesh = model.GetComponent<MeshFilter>().mesh;
List<Vector3> _vertices = new List<Vector3>(mesh.vertices);
List<Color> _colors = new List<Color>(mesh.colors);
List<int> _triangles = new List<int>(mesh.triangles);
objWriter(_vertices, _colors, _triangles);
}
private void objWriter(List<Vector3> list_v, List<Color> list_c, List<int> list_t){
string path = Application.persistentDataPath + "/test.obj";
using (var fs = new StreamWriter(path, true, System.Text.Encoding.GetEncoding("UTF-8")))
{
print(path);
// ファイルの文頭から頂点情報を入れると反応しないレンダリングソフトがあるのでコメント挿入
fs.Write("### created by unity script")
for(int t = 0; t < list_v.Count; t++){
// 色つきで保存する場合はこのコメントを外して,下のfs.Writeをコメントアウト
// fs.Write("v " + list_v[t].x + " " + list_v[t].y + " " + list_v[t].z +
// " " + list_c[t].r + " " + list_c[t].b +" "+ list_c[t].g + "\n");
fs.Write("v " + list_v[t].x + " " + list_v[t].y + " " + list_v[t].z + "\n");
}
for(int t = 0; t < list_t.Count/3; t++){
string f1 = (list_t[t * 3 + 0] + 1)+"";
string f2 = (list_t[t * 3 + 1] + 1)+"";
string f3 = (list_t[t * 3 + 2] + 1) +"";
fs.Write("f "+f1+"//"+f1 +" "+ f2+"//"+f2+" "+f3+"//"+f3+"\n");
}
fs.Write("# vertex: "+list_v.Count + " face: "+ list_t.Count);
}
}
解説
- Unityの頂点番号は配列などと同様で0,1,2...n-1と保存されているが,.objのフォーマットでは1,2,3...nと記載するため,1を足している
- MeshLab2020.12 for Windowsでは文頭から頂点情報を書き込むと文頭の1点が無視されることを確認..objフォーマットの規則なのか文字コードが悪いのかバグなのか不明.詳しい人情報ください.