| この記事の要点 |
|
Mesh Filter とは
Mesh Filter は Unity の標準コンポーネントで、3D メッシュデータ(頂点・面・UV・法線・接線・カラー)を GameObject に保持させる役割を担います。Mesh Filter 単独では描画されず、Mesh Renderer がそのメッシュをマテリアルで描画することで初めて画面に表示されます。
つまり Unity の 3D オブジェクトは次の三層構造で成り立ちます。
| コンポーネント | 役割 | 必須 |
|---|---|---|
| Transform | 位置・回転・スケール | 常に存在 |
| Mesh Filter | メッシュデータ(形状)の保持 | 3D 表示には必須 |
| Mesh Renderer | マテリアル適用・描画 | 表示には必須 |
Inspector での見え方
Hierarchy で 3D Object → Cube を作ると、Mesh Filter が自動付与され、Mesh 欄に Cube がセットされた状態になります。
| Inspector 項目 | 意味 |
|---|---|
| Mesh | 表示するメッシュアセット(.fbx / .obj / .asset)への参照 |
Project ウィンドウから別の .fbx をドラッグ&ドロップするだけで、形状を差し替えられます。
mesh と sharedMesh の違い(重要)
Unity 初心者がもっとも嵌まるのが mesh と sharedMesh の挙動差です。両者は名前が似ていますが、メモリと参照の扱いが全く違います。
| プロパティ | 挙動 | 用途 |
|---|---|---|
mesh | 初回アクセスで元メッシュをコピーしてインスタンス化。以降は専用インスタンスを返す | そのオブジェクト固有に頂点を編集したいとき |
sharedMesh | 元アセットへの参照を直接返す。書き換えると同じアセットを参照する全 GameObject に影響 | 表示メッシュの差し替え/読み取り専用アクセス |
using UnityEngine;
public class MeshFilterSample : MonoBehaviour
{
[SerializeField] private Mesh newMesh;
void Start()
{
var mf = GetComponent<MeshFilter>();
// (A) 表示メッシュを別アセットに差し替える(共有参照)
mf.sharedMesh = newMesh;
// (B) このオブジェクト固有に頂点を編集する
Mesh m = mf.mesh; // 内部でコピー生成(インスタンス化)
Vector3[] verts = m.vertices;
for (int i = 0; i < verts.Length; i++) verts[i] *= 1.2f;
m.vertices = verts;
m.RecalculateNormals();
m.RecalculateBounds();
// 不要になったら破棄してリーク防止
// Destroy(m); // OnDestroy 等で
}
}
よくある事故: sharedMesh を書き換えた
sharedMesh.vertices = ... を書くと、同じ Cube プリミティブを使う全 GameObject の形状が変わります。プロトタイプ全体が変形して原因不明となるので注意してください。
スクリプトから動的に差し替える
// 武器の見た目を切り替える例
public Mesh swordMesh;
public Mesh axeMesh;
public void Equip(string weapon)
{
var mf = GetComponent<MeshFilter>();
mf.sharedMesh = (weapon == "sword") ? swordMesh : axeMesh;
// マテリアルも切り替える場合は MeshRenderer.sharedMaterial も
}
メッシュをコードで自作する(プロシージャル)
// 三角形 1 枚を動的生成
Mesh mesh = new Mesh();
mesh.vertices = new[] {
new Vector3(0, 0, 0),
new Vector3(1, 0, 0),
new Vector3(0, 1, 0),
};
mesh.triangles = new[] { 0, 1, 2 };
mesh.uv = new[] { new Vector2(0,0), new Vector2(1,0), new Vector2(0,1) };
mesh.RecalculateNormals();
mesh.RecalculateBounds();
GetComponent<MeshFilter>().mesh = mesh;
MeshFilter と SkinnedMeshRenderer の違い
| 用途 | コンポーネント | 備考 |
|---|---|---|
| 静的なオブジェクト(壁、岩、武器) | Mesh Filter + Mesh Renderer | 軽量・バッチング可 |
| 人型・骨アニメ対象 | Skinned Mesh Renderer 単体 | Mesh Filter 不要(内部に sharedMesh を持つ) |
| 布・髪などのソフトボディ | Skinned Mesh Renderer + Cloth | 頂点を CPU で計算 |
Skinned Mesh Renderer は内部でメッシュを持つため、別途 Mesh Filter は付けません。両方付けるとメモリの無駄になります。
メッシュ編集ツール: ProBuilder
外部 DCC ツール(Blender / Maya)を使わずに Unity Editor 内でメッシュ編集したい場合は ProBuilder(Package Manager から無料導入)が便利です。
- 頂点・辺・面の押し出し、削除、結合
- UV 編集、マテリアル割り当て
- 編集結果はそのまま Mesh Filter に反映される
- レベルデザインのブロックアウトや、簡易プロップ作成に最適
メッシュデータの構成要素
| 要素 | 型 | 説明 |
|---|---|---|
| vertices | Vector3[] | 頂点座標 |
| triangles | int[] | 頂点インデックス(3 つで 1 三角形) |
| uv / uv2 / uv3 | Vector2[] | テクスチャ座標。ライトマップ用が uv2 |
| normals | Vector3[] | 法線ベクトル。ライティング計算に必須 |
| tangents | Vector4[] | ノーマルマップ用の接線 |
| colors | Color[] | 頂点カラー(シェーダー側で使用) |
| bounds | Bounds | カリング判定用 AABB |
最適化のポイント
- Static フラグを ON にして Static Batching を有効化(同じマテリアルのメッシュを 1 ドローコールに統合)
- GPU Instancing: マテリアルで Instancing を有効化すると、同じメッシュ × 多数表示が高速化
- Combine Meshes: スクリプトで
Mesh.CombineMeshesを使い 1 メッシュへ統合 - Mesh Compression: Import Settings で Low/Medium/High → 容量削減(精度低下とのトレードオフ)
- LOD Group: 距離に応じて低ポリメッシュへ自動切替
- Read/Write Enabled OFF: スクリプトでメッシュを読まないなら OFF にして、メモリ半減
よくあるトラブル
| 症状 | 原因 | 対処 |
|---|---|---|
| 表示されない | Mesh Renderer 未付与 or マテリアル None | 両方を付ける |
| 真っ黒に見える | 法線が逆/未設定/ライト無し | RecalculateNormals() /ライト追加 |
| マゼンタ(ピンク)表示 | マテリアルのシェーダーがレンダーパイプライン非対応 | URP/HDRP 用シェーダーに変更 |
| 頂点を書き換えてもメモリが減らない | 古い mesh インスタンスを破棄していない | Destroy(oldMesh) |
| 共有メッシュを変えたら他オブジェクトも変わる | sharedMesh を編集した | mesh 経由でインスタンス化 |
FAQ
Q: Mesh Filter だけ付けて Mesh Renderer を外すと?
A: 描画されません。データだけ保持された状態。当たり判定(Mesh Collider)に流用するときに使う構成です。
Q: 同じプレハブを大量配置するとドローコールが増えます
A: GPU Instancing 対応のマテリアルにし、Static 設定で Static Batching を有効化してください。
Q: mesh アクセスでメモリリークすると聞きました
A: mesh を呼ぶたびにコピーが作られ、Destroy しないと GC まで残ります。OnDestroy で Destroy(meshInstance) を呼ぶ習慣を。
📸 参考画像
※ 旧バージョンから引き継いだ参考画像です。手順・図解の補助としてご覧ください。

子ページはありません
- Mesh Filter
- Mesh Renderer
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- プロジェクトをTomcatプロジェクトとして認識させる方法 2026-10-07 22:32:50
- MySQLの1366 Incorrect string value|Laravelの文字コード・絵文字エラー 2026-10-07 21:54:03
- curlの証明書ホスト名不一致|旧エラー51・現行60の確認と対処 2026-10-07 21:54:03
- LaravelのMassAssignmentException|fillableの原因と安全な対処 2026-10-07 21:54:03
- Eclipse で Tomcat の起動ログがコンソールに出ない時の確認手順 2026-10-07 21:54:02
- MySQLにおける中央値(Median)の導き方(バージョン8未満) 2026-10-07 13:49:45
- getInputForward 2026-10-07 13:41:15
- JSONから配列に変換 2026-10-07 13:41:15
- ビューから値をモデルに格納しコントローラーで受け取る方法 2026-10-07 13:23:41
- Laravelのテーブル作成と定義変更|マイグレーション・up/down・注意点 2026-10-07 13:23:41
- NumPy 配列に要素を追加する方法 (append / concatenate) 2026-10-07 13:23:41
- MariaDB・MySQLで現在日時を取得する方法|NOW・タイムゾーン・保存型 2026-10-07 13:13:36
- 【django】テンプレートで定数を使用する方法 2026-10-07 13:10:15
- Spring BootにおけるApplication.propertiesの環境依存設定の分割方法 2026-10-07 12:09:35
- Not supported for DML operations【Springエラー】 2026-10-07 11:09:38