出来るだけ公平なゲームマップを自動生成する「カタン・ボードジェネレーター」を作ってみた

世界的に人気なボードゲーム「カタン(Catan)」をご存知ですか?

普段ボードゲームを遊ばない私ですが、年始に旧友らとプレイして、気がついたらドハマリしていました。

カタンは計19枚の資材タイルを組み合わせたボードの上で、各頂点にプレイヤーが拠点を配置し、毎ターン2ダイスを振って、その合計値に対応したタイルに隣接する拠点を持つプレイヤーが資材を獲得するというシンプルなルールです。

プレイヤーは資材を使用して「街道」をタイルの辺に設置することができ、その街道沿いに別の拠点を建てることができます。

拠点の数が増えると隣接するタイルも増えて、より多くの数字をカバーすることができるので、資材獲得のチャンスが増え、ゲームを有利に進められるという仕組みです。

ここで重要になってくるのが、タイルの配置方法と、対応数字の配分です。

同じ種類の資材が隣接していたり、期待値が高い数字(6と8)が隣接していると、特定プレイヤーが極端に資源を獲得してゲームバランスが崩れます。

より公平なゲームにするためには、確率が極端に偏らないように、慎重にタイルを配置する必要があります。

そこで今回は、数学的に「公平なタイル配置」を瞬時に生成できる「カタン・ボードジェネレーター」を作成してみました。

【2025年6月更新】 v2.1.0にて資材バランスの視覚化生成精度の向上を実現!v2.0.0で実装した拡張版(5-6人用)対応とUI改善に加え、より高品質なボード生成が可能になっています。

▶︎ Catan Board Generator


  1. カタン・ボードジェネレーターとは
  2. 特徴・主な機能
  3. 使用方法
  4. 配置ルールの詳細
  5. v2.0.0 拡張版対応(2025/06/07)
  6. v2.1.0 公平精度向上+資材バランス視覚化(2025/06/12)
  7. v2.2.0 バランス崩壊オプション(2025/06/14)
  8. まとめ

カタン・ボードジェネレーターとは

このツールは、カタン(Catan)のボードを自動で生成するWebアプリです。
一度に「資源タイル」と「数字チップ」をランダム配置できるほか、数字だけを再シャッフルすることも可能です。
公式ルールで推奨される「6と8が隣接しないようにする」「同じ資源が連続しすぎない」などを考慮しつつ、ある程度バランスを取った配置を目指しています。
自分好みの盤面ができたら、画像として保存しておくこともできます。

v2.0.0では通常版(3-4人用)に加えて拡張版(5-6人用)にも対応し、UIも大幅に改善しました。

▶︎ Catan Board Generator

特徴・主な機能

  • 🆕 通常版・拡張版の両対応 – 3-4人用(19タイル)と5-6人用(30タイル)を切り替え可能
  • 📖 資源タイル数字チップの自動シャッフル
  • 🔨 「数字だけシャッフル」で資源配置はそのまま保持
  • 🔄 6と8の隣接を厳格に回避
  • 📊 出現確率の偏りを抑えた高度なバランス調整
  • 🖥️ 2カラムレイアウトで操作性が大幅向上
  • 📱 レスポンシブ対応 – PC、タブレット、スマホで最適表示
  • 🖼️ 高解像度画像として保存が可能(2000x2000px)

使用方法

  1. カタン・ボードジェネレーター へアクセス
  2. ボードタイプを選択 – 「通常版」または「拡張版(5-6人用)」を選択
  3. シャッフル」ボタンを押して、資源タイル+数字チップをランダム配置
  4. 資源配置は気に入ったまま、数字だけ変えたい場合は「数字だけシャッフル」ボタン
  5. 画像として保存したい場合は「画像を保存」ボタン

配置ルールの詳細

このツールは公式ルールを基盤としつつ、より公平で戦略的なゲーム展開を目指すための独自のバランス調整を加えています。

【基本的な配置ルール】

  • 資源の隣接禁止: 同じ種類の資源タイル(森、牧草地、丘陵、山地、畑)は隣接しません
  • 特定数字の隣接禁止: 高確率の「6」と「8」、および低確率の「2」と「12」は隣接しないように配置されます
  • 同じ数字の重複禁止: 同じ資源タイプに同じ数字が複数割り当てられることはありません

【高度なバランス調整】

  • 高確率数字の分散: 高確率の「6」「8」が特定の資源に集中しないよう、各資源タイプにバランス良く割り当てられます
  • 交差点の期待値均一化: 3つのタイルが接する「交差点」の価値(3タイルの数字の出やすさの合計)が極端に低い場所が固まらないように調整します
  • 資源ごとの数字品質: 特定の資源に悪い数字(2, 3, 11, 12など)ばかりが集まらないようにし、各資源に最低限の生産期待値を保証します
  • 確率分散の最適化: 各資源タイプの生産確率が理想的な比率に近づくよう微調整されます

【表示について】

  • 数字の確率: 数字チップ下の「●」の数は、その数字の出やすさ(36通り中の確率)を表しています
  • 高確率の強調: 特に確率の高い「6」と「8」は、赤色で表示されます
  • 視認性: 各タイルは資源に応じた色分けで、一目でボード構成が把握できます

v2.0.0 拡張版対応(2025/06/07)

2025年6月のアップデートで、v2.0.0をリリースしました。主な改善点は以下の通りです:

拡張版の特徴

  • タイル数: 19枚 → 30枚に増加
  • 資源構成: 各資源が追加され、より多様な戦略が可能
  • 数字チップ: 各数字が追加され、より多くの選択肢
  • 砂漠タイル: 1枚 → 2枚に増加

その他の改善点

  • 2カラムレイアウト: PC画面ではコントロールパネルとボード表示を分離し、操作性を大幅向上
  • レスポンシブデザイン: デバイスサイズに応じてレイアウトを最適化
  • 動的パラメータ調整: ボードサイズに応じて生成アルゴリズムのパラメータを自動調整
  • 探索空間の最適化: 拡張版では探索ステップ数を2.3倍に増加し、安定した生成を実現
  • パフォーマンス改善: 座標計算のキャッシュ化とアルゴリズムの最適化
  • エラーハンドリング: 生成失敗時の適切なフィードバックとリトライ機能

これにより、通常版と同等の品質で拡張版のボードを生成できるようになりました。

v2.1.0 公平精度向上+資材バランス視覚化(2025/06/12)

2025年6月12日のアップデートで、v2.1.0をリリースしました。主な改善点は以下の通りです:

  • 資材バランスの視覚化: 「資源の出やすさ」を示す統計情報セクションを追加し、各資源の生産期待値をスコア化して表示
  • 公平性の向上: 資源ごとの合計生産期待値に下限値を設定(通常版:11, 拡張版:16)し、極端に不利な資源が生まれないよう調整
  • 処理の高速化: Web Workerを導入し、ボード生成中の計算処理を高速化・安定化

これらの改善により、生成されたボードの品質をより正確に評価できるようになり、より公平で戦略的なゲーム展開が可能になりました。

v2.2.0 バランス崩壊オプション(2025/06/14)

2025年6月14日のアップデートで、v2.2.0をリリースしました。主な改善点は以下の通りです:

  • バランス崩壊オプション: あえて資源や数字の偏りを許容する「バランス崩壊オプション」を新設。デフォルトでは最も公平なボードが生成されますが、このオプションを有効にすることで、特定資源や数字が極端に偏る“カオスなボード”も作成可能になりました。
  • 資源期待値のバランス: 各資源の生産期待値の下限を調整し、偏りの度合いを選択可能に。
  • 資源の隣接制限: 同じ資源が隣接しないよう制限するか選択可能に。
  • 数字の隣接制限: 高確率数字や低確率数字が隣接しないよう制限するか選択可能に。

これにより、通常のバランス重視プレイはもちろん、ネタプレイや上級者向けの変則ルールにも対応できるようになりました。

「バランス崩壊オプション」を使って、あえて理不尽なボードや戦略性の高い盤面を楽しむこともできます。

まとめ

この「カタン・ボードジェネレーター」を使えば、6と8が固まる問題資源タイルが同一に偏る問題をできるだけ回避しつつ、短時間でボードレイアウトを決めることができます。
v2.0.0では拡張版対応により5-6人でのプレイにも対応し、UI改善によってより使いやすくなりました。
v2.1.0では資材バランスの視覚化生成精度の向上により、より公平で戦略的なボード生成が可能になっています。
実際のゲーム開始までの準備時間を大幅に減らし、いち早くプレイに集中したいときなどにおすすめです。

ご利用上の注意点

当ツールは公平なゲーム体験を目指し設計されていますが、ボードの「最適さ」はプレイヤーの戦略や好みによっても異なります。生成ロジックは確率的な要素を含むため、最終的な盤面のバランスについては、ご自身の目でご確認の上、ご活用いただくことをお勧めします。

ぜひ下記リンクよりお試しください。

▶︎ Catan Board Generator

皆さんのカタンライフが、よりスムーズで楽しいものになるよう祈っています!

Synology NAS DS218playの故障したファンを交換してみた

映像制作やゲーム制作の膨大なデータを管理するため、いくつかのNAS(Network Atacched Storage)を運用しています。複数PC間で制作した素材を、ネットワーク経由で即時受け渡しすることができるので非常に便利です。

今回、その中でも古くから使用しているSynologyNAS DS218playのファンが定期的に止まるようになってしまったので、スペアパーツを購入して交換した手順を記録します。


NAS本体+スペアパーツ


発生した問題: ファンが停止&再起動を繰り返す

今回発生したのは、SynologyNASの電源をいれてしばらくするとファンが停止し、数秒で復活して、再び停止するを繰り返す問題です。数分おきに下記のような警告が通知されました。


ファンの掃除などをしても問題が解決しなかったため、スペアパーツを購入。


スペアパーツへの交換

届いたスペアファン。AmazonのSynology販売から購入しました。

SynologyNASのネジを外します。

ファン周りの構造は非常にシンプルです。電源ケーブルを抜いて、銀ラベルを剥がします。

SynologyNASのファンはモデルによって固定方法が異なります。

例えばDS218は背面からネジで止められていますが、DS218playはこのように内側のゴムリングで固定されています。

DS218playのシステムメンテナンスページは見つかりませんでしたが、下記からDS223jの交換手順が確認できます。DS218playとほぼほぼ同じ手順で交換できます。

DS223j 製品マニュアル 4.1 故障したファンの交換 – Synologyナレッジセンター

NASの底面の4箇所のネジを取り外して、指が届かない下部のゴムリングも外してスペアファンと交換します。

取り付け完了。これで正常に動作するようになりました。

ブラウザで簡単印刷!参考書・資格勉強の進捗管理チェックシート作成【進捗チェックシートメーカー】

分厚い参考書や長大なオンラインコース、学習を始めたはいいものの、なかなか最後までやり遂げられない…そんな経験はありませんか?日々の進捗が見えにくいと、モチベーションを保つのが難しくなってしまいますよね。

そんな時、アナログな「進捗チェックシート」が意外な効果を発揮します。自分の手で進捗を記録し、達成感を可視化することで、「今日も頑張った!」「あと少しだ!」と前向きな気持ちを維持しやすくなります。

そこで今回は、そんな学習の伴走者となる「進捗チェックシートメーカー」をご紹介します。ブラウザ上で誰でも簡単に、自分だけのオリジナルチェックシートを作成し、印刷できる無料のWebツールです。

資格試験の勉強、読書記録、オンラインコースの受講管理など、様々な目標達成にご活用ください!

▶︎ 進捗チェックシートメーカー(印刷用)


  1. 「進捗チェックシートメーカー」とは?
  2. 主な特徴・機能
  3. 使い方(かんたん3ステップ)
  4. 活用メリットとアイデア
  5. 仕組みについて(安心設計)
  6. まとめ

「進捗チェックシートメーカー」とは?

「進捗チェックシートメーカー」は、参考書、問題集、オンラインコース、読書など、ページ数やセクション数で管理できる学習対象の進捗を「見える化」するためのチェックシートを、ブラウザ上で手軽に作成・印刷できるツールです。
お好みの表紙画像と、管理したい開始ページ・終了ページを入力するだけで、A4横サイズに最適化されたチェックシートが自動生成されます。
デジタルツールでの進捗管理も便利ですが、「紙に印刷して、ペンでチェックを入れる」というアナログな行為が、達成感や学習継続のモチベーションに繋がることも多いものです。このツールは、そんな手触りのある学習管理をサポートします。

アクセスはこちらからどうぞ。

▶︎ 進捗チェックシートメーカー(印刷用)

主な特徴・機能

  • 📋 簡単操作: 画像選択とページ数入力だけで、誰でも簡単にチェックシートを作成。
  • 🖼️ カスタム表紙画像: 参考書の表紙やコースのサムネイルなど、好きな画像を表紙に設定可能(画像なしでもOK)。
  • ページ範囲指定: 開始ページと終了ページを指定して、必要な範囲だけのチェックシートを作成。
  • 📄 A4印刷最適化: 生成される画像はA4横サイズ(3508×2480ピクセル)で、印刷して使いやすいレイアウト。
  • 🕹️ ドラッグ&ドロップ対応: 表紙画像はドラッグ&ドロップでも簡単に設定できます。
  • 🔒 プライバシー配慮: 画像処理はすべてブラウザ内で行われ、画像データがサーバーに送信されることはありません。
  • 🔀 自動グリッド調整: 指定された総ページ数に応じて、チェックボックスのマス目の大きさと数が自動で最適化されます。
  • 📥 即時ダウンロード: 生成されたチェックシートはすぐにPNG画像としてダウンロードできます。
  • 🎓 学習モチベーション向上: 手書きでチェックすることで進捗を実感しやすく、学習継続をサポート。

使い方(かんたん3ステップ)

チェックシートの作成は非常にシンプルです。

  1. 表紙画像を選択(任意)

    チェックシートの左側に表示したい画像ファイル(参考書の表紙など)をドラッグ&ドロップするか、エリアをクリックして選択します。画像は必須ではありません。選択しない場合はデフォルトのイメージが表示されます。
    ※画像はブラウザ上のみで処理され、サーバーには送信されません。

  2. ページ数を入力

    チェックシートで管理したい「開始ページ」と「終了ページ」を入力します。例えば、参考書の10ページから150ページまでを管理したい場合は、開始に「10」、終了に「150」と入力します。入力すると、チェックシートのプレビューが自動で更新されます。

  3. 生成された画像をダウンロード

    プレビューで確認し、問題がなければ「画像をダウンロード」ボタンをクリックします。作成されたチェックシートがPNG画像としてダウンロードされるので、あとはプリンターで印刷するだけです!

活用メリットとアイデア

「進捗チェックシートメーカー」は、単にページ進捗を管理するだけでなく、様々なメリットや活用方法があります。

  • 達成感の可視化: 一つ一つチェックマークを付けていくことで、目に見える形で進捗を実感でき、達成感が得られます。特に長い道のりでは、この小さな成功体験の積み重ねが重要です。
  • モチベーション維持: 「あとこれだけ進んだ」「目標まであと少し」といった具体的な感覚が、学習を続ける上でのモチベーションに繋がります。
  • 学習習慣の確立: シートを壁に貼ったり、手帳に挟んだりして常に目に入る場所に置くことで、学習を意識しやすくなり、習慣化を助けます。
  • タスク管理にも応用可能: ページ数の代わりにタスクの項目数を設定すれば、日々のタスクリストや習慣化したいこと(例:30日間チャレンジなど)のチェックシートとしても使えます。
  • デジタルデトックス: PCやスマホから離れ、紙とペンで記録することで、集中力を高めたり、デジタル疲れを軽減したりする効果も期待できます。
  • 計画の見直し: 進捗が遅れている場合や、逆に早く進んでいる場合に、計画を見直すきっかけにもなります。

例えば、お子さんのドリル学習の管理、趣味の編み物や手芸の工程管理、長編映画やドラマシリーズの視聴記録など、アイデア次第で幅広くご活用いただけます。

仕組みについて(安心設計)

この「進捗チェックシートメーカー」は、特別なソフトウェアをインストールすることなく、お使いのウェブブラウザだけで全ての機能が動作します。
表紙画像の処理やチェックシートの描画は、すべてお手元のコンピュータやスマートフォンのブラウザ内部で行われます。そのため、選択した画像データが外部のサーバーに送信されることは一切なく、プライバシーの面でも安心してご利用いただけます。
技術的には、ブラウザの描画機能(Canvas API)を活用して、入力された情報に基づいてリアルタイムにチェックシート画像を生成しています。

まとめ

「進捗チェックシートメーカー」は、地道な努力が必要な学習や目標達成において、あなたの「頑張り」を形にし、継続を後押しするためのシンプルなツールです。
デジタル全盛の時代だからこそ、手書きのチェックがもたらす温かみや達成感を、ぜひ体験してみてください。
このツールが、皆さんの目標達成の一助となれば幸いです。

▶︎ 進捗チェックシートメーカー(印刷用)

ご意見やご感想、改善点などありましたら、ぜひお聞かせください。

Next.jsサイトをCloudflare Pagesにデプロイ!独自ドメイン設定までの完全ガイド

この記事では、人気フレームワーク「Next.js」で作成したWebサイトを、高機能なホスティングサービス「Cloudflare Pages」へデプロイし、さらにオリジナルの独自ドメイン(例: your-domain.com)を設定するまでの全手順を、初心者の方にも分かりやすく、ステップバイステップで解説する完全ガイドです。

Next.jsのデプロイ先としては開発元のVercelが有名ですが、Cloudflare Pagesも非常に有力な選択肢です。Cloudflareが提供する高速なCDN、強力なセキュリティ機能、そして余裕のある無料枠といったメリットがあり、個人開発から小~中規模のWebサイトまで幅広く活用できます。今回は、筆者がよく利用するCloudflare Pagesへのデプロイ方法をご紹介します。

※この手順は、作成したNext.jsプロジェクトのコードが、GitHub(またはGitLab)のリポジトリ(プライベートでも可)にプッシュ(保存)されていることを前提としています。


この記事で解説する手順

  1. Cloudflare PagesにNext.jsプロジェクトを追加する
  2. GitHubプライベートリポジトリへのアクセス許可を設定する
  3. Next.js用のビルド設定と注意点 (Node.jsバージョン, 互換フラグ)
  4. Cloudflare Pagesに独自ドメインを設定する (ネームサーバー変更)
  5. まとめ:Next.js + Cloudflare Pages + 独自ドメイン設定の流れ

Cloudflare PagesにNext.jsプロジェクトを追加する

まず最初のステップとして、Cloudflareの管理画面(ダッシュボード)で新しいPagesプロジェクトを作成し、デプロイしたいNext.jsプロジェクトのGitHubリポジトリと連携させます。

1. Cloudflareダッシュボードにログインし、左側のメニューから「Workers & Pages」セクションを選択します。(※CloudflareのUIは頻繁に更新されるため、メニュー名が若干異なる場合があります。類似の項目を探してください。)

CloudflareダッシュボードのWorkers & Pagesメニュー

2. 表示された画面の「概要」タブなどで、「アプリケーションを作成」ボタンを見つけてクリックします。

アプリケーションを作成ボタン

3. 「アプリケーションを作成」画面が開いたら、「Pages」タブが選択されていることを確認し、「Gitに接続」ボタンをクリックします。Cloudflare PagesはGitリポジトリと連携して自動デプロイを行うのが基本です。

Pagesタブを選択し、Gitに接続ボタンをクリック

4. GitHubまたはGitLabアカウントとの連携画面に進みます。初めて連携する場合は、「アカウントを追加」ボタンをクリックし、画面の指示に従ってGitHubアカウントを認証し、Cloudflareからのアクセスを許可します。

5. アカウント連携が完了すると、「リポジトリを選択」セクションに、連携したアカウントのGitリポジトリ一覧が表示されます。この中から、デプロイしたいNext.jsプロジェクトのリポジトリを選択してください。

GitHubリポジトリの選択画面

GitHubプライベートリポジトリへのアクセス許可を設定する

【ポイント】 もしデプロイしたいリポジトリがプライベート(非公開)設定の場合、上記のリポジトリリストに表示されないことがあります。これは、Cloudflare Pagesアプリケーションがそのプライベートリポジトリにアクセスする権限を持っていないためです。その場合は、以下の手順でGitHub側でアクセス許可を与える必要があります。

1. GitHubにログインし、右上のアイコンから「Settings」(設定)を開き、左側メニューの「Applications」(アプリケーション)を選択します。

GitHub設定画面のApplicationsメニュー

2. 「Installed GitHub Apps」タブを選択し、リストの中から「Cloudflare Pages」(または類似の名前)を見つけてクリックします。

Installed GitHub Apps内のCloudflare Pages

3. 「Repository access」(リポジトリへのアクセス)セクションまでスクロールします。ここで、「Only select repositories」(選択したリポジトリのみ)オプションを選択し、表示されるリポジトリリストの中から、Cloudflare PagesにデプロイしたいNext.jsプロジェクトのリポジトリにチェックを入れます。最後に「Save」ボタンを押して変更を保存します。

【セキュリティ推奨】もしここが「All repositories」(すべてのリポジトリ)になっていた場合でも、セキュリティの観点から、必要なリポジトリのみにアクセスを限定する「Only select repositories」に変更することをお勧めします。

Repository access設定でリポジトリを選択

4. このGitHub側の設定が完了したら、Cloudflare Pagesの画面に戻り、リポジトリ選択のリストを更新(またはページを再読み込み)すると、先ほどアクセスを許可したプライベートリポジトリが表示されるはずです。目的のリポジトリを選択し、「セットアップを開始」ボタンをクリックして次のステップに進みます。

リポジトリを選択してセットアップを開始

Next.js用のビルド設定と注意点 (Node.jsバージョン, 互換フラグ)

リポジトリを選択すると、次にビルド設定とデプロイに関する設定画面が表示されます。Cloudflare PagesがGitHubリポジトリからコードを取得し、どのようにビルドしてデプロイするかをここで指定します。

1. 「ビルド設定」セクションにある「フレームワーク プリセット」のドロップダウンメニューを開き、「Next.js」を選択します。Cloudflare Pagesは多くのフレームワークに対応しており、プリセットを選択すると、そのフレームワークに最適なビルドコマンドや設定が自動的に入力されるため便利です。

フレームワークプリセットでNext.jsを選択

2. プリセットを選択すると、「ビルドコマンド」(例: `npm run build` や `next build`)や「ビルド出力ディレクトリ」(例: `.next` や `.vercel/output/static`。Next.jsのバージョンや設定により異なる場合があります)が自動的に入力されます。通常はこのままで問題ありません。

自動設定されたビルドコマンドと出力ディレクトリ

【注意点1】Node.jsバージョンの指定が必要な場合

基本的な設定は以上ですが、このまま「保存してデプロイする」をクリックすると、ビルド時にエラーが発生することがあります。よくある原因の一つが、Cloudflare Pagesのビルド環境で使用されるNode.jsのバージョンが、あなたのNext.jsプロジェクトが必要とするバージョンよりも古い場合です。

ビルドログを確認し、以下のようなエラーメッセージが表示されていたら、Node.jsのバージョン指定が必要です。

Initializing build environment. Failed: error finding node version '>=18.0.0'
You are using Node.js 18.17.1.
For Next.js, Node.js version "^18.18.0 || ^19.8.0 || >= 20.0.0" is required.

(上記はエラーメッセージの例です。バージョン番号は異なる場合があります)

このエラーを解決するには、Cloudflare Pagesのプロジェクト設定で、使用するNode.jsのバージョンを明示的に指定します。

プロジェクトの「設定」>「環境変数」を開き、「ビルド環境変数」セクション(または「実稼働/プレビュー環境変数」の両方)で「変数を追加」をクリックし、以下のように設定します。

  • 変数名: NODE_VERSION
  • 値: あなたのNext.jsプロジェクトが必要とするNode.jsのバージョン番号を指定します(例: 18.18.020.0.0 など。エラーメッセージやNext.jsのドキュメント、ローカル開発環境に合わせてください)。package.json の `engines` フィールドで指定している場合は、それに合わせるのが良いでしょう。

環境変数でNODE_VERSIONを指定

環境変数を設定した後、再度デプロイ(ビルドログ画面などから「デプロイを再試行」)を行うと、指定したNode.jsバージョンが使用され、ビルドが正常に完了するはずです。

【注意点2】Node.js互換フラグの設定が必要な場合

ビルドは成功したものの、デプロイされたサイト(xxx.pages.dev)にアクセスすると、以下のようなエラー画面が表示される場合があります。

Node.JS Compatibility Errorの画面

これは「Node.JS Compatibility Error」と呼ばれるもので、Cloudflare Pagesの実行環境(Cloudflare Workers)でNext.jsアプリケーション(特にサーバーサイドの機能やAPIルートなど)を正しく動作させるために、Node.jsのAPI互換モードを有効にする必要があることを示しています。

このエラーを解決するには、以下の設定を行います。

プロジェクトの「設定」>「関数」>「互換性フラグ」セクション(または「互換性設定」など類似の項目)を見つけます。「フラグを設定」(または「追加」)ボタンをクリックし、「nodejs_compat」というフラグを追加して保存します。(通常、実稼働環境とプレビュー環境の両方に設定します)

互換性フラグにnodejs_compatを設定

このフラグを設定し、再度デプロイが完了した後、サイトにアクセスすると、Next.jsアプリケーションが正常に表示されるはずです。

Cloudflare Pagesに独自ドメインを設定する (ネームサーバー変更)

ビルドとデプロイが成功し、プロジェクト名.pages.dev のようなURLでサイトが表示されるようになったら、最後のステップとして、あなたが所有する独自ドメイン(例: your-cool-site.com)をこのCloudflare Pagesプロジェクトに割り当てます。

独自ドメインを設定する大まかな流れは以下の通りです。

  1. Cloudflare Pages側での設定: プロジェクトの設定画面で、使用したい独自ドメイン名を追加します。
  2. ネームサーバー情報の確認: Cloudflareから、あなたのドメインに設定すべきネームサーバーのアドレスが指示されます。
  3. ドメインレジストラ側での設定: あなたがドメインを取得したサービス(例: お名前ドットコム, Google Domains, Route 53など)の管理画面で、ドメインのネームサーバー設定を、Cloudflareから指示されたものに変更します。
  4. DNS反映待ち: ネームサーバー変更の情報がインターネット全体に行き渡る(DNSが伝播する)のを待ちます。通常は数分から数時間ですが、最大で48時間程度かかることもあります。
  5. Cloudflare Pages側での有効化: Cloudflareがネームサーバーの変更を確認できたら、ドメインが「アクティブ」状態になり、Pagesプロジェクトと独自ドメインが接続されます。

以下では、ドメインレジストラとして「お名前ドットコム」を使用した場合の具体的な手順例を示します。(基本的な流れは他のレジストラでも同様です)

ステップ1:Cloudflare Pagesにカスタムドメインを追加

1. Cloudflare Pagesのプロジェクト画面に戻り、「カスタムドメイン」タブを選択し、「カスタムドメインを設定」ボタンをクリックします。

カスタムドメインを設定ボタン

2. テキストボックスに、設定したいあなたの独自ドメイン名(例: your-cool-site.com)を入力し、「続行」をクリックします。

設定したいドメイン名を入力

3. もしまだそのドメインがCloudflareで管理されていない場合は、CloudflareにドメインのDNS管理を移管(または部分的に委任)するプロセスが開始されます。画面の指示に従い、「DNS転送を開始」や「サイトを追加」のようなボタンをクリックします。(※これはドメイン自体をCloudflareに移管するのではなく、あくまでDNSの管理権限をCloudflareに向ける設定です)

DNS転送を開始ボタン

4. ドメイン名を入力し、Cloudflareが既存のDNSレコードをスキャンするプロセスに進みます。「Continue」をクリックします。

DNSレコードのスキャン開始画面

5. Cloudflareのプラン選択画面が表示されます。独自ドメインの利用だけであれば、通常は画面下部にある「Freeプラン」(無料プラン)を選択して「Continue」をクリックすれば十分です。

Freeプランを選択

6. Cloudflareがスキャンした現在のDNSレコードが表示されます(もしあれば)。内容を確認し(分からなければそのままでもOK)、「Continue」をクリックします。

DNSレコードのスキャン結果画面

7. 確認のポップアップが出たら「Confirm」をクリックします。

確認ポップアップ

8. 【重要】 この画面で、あなたのドメインに設定すべきCloudflareのネームサーバーアドレス(通常は2つ)が表示されます。これらのアドレス(例: `ada.ns.cloudflare.com`, `ben.ns.cloudflare.com` など)を正確にコピーまたはメモしておきます。これが次のステップで必要になります。

表示されたCloudflareのネームサーバーアドレス

ステップ2:ドメインレジストラでネームサーバーを変更

次に、あなたのドメインを取得・管理しているサービス(ドメインレジストラ)の管理画面にログインし、ネームサーバーの設定を変更します。

1. ドメインレジストラ(この例では「お名前ドットコム」)のウェブサイトにアクセスし、ログインします。

2. ドメイン管理メニューの中から、対象ドメインの「ネームサーバー設定」や「DNS設定」といった項目を探し、編集画面を開きます。

3. レジストラの現在のネームサーバー設定(通常はレジストラ自身のネームサーバーが設定されています)を削除または変更し、先ほどCloudflareから指示された2つのネームサーバーアドレスを入力・保存します。(入力欄が複数ある場合は、指示された2つを入力し、残りは空欄にするか、レジストラの指示に従います)

お名前ドットコムでのネームサーバー変更画面例

【注意】DNSの伝播には時間がかかります!

ネームサーバーの変更設定がインターネット全体に行き渡る(DNSが伝播する)までには、時間がかかります。早ければ数分で反映されることもありますが、通常は数時間、場合によっては最大で48時間程度かかることもあります。この間は、独自ドメインでサイトにアクセスできなかったり、古い情報が表示されたりすることがありますので、焦らず気長に待ちましょう。Cloudflareのダッシュボードで定期的にステータスを確認するか、Cloudflareから届く確認メールを待ちます。

Cloudflareからのネームサーバー更新完了通知メール例

ステップ3:Cloudflare Pagesでドメインを有効化

ネームサーバーの変更がCloudflare側で無事に認識されると、Cloudflareダッシュボードのドメイン管理画面で、該当ドメインのステータスが「保留中」から「アクティブ」に変わります。(今回は比較的早く、5分程度で反映されました)。

Cloudflareでドメインがアクティブになった状態

ドメインがアクティブになったら、いよいよCloudflare Pagesプロジェクトと独自ドメインを正式に接続します。

1. 再度、Cloudflare Pagesのプロジェクト設定画面に戻り、「カスタムドメイン」タブを開きます。

2. 「カスタムドメインを設定」ボタンをクリックし、もう一度あなたの独自ドメイン名を入力して「続行」します。

3. 今度はCloudflareがドメインを認識しているため、「ドメインをアクティベート」や「DNSレコードを確認」といった画面が表示されるはずです。Cloudflare Pagesが必要とするDNSレコード(通常はCNAMEレコード)が自動で設定(または提案)されます。内容を確認し、「ドメインをアクティベート」ボタンをクリックします。

カスタムドメインのアクティベート画面

4. ステータスが「初期化中」や「認証中」などと表示され、しばらく待つと最終的に「アクティブ」に変わります。これで設定は完了です!

設定が完了すると、あなたの独自ドメイン(例: https://your-cool-site.com)にアクセスすると、Cloudflare PagesにデプロイされたNext.jsサイトが表示されるようになります。(SSL証明書もCloudflareが自動で発行・管理してくれます)

カスタムドメインがアクティブになった状態

まとめ:Next.js + Cloudflare Pages + 独自ドメイン設定の流れ

以上が、Next.jsサイトをCloudflare Pagesにデプロイし、独自ドメインを設定するまでの一連の手順でした。全体の流れをもう一度おさらいしましょう。

  1. GitHub準備: Next.jsプロジェクトをGitHubリポジトリにプッシュする。
  2. Cloudflare Pages連携: Cloudflare Pagesでプロジェクトを作成し、GitHubリポジトリと連携する。(プライベートリポジトリの場合はGitHub側でアクセス許可設定を行う)
  3. ビルド設定とエラー対応:
    • フレームワークプリセットで「Next.js」を選択。
    • 必要に応じて、環境変数 `NODE_VERSION` でNode.jsバージョンを指定する。
    • 必要に応じて、互換性フラグ `nodejs_compat` を設定する。
  4. 独自ドメイン設定:
    • Cloudflare Pagesにカスタムドメインを追加し、指示されたCloudflareのネームサーバーを確認する。
    • ドメインレジストラの管理画面で、ネームサーバーをCloudflareのものに変更する。
    • DNSの伝播を待ち、Cloudflareでドメインがアクティブになったら、Pagesプロジェクトでドメインを有効化する。

ビルド時のNode.js関連のエラーや、DNS設定の反映待ち時間など、いくつか注意すべき点はありますが、手順自体は比較的シンプルに進められます。Cloudflare Pagesは、高速な配信、強力なセキュリティ、そして手厚い無料枠を提供しており、Next.jsアプリケーションのホスティング先として非常に魅力的な選択肢です。ぜひこのガイドを参考に、デプロイに挑戦してみてください。

(※この記事では基本的なデプロイ手順を解説しました。実際のアプリケーションの要件によっては、環境変数の設定、カスタムビルドコマンド、リダイレクトルールなど、さらに詳細な設定が必要になる場合があります。その際はCloudflare Pagesの公式ドキュメント等も合わせて参照してください。)

【VRChat】アバター最適化でVery Poor脱出!Mantis & MeshDeleterでポリゴン削減してPoorにする方法

VRChatで使用しているアバターのパフォーマンスランクが「Very Poor」になってしまうことがあります。Very Poorランクは、ワールドによっては表示が制限されたり、他ユーザーへの負荷となる可能性も指摘されており、可能な範囲での最適化が推奨されています。

今回は、Unityのツール「Mantis LOD Editor」と「MeshDeleterWithTexture」を用いて、アバターのポリゴン数を削減し、パフォーマンスランクを「Very Poor」から「Poor」へ改善することができたため、その手順と方法を記録としてまとめます。

【最適化結果:ビフォーアフター】

最適化前: 188,784ポリゴン / パフォーマンスランク: Very Poor

最適化前のアバター(Very Poorランク)

最適化後: 69,995ポリゴン / パフォーマンスランク: Poor

最適化後のアバター(Poorランク)

上記のように、見た目への影響を最小限に抑えつつ、ポリゴン数を63%削減することに成功しました!

具体的には、以下の方法でポリゴン数を効果的に削減しました。これらのテクニックは、アバター改変や自作モデル制作においても重要になると思われます。

  • 隠れたパーツの削除: 服の下で見えない体の一部(肘など)のメッシュを削除。
  • Mantis LOD Editorによる削減: 各パーツ(服、髪、小物など)のポリゴン数を、見た目が崩れない範囲で削減。
  • MeshDeleterWithTextureによる部分削除: 服の不要な装飾や、さらに隠れた部分のメッシュをテクスチャ指定で削除。
  • (応用)MeshDeleterによるパーツ分離: 複合パーツ(例:インナーとアウターが一体化した服)を分離し、それぞれ個別に最適化。

この記事では、これらの手順を順番に解説していきます。


この記事の内容

  1. 最適化に必要なツールと準備
  2. 知っておくと便利な専門用語(非破壊的, NDMF)
  3. Mantis LOD Editorを使ったポリゴン削減の基本
  4. Mantisだけでは難しいケースと課題
  5. MeshDeleterWithTextureを使った部分的なメッシュ削除
  6. 応用テクニック:MeshDeleterで服パーツを分離する
  7. まとめ:Very Poor脱出!最適化の成果とポイント
  8. 参考にさせていただいた情報
  9. 追記:ハイエンドモデル最適化の限界と注意点 (2025年4月)

最適化に必要なツールと準備

今回のVRChatアバター最適化(ポリゴン削減)で使用した主なツールは以下の通りです。

  • Mantis LOD Editor – Professional Edition (Unity Asset Store / 有料: 約$55)
    • 高品質なポリゴン削減(リダクション)機能を持つ定番のUnityアセット。アバターの各パーツのポリゴン数を効率的に減らせます。購入後、UnityのPackageManager > My Assetsからインポートします。
  • 【非破壊でポリゴン削減】Mantis LOD EditorのNDMF化ツール (Booth: ひつぶさん作 / 無料 ※Mantis LOD Editor本体が必要)
    • 上記のMantis LOD Editorを、VRChatアバター改変で広く使われているフレームワーク「NDMF(なでもふ)」上で、より安全かつ簡単に(非破壊的に)利用できるようにするツール。Boothからダウンロードし、unitypackageをインポートします。実際にアバターに適用するのはこちらです。
  • MeshDeleterWithTexture beta (Booth: がとーしょこらさん作 / 無料)
    • テクスチャ画像上で範囲を指定することで、対応するメッシュ部分を削除(実際には新しいメッシュを生成)できる非常に便利なUnityエディタ拡張。Mantisでは難しい、服の細かい装飾の削除や、隠れた部分のメッシュ除去に役立ちます。Boothからダウンロードし、unitypackageをインポートします。
  • anatawa12’s VRC Avatar Tools (旧: gists pack) (VCC経由で導入可能)
    • アバターのパフォーマンス統計情報を詳細に表示する機能などが含まれるツール群。特に「Actual Performance」タブは、最適化作業中の現在のポリゴン数やパフォーマンスランクをリアルタイムで確認するために必須です。VCC (VRChat Creator Companion) の「Manage Project」から簡単に追加できます。

【重要】Actual Performanceタブでの確認方法:

anatawa12’s VRC Avatar Toolsを導入すると、VRChat SDK Control Panelに「Avatars」タブが追加され、その中に「Actual Performance」という項目が表示されます。MantisやMeshDeleterで最適化を行った後、Unityを再生モード(Play Mode)にすると、このタブの情報が更新され、最新のポリゴン数やパフォーマンスランクを確認できます。目標は、ここの「Polygons」の数値を70,000以下にすることです(Poorランクの上限)。

VCCでanatawa12's VRC Avatar Toolsを追加する画面

Actual Performanceタブでポリゴン数とランクを確認

(↑この例では188,784ポリゴンでVery Poor。目標は70,000ポリゴン以下!)

知っておくと便利な専門用語(非破壊的, NDMF)

アバター最適化を進める上で、いくつか知っておくと理解が深まる用語があります。

  • 非破壊的 (Non-Destructive)
    元のデータを直接書き換えずに行う編集方法のこと。今回使うNDMF版MantisやMeshDeleterは、元のメッシュデータを保持したまま処理を行うため、「非破壊的」です。つまり、設定を間違えたり、結果が気に入らなかったりした場合でも、ツール(コンポーネント)を削除したり設定を戻したりするだけで、簡単に元の状態に戻すことができます。初心者でも安心して試せる大きなメリットです。
  • NDMF (Nade Nadenadeshiko Mod Fwk / なでもふ)
    VRChatアバター改変のためのフレームワーク(仕組み)の一つ。アバターの色々な設定や改変を「コンポーネント」として管理し、それらをビルド時に自動で適用してくれます。非破壊的な改変と相性が良く、多くの便利ツールがNDMFに対応しています。今回使う「Mantis LOD EditorのNDMF化ツール」もその一つです。

Mantis LOD Editorを使ったポリゴン削減の基本

VRChat SDKのValidation画面でポリゴン超過パーツを特定

まずは、アバターの中でどのパーツがポリゴン数を増やしている主犯なのかを特定しましょう。

1. UnityでVRChat SDK Control Panelを開き、「Builder」タブを選択します。

2. アバターを選択した状態でビルドを実行しようとすると、パフォーマンスに関する警告(Validation Results)が表示されます。「Polygons」に関する警告メッセージの横にある「Select」ボタンをクリックすると、ポリゴン数が特に多いメッシュ(衣装パーツなど)がHierarchyウィンドウでハイライトされます。

3. ハイライトされたオブジェクト(衣装パーツなど)に、「NDMF Mantis LOD Editor」コンポーネントを追加します。(Inspectorウィンドウで「Add Component」し、”Mantis”で検索すると見つかります)

4. 追加されたコンポーネントの「Quality」スライダーを調整します。この数値を下げるほどポリゴン数が削減されますが、下げすぎるとメッシュの形が崩れてしまいます。

NDMF Mantis LOD EditorコンポーネントのQualityスライダー

【ポイント】Shaded Wireframe表示を活用しよう

Qualityスライダーを調整する際は、Unityのシーンビュー表示を「Shaded Wireframe」に切り替えると、ポリゴンの削減具合やメッシュの崩れ具合が視覚的に分かりやすくなります。「Shaded」表示と適宜切り替えながら、見た目を損なわないギリギリのラインを探っていきましょう。

Shaded Wireframe表示でポリゴンを確認

この「パーツ特定 → コンポーネント追加 → Quality調整」を、ポリゴン数が多いパーツに対して繰り返していくのが基本的な流れです。

【重要】使わないパーツは完全に削除しよう

アバター改変をしていると、「元の服や髪型も、いつか使うかもしれないから一応残しておこう」と、非表示にしただけでHierarchyに残してしまうことがあります。しかし、非表示にしただけのメッシュもポリゴン数としてカウントされてしまう場合があります!

今回の私のアバターも、元のマヌカちゃんのエプロンパーツなどを非表示で残していましたが、これらをHierarchyから完全に削除したところ、約16,000ポリゴンも削減できました。

使わないパーツは思い切って削除しましょう。もし後で必要になった場合は、元のアバターや衣装のunitypackageを再インポートすれば簡単に戻せます。

Hierarchyから不要なパーツを削除する

(参考: UnityだけでVRChatアバターのVeryPoorを脱出する方法|こはだ 様

【注意】顔と素体のポリゴン削減は慎重に!

顔周りの細かいメッシュ構造

Mantisでのポリゴン削減は効果的ですが、アバターの「顔」と「素体(Body)」のメッシュは、原則として削減しない方が無難です。

特に顔周りは、豊かな表情を作るために非常に多くの細かいポリゴン(メッシュ)で構成されています。口周りのポリゴンはリップシンク(口パク)の様々な形に対応するため、目周りのポリゴンはまばたきや感情表現のために必要です。

これらの部分をMantisで安易に削減してしまうと、喋るたびに口が破綻したり、表情が崩壊したりする可能性が非常に高くなります。同様に、素体の関節部分なども、削減するとポーズを取ったときに不自然な見た目になりやすいです。

ポリゴン削減は、主に服、髪、アクセサリーなどのパーツで行い、顔と素体はできるだけ元の状態を保つようにしましょう。

【判断】時にはデザイン的な妥協も必要

尻尾パーツの削減前後の比較

どうしても目標のポリゴン数(Poorランクの70,000ポリゴン)に収まらない場合、デザインの一部を諦めるという判断が必要になることもあります。

今回のアバターでは、尻尾パーツのポリゴン数をMantisである程度削減しましたが、それでも目標達成が難しかったため、最終的に尻尾パーツ自体を削除する決断をしました。もちろん残念ですが、パフォーマンスランク改善のためには、こうしたトレードオフが必要になる場合もあります。

Mantisだけでは難しいケースと課題

Mantis LOD Editorは非常に優秀なツールですが、最適化を進める中で、Mantisだけでは対応が難しい、あるいは効率が悪いと感じる場面が出てきました。

  • 複合パーツの削減限界: インナーとアウターが一体化している服など、一つのオブジェクトに複数の部位が含まれている場合、Mantisで削減すると、先にポリゴン数が少ない部分(例: インナー)が破綻してしまい、ポリゴン数が多い部分(例: アウター)を十分に削減できないことがある。パーツを分離して個別に削減したい。
  • 隠れたメッシュの残り: 服の下に隠れている素体の一部(例: お腹周り)を非表示にしてもメッシュが残り、ポリゴン数に含まれてしまう。この隠れた部分だけを削除したい。
  • 部分的な装飾の削除: 服の特定の部分(ポケット、ベルト、フリルなど)だけを削除してポリゴン数を稼ぎたいが、Mantisでは全体的な削減しかできない。

これらの課題を解決するために役立つのが、「MeshDeleterWithTexture beta」です。

最適化前の体メッシュ(服で隠れている部分も表示)

(↑例えば、服の下に隠れているこのお腹部分のメッシュを削除したい)

服を非表示にした状態。腹部のメッシュが残っている

MeshDeleterWithTexture betaを使った部分的なメッシュ削除

MeshDeleterWithTexture beta」は、その名の通り、テクスチャ画像上で指定した範囲に対応するメッシュ部分を削除(正確には、削除した新しいメッシュを生成)してくれる画期的なツールです。

使い方は非常に直感的です。

1. がとーしょこらさんのBoothからunitypackageをダウンロードし、プロジェクトにインポートします。

2. Unityメニューバーに「GotoTools」という項目が追加されるので、「MeshDeleter with Texture」を選択して専用ウィンドウを開きます。

MeshDeleter with Textureのメニュー

3. ウィンドウ上部の「Renderer」という欄に、メッシュを削除したいオブジェクト(例: 体のメッシュを持つオブジェクト)をHierarchyウィンドウからドラッグ&ドロップします。

4. オブジェクトに設定されているテクスチャ画像がウィンドウ内に表示されます。

5. 画面右側の「Draw Type」から「PEN」などを選択し、テクスチャ上で削除したい部分(例: 服で隠れるお腹の部分)を黒く塗りつぶします。塗りつぶした部分は、シーンビュー上のモデルにもリアルタイムで反映され、削除される範囲を確認できます。

MeshDeleterでテクスチャのお腹部分を黒く塗りつぶす

6. 削除範囲を確認したら、「DeleteMesh」ボタンをクリックします。これで、指定した部分が削除された新しいメッシュが生成され、オブジェクトに自動で適用されます。

MeshDeleter実行後、お腹部分のメッシュが削除された状態

【ポイント】MeshDeleterも非破壊的!

このツールも「非破壊的」で、元のメッシュデータはプロジェクト内に残っています。もし削除範囲を間違えたり、元に戻したくなったりした場合は、オブジェクトのMesh Renderer(またはSkinned Mesh Renderer)コンポーネントで、Meshの指定を元のファイルに戻すだけでOKです。安心して試せますね。

生成された新しいメッシュが適用されているInspector画面

この方法で、服の下に隠れていた腹部メッシュを削除したところ、約1,000ポリゴン削減できました。さらに、残った部分にMantis LOD Editorを適用して、より効率的にポリゴンを削減することも可能です。

応用テクニック:MeshDeleterで服パーツを分離する

最適化対象のテックウェア(インナーとアウターが一体)

MeshDeleterの「テクスチャ範囲指定でメッシュを削除する」機能は、応用することで一体化している服パーツを分離するのにも使えます。

今回使用したテックウェア(約60,000ポリゴン)は、コート部分(アウター)と上半身のインナーが同じ一つのオブジェクト(メッシュ)として作られていました。このままだと、Mantisで削減しようとしても、ポリゴン数の少ないインナー部分が先に破綻してしまい、ポリゴン数の多いコート部分を十分に削減できませんでした。

そこで、MeshDeleterを使って「インナーだけのメッシュ」と「アウターだけのメッシュ」を擬似的に作り出すことにしました。

【パーツ分離手順】

1. 元のテックウェアオブジェクトをHierarchy上で複製(Ctrl+D または Cmd+D)し、それぞれ「インナー用」「アウター用」など分かりやすい名前に変更します。

2. 「インナー用」オブジェクトを選択し、MeshDeleterウィンドウを開きます。

3. テクスチャ上で、アウター(コート)に対応する部分をすべて黒く塗りつぶし、「DeleteMesh」を実行します。これにより、インナー部分だけが残ったメッシュが生成されます。

インナー用オブジェクトでコート部分を塗りつぶす

インナー部分だけのメッシュが完成

4. 同様に、「アウター用」オブジェクトを選択し、MeshDeleterウィンドウで今度はインナーに対応する部分をすべて黒く塗りつぶし、「DeleteMesh」を実行します。これにより、アウター(コート)部分だけが残ったメッシュが生成されます。

アウター用オブジェクトでインナー部分を塗りつぶす

これで、もともと一体だった服を「インナー」と「アウター」の2つのメッシュに分離できました。Blenderなどの外部モデリングソフトを使わずに、Unity上だけでパーツを分離できるのは非常に便利です。

分離後は、それぞれのパーツ(インナー、アウター)に個別にNDMF Mantis LOD Editorを適用し、より効果的にポリゴン数を削減していくことが可能になります。

まとめ:Very Poor脱出!最適化の成果とポイント

以上の方法を用いた結果、最初に18万ポリゴンあったVeryPoorランクのアバターを、69,995ポリゴンのPoorランクに改善することができました。

最終的なポリゴン数(69995)とPoorランクの表示

最終的に目標の70,000ポリゴン以下に収めるために、服の装飾削除やコートのポリゴン削減など、デザイン面での調整も行いました。見た目を維持しながらポリゴン数を削減する作業は、試行錯誤が必要ですが、非常に良い練習になったと感じています。

最適化後のアバターの外観(見た目の劣化は最小限)

今回使用した「Mantis LOD Editor (NDMF版)」と「MeshDeleterWithTexture beta」は、どちらも非破壊的なツールであるため、初心者でも比較的安心して試すことができます。「いつでも元に戻せる」という点は、最適化作業を進める上での大きな心理的な支えになります。

Mantisの強力なポリゴン削減能力と、MeshDeleterの柔軟な部分編集・応用力を組み合わせることで、Very Poorランクのアバターも効果的に最適化できる可能性が高まります。

VRChatアバターのポリゴン数でお悩みの方は、ぜひこの記事で紹介したツールと手順を参考に、最適化に挑戦してみてください。(なお、パフォーマンスランクにはポリゴン数以外にもマテリアル数などが影響するため、総合的な最適化を目指す場合はそちらも考慮が必要です)

参考にさせていただいた情報

今回のアバター最適化(ポリゴン削減)にあたり、以下の記事や動画を大変参考にさせていただきました。素晴らしい情報をありがとうございます。


追記:ハイエンドモデル最適化の限界と注意点 (2025年4月)

この記事ではVery PoorランクのアバターをPoorランクに改善する手順を紹介しましたが、すべてのケースで同様の最適化が最善とは限らない点について追記します。特に、元のポリゴン数が非常に多い、いわゆる「ハイエンドモデル」の最適化には注意が必要です。

これらのモデルは、ディテールに富んだ装飾や複雑な衣装、多くのギミックなどが魅力ですが、その分ポリゴン数が膨大(10万ポリゴンをはるかに超えることも珍しくありません)です。このようなモデルに対してMantis LOD Editorなどでポリゴン削減を行うと、わずかな削減率でも見た目のディテールが失われ、モデル本来の魅力が大きく損なわれてしまう可能性があります。

Poorランクの規定(7万ポリゴン)を少しオーバーしている程度のアバター(例えば7万~10万ポリゴン程度)や、もともとシンプルなデザインのデフォルメモデルなどであれば、この記事で紹介した方法は有効でしょう。しかし、規定の倍以上、例えば15万、20万ポリゴンを超えるようなハイエンドモデルを、見た目を維持したままPoorランクまで無理に削減しようとすることは、多くの場合困難であり、あまり推奨できません。

では、どうすれば良いかというと、無理に一つのモデルを極端に最適化するのではなく、用途に応じた使い分けを検討するのが現実的です。

  • 通常利用: メインのアバターは、最適化せず元のクオリティのまま使用する。
  • 軽量化が必要な場面: 大人数が集まるイベントや、パフォーマンスが重視される特定のワールドに参加する際には、別途軽量化されたバージョン(Quest対応版などが用意されている場合もあります)を用意するか、あるいは最初から軽量な別のアバターを使用する

【筆者の体験談と反省】

実を言うと、今回Poorランク(69,995ポリゴン)まで最適化したマヌカ改変モデルですが、しばらく使ってみて、少し考えが変わりました。確かに軽量化には成功したのですが、その過程で服の細かい装飾などを一部削除してしまったことに対し、「そこまでして最適化する必要があったかな?」という気持ちが後から出てきました。

また、私自身のVRChatのプレイスタイルとして、パフォーマンスが非常にシビアなワールドに頻繁に参加するわけではなかったため、「このモデルに関しては、Very Poorのままでも大きな支障はなかったかもしれない」というのが正直なところです。

アバターの最適化は、VRChatを快適に楽しむ上で重要な要素の一つですが、それが常に必須というわけではありません。ご自身のプレイスタイルや参加するコミュニティ、そして「どの程度の見た目の変化なら許容できるか」をよく考慮した上で、最適化を行うかどうか、どのレベルまで行うかを判断することが大切だと思います。

Google Analytics Data APIで静的ブログサイトに『人気記事一覧』を実装する方法【Next.js / Gatsby.js】

JAMstack構成(例: Next.jsGatsby.js + ヘッドレスCMS)は、フロントエンドとバックエンドを分離することで、使用する技術選択の自由度が高く、パフォーマンスやセキュリティ面でのメリットも大きいモダンなWebサイト構築のアプローチです。

しかし、その一方で、従来のWordPressサイトなどではプラグインで簡単に実現できた機能、例えば「人気記事一覧(ランキング)」などを実装しようとすると、少し工夫が必要になります。

WordPressで人気記事一覧が容易なのは、記事データとページ閲覧数(PV数)が同じデータベース内に記録されており、動的にデータを取得・集計してランキング表示できるためです。しかし、JAMstack構成の多くは、ビルド時に静的なHTMLファイルを生成するため、リアルタイムで変動する閲覧数を基にした動的なランキング表示は得意ではありません。また、フロントエンドとバックエンドが分離しているため、アクセス数を記録・参照する共通の仕組みが標準では備わっていません。

そこで活用したいのが、多くのWebサイトで導入されているアクセス解析ツール「Google Analytics」です。Google Analyticsに蓄積されたページごとの閲覧数データを、そのAPI(Google Analytics Data API (GA4 Data API))経由で取得し、ビルドプロセスに組み込むことで、静的サイトでありながら「人気記事一覧」を表示することが可能になります。

この記事では、Google Analytics Data API (GA4) を利用して人気記事データを取得し、Next.jsGatsby.jsといった静的サイトジェネレーター環境で「人気記事一覧」を実装するための具体的な手順と考え方を紹介します。


この記事の内容

  1. 静的サイト(ヘッドレスCMS)で人気記事一覧を実装する難しさ
  2. Google Analytics Data API (GA4) の有効化と基本準備
  3. サービスアカウントの利用とセキュリティ上の注意点
  4. Node.jsによる人気記事データ取得スクリプトの実装例
  5. ビルド時にJSONデータを活用し、静的サイトに組み込む方法
  6. まとめ:静的サイトでもAPI連携で人気記事一覧は実現できる!

静的サイト(ヘッドレスCMS)で人気記事一覧を実装する難しさ

JAMstack構成とGoogle Analytics連携のイメージ図

前述の通り、従来の動的なCMS(WordPressなど)では、データベースへのアクセスを通じてリアルタイムにPV数を集計し、人気記事ランキングを表示することが一般的でした。

しかし、JAMstack構成の静的サイトでは、サイトのコンテンツはビルド時に生成され、サーバー側での動的なデータ処理は基本的には行いません。そのため、サイトが表示されるたびにPV数をリアルタイムで集計してランキングを変動させる、といった実装は困難です。

そこで、外部サービスであるGoogle Analyticsのデータを活用するアプローチが有効になります。基本的な流れは以下のようになります。

  1. ビルド前にデータを取得: スクリプトを実行し、Google Analytics Data APIを通じて、指定期間のページ別閲覧数を取得します。(例: 直近30日間のPV数トップ10記事)
  2. データを整形・保存: 取得したランキングデータを扱いやすい形式(例: JSONファイル)に整形して、プロジェクト内に保存します。
  3. ビルド時にデータを参照: Next.jsやGatsby.jsなどの静的サイトジェネレーターがサイトをビルドする際に、保存されたJSONファイルを読み込みます。
  4. 静的ページに埋め込み: 読み込んだランキングデータ(記事タイトル、URL、PV数など)を使って、「人気記事一覧」のコンポーネントやリストを生成し、静的なHTMLページ内に埋め込みます。

この方法であれば、サイトをデプロイ(ビルド)するたびに最新のランキング情報が反映され、かつサイト自体は高速な静的ファイルとして提供できるため、パフォーマンスを損なうこともありません。


Google Analytics Data API (GA4) の有効化と基本準備

まず、Google Analyticsのデータをプログラムから取得するために、APIの有効化と必要な情報を準備します。

Google Cloud PlatformでGoogle Analytics Data APIを有効化する画面

  1. Google Cloud Platform (GCP) でAPIを有効化:
    • Google Cloud Console (https://console.cloud.google.com/) にアクセスし、プロジェクトを選択または新規作成します。
    • 「APIとサービス」>「ライブラリ」で「Google Analytics Data API」を検索し、有効にします。
  2. サービスアカウントを作成し、キーをダウンロード:
    • GCPの「APIとサービス」>「認証情報」で、「認証情報を作成」>「サービスアカウント」を選択し、新しいサービスアカウントを作成します。(名前は任意、ロールは不要な場合が多い)
    • 作成したサービスアカウントを選択し、「キー」タブ>「鍵を追加」>「新しい鍵を作成」で「JSON」形式のキーを作成・ダウンロードします。このJSONファイルは後でスクリプトから使用します。大切に保管してください。
  3. サービスアカウントにGA4プロパティへのアクセス権を付与:
    • Google Analytics (https://analytics.google.com/) にアクセスし、対象のGA4プロパティの「管理」(歯車アイコン)を開きます。
    • 「プロパティ設定」>「プロパティのアクセス管理」で、「+」ボタン >「ユーザーを追加」を選択します。
    • 先ほど作成したサービスアカウントのメールアドレス(GCPの認証情報画面で確認できます)を入力し、「役割」として少なくとも「閲覧者」の権限を付与して追加します。
  4. GA4プロパティIDを控える:
    • Google Analyticsの「管理」>「プロパティ設定」で、「プロパティ ID」(数字のみのID)を確認し、控えておきます。これもスクリプトで使用します。

    Google Analytics 4のプロパティID確認画面

これらの準備(特にGCPやGA4の操作)については、Googleの公式ドキュメントや他の解説記事も参考に、ご自身の環境に合わせて進めてください。


サービスアカウントの利用とセキュリティ上の注意点

Google Cloud Platformでのサービスアカウントキー管理画面

Google Analytics Data APIのように、Googleのサービスにプログラムからアクセスする際には、通常「サービスアカウント」という特殊なアカウントを使用します。これは、個人のGoogleアカウントではなく、アプリケーションやスクリプトが自身を認証するためのものです。

前述のステップで作成しダウンロードしたサービスアカウントキー(JSONファイル)には、そのサービスアカウントとしてAPIにアクセスするための秘密の情報が含まれています。そのため、このキーファイルの取り扱いには細心の注意が必要です。

  • 絶対に公開しない: JSONキーファイルは、Gitリポジトリ(特にPublicリポジトリ)に絶対にコミットしないでください。誤って公開してしまうと、第三者に不正利用される危険性があります。.gitignoreファイルにキーファイル名を追加し、Gitの管理対象から除外しましょう。
  • 安全な場所に保管: ローカル開発環境ではプロジェクトルートなどに置くこともありますが、本番環境(デプロイ先)では、環境変数やシークレット管理機能を使って安全にキー情報を渡すのが一般的です。(後述のスクリプト例参照)
  • 権限は最小限に: GA4プロパティでサービスアカウントに付与する権限は、データ取得に必要な最低限の「閲覧者」権限にしておきましょう。

Node.jsによる人気記事データ取得スクリプトの実装例

ここでは、準備したサービスアカウントキーとGA4プロパティIDを使って、実際に人気記事データを取得し、JSONファイルとして保存するNode.jsスクリプトの例を示します。

【準備】

  1. プロジェクトのルートディレクトリにscriptsフォルダを作成し、その中に以下のスクリプトをfetch-popular-posts.jsなどの名前で保存します。
  2. プロジェクトのルートディレクトリに、GCPからダウンロードしたサービスアカウントキーのJSONファイルをservice-account.json(または任意の名前)として配置します。
  3. プロジェクトのルートディレクトリに.envファイルを作成し、以下の形式でGA4プロパティIDを記述します(?????????の部分は実際のIDに置き換えてください)。
    GA4_PROPERTY_ID=?????????
  4. 【重要】service-account.json.envファイルは機密情報を含むため、必ず.gitignoreファイルに追加して、Gitリポジトリに含まれないようにします。
    # .gitignore ファイルの例
    service-account.json
    .env
        
  5. 必要なnpmパッケージをインストールします。ターミナルで以下のコマンドを実行してください。
    npm install @google-analytics/data dotenv

    (または yarn add @google-analytics/data dotenv

【スクリプト例: scripts/fetch-popular-posts.js

// .envファイルから環境変数を読み込む
require("dotenv").config();
// Google Analytics Data APIクライアントライブラリ
const { BetaAnalyticsDataClient } = require("@google-analytics/data");
// Node.jsのファイルシステムとパス操作モジュール
const fs = require("fs");
const path = require("path");

// 非同期関数として人気記事取得処理を定義
async function fetchPopularPosts() {
  let credentials;

  // --- 認証情報の設定 ---
  // 本番環境用に環境変数 GA_CREDENTIALS_JSON があればそれを使う (推奨)
  if (process.env.GA_CREDENTIALS_JSON) {
    try {
      credentials = JSON.parse(process.env.GA_CREDENTIALS_JSON);
    } catch (e) {
      console.error("Failed to parse GA_CREDENTIALS_JSON environment variable.", e);
      process.exit(1);
    }
  }
  // 環境変数がなければ、ローカルの service-account.json を読み込む
  else {
    const keyFilePath = path.resolve(__dirname, "../service-account.json");
    if (fs.existsSync(keyFilePath)) {
      credentials = JSON.parse(fs.readFileSync(keyFilePath, "utf8"));
    } else {
      console.error(`Service account key file not found at ${keyFilePath}. Or set GA_CREDENTIALS_JSON env var.`);
      process.exit(1);
    }
  }

  // --- GA4 Data API クライアントの初期化 ---
  const analyticsDataClient = new BetaAnalyticsDataClient({
    credentials: {
      client_email: credentials.client_email,
      private_key: credentials.private_key,
    },
  });

  // --- GA4 プロパティIDの取得 ---
  const propertyId = process.env.GA4_PROPERTY_ID;
  if (!propertyId) {
    throw new Error("GA4_PROPERTY_ID is not set in environment variables.");
  }

  // --- APIリクエストの実行 ---
  try {
    const [response] = await analyticsDataClient.runReport({
      // プロパティIDを指定
      property: `properties/${propertyId}`,
      // データ取得期間 (過去30日間)
      dateRanges: [{ startDate: "30daysAgo", endDate: "today" }],
      // 取得するディメンション (ページのパス, ページのタイトル)
      dimensions: [{ name: "pagePath" }, { name: "pageTitle" }],
      // 取得するメトリクス (表示回数)
      metrics: [{ name: "screenPageViews" }], // GA4では "ga:pageviews" ではなく "screenPageViews"
      // 並び順 (表示回数の降順 = 多い順)
      orderBys: [{ metric: { metricName: "screenPageViews" }, desc: true }],
      // 取得件数 (上位10件)
      limit: 10,
      // ディメンションフィルタ (ブログ記事パス '/blog/' で始まるページのみ対象とする例)
      dimensionFilter: {
        filter: {
          fieldName: "pagePath",
          stringFilter: {
            matchType: "PARTIAL_REGEXP", // 正規表現に部分一致
            value: "^/blog/", // /blog/ で始まるパス
          },
        },
      },
    });

    // --- 結果の整形 ---
    const popularPosts = response.rows.map((row) => ({
      pagePath: row.dimensionValues[0].value,
      pageTitle: row.dimensionValues[1].value,
      pageViews: parseInt(row.metricValues[0].value, 10), // 閲覧数を整数に変換
    }));

    // --- JSONファイルへの書き出し ---
    // プロジェクトルートに data フォルダがなければ作成
    const dataDir = path.resolve(__dirname, "../data");
    if (!fs.existsSync(dataDir)) {
      fs.mkdirSync(dataDir);
    }
    // dataフォルダ内に popular-posts.json として保存
    fs.writeFileSync(
      path.join(dataDir, "popular-posts.json"),
      JSON.stringify(popularPosts, null, 2) // 読みやすいように整形して出力
    );
    console.log("Successfully fetched popular posts and saved to data/popular-posts.json");

  } catch (error) {
      console.error("Error fetching Google Analytics data:", error);
      process.exit(1); // エラー発生時はプロセスを終了
  }
}

// 関数を実行
fetchPopularPosts();

スクリプトのポイント:

  • 認証情報: 環境変数 `GA_CREDENTIALS_JSON` があればそれを優先的に使用し、なければローカルの `service-account.json` を読み込みます。これにより、ローカル開発と本番環境(Cloudflare Pagesなど)で認証情報を安全に扱うことができます。(本番環境では、環境変数にJSONキーの内容全体を設定するのが一般的です)
  • APIリクエスト: `runReport` メソッドでGA4にリクエストを送ります。
    • dateRanges: データ取得期間を指定します(例: “30daysAgo”~”today”)。
    • dimensions: 取得したい情報の種類(ページのパス、タイトルなど)を指定します。
    • metrics: 集計したい指標(表示回数 `screenPageViews` など)を指定します。
    • orderBys: 並び順を指定します(例: 表示回数の多い順)。
    • limit: 取得する最大件数を指定します。
    • dimensionFilter: 【重要】 取得するページを絞り込むためのフィルターです。この例では「ページのパス (`pagePath`) が正規表現 ^/blog/ に一致するもの」だけを取得しています。これにより、ブログ記事以外のページ(トップページ `/` など)がランキングに含まれるのを防ぎます。この `value` は、あなたのブログ記事のURL構造に合わせて必ず変更してください。
  • 結果の整形と保存: APIからの応答データを扱いやすいJSON形式(パス、タイトル、閲覧数のオブジェクト配列)に変換し、data/popular-posts.json ファイルに書き出します。

このスクリプトをターミナルで node scripts/fetch-popular-posts.js と実行すると、`data` フォルダ(なければ作成される)に人気記事のデータがJSONファイルとして保存されます。


ビルド時にJSONデータを活用し、静的サイトに組み込む方法

人気記事データを含むJSONファイルが用意できたら、あとは静的サイトジェネレーター(Next.jsやGatsby.js)のビルドプロセスでこのJSONファイルを読み込み、ページやコンポーネントにデータを渡して表示するだけです。

しかし、ここで重要なのは「サイトをビルド(デプロイ)するたびに、このJSONファイルが最新の情報に更新されるようにする」ことです。そうしないと、ランキングが古いままになってしまいます。

これを実現するには、通常、プロジェクトの package.json ファイル内の scripts セクションを編集し、ビルドコマンドの実行前にデータ取得スクリプトが実行されるように設定します。

package.json の設定例 (Gatsby.jsの場合)】

{
  "scripts": {
    // データ取得スクリプトを実行するコマンドを定義
    "fetch-data": "node scripts/fetch-popular-posts.js",
    // 開発サーバー起動時にもデータを取得する場合 (任意)
    "develop": "npm run fetch-data && gatsby develop",
    // 本番ビルド時に必ずデータ取得を実行するように設定
    "build": "npm run fetch-data && gatsby build",
    // startコマンドも同様に(開発用サーバー起動など)
    "start": "npm run develop",
    // 他にも test や serve など...
  }
}

この例では、

  1. fetch-data という名前でデータ取得スクリプトを実行するコマンドを定義しています。
  2. build コマンド(本番用ビルド)の実行時に、まず npm run fetch-data を実行し、その後に gatsby build が実行されるように設定しています。(&& はコマンドを順番に実行する指定子)
  3. 同様に、開発サーバー起動時 (develop, start) にもデータを取得するようにしています(開発中も最新データで確認したい場合)。Next.jsの場合は next devnext build の前に npm run fetch-data && を追加します。

このように設定しておくことで、npm run build コマンドを実行(またはVercelやCloudflare Pagesなどのホスティングサービスで自動ビルドが実行される際)に、

  1. まず fetch-popular-posts.js が実行され、最新の人気記事データが data/popular-posts.json に保存されます。
  2. 次に、Gatsby (またはNext.js) のビルドプロセスが開始され、その中で data/popular-posts.json ファイルを読み込み、人気記事一覧を含む静的HTMLページが生成されます。

この「ビルド時データフェッチ」のアプローチにより、サイト訪問者は常に(ビルド時点での)最新の人気記事一覧を高速な静的ページとして閲覧でき、サーバーへの負荷やAPIの実行時呼び出しを気にする必要がなくなります。これはパフォーマンスとセキュリティの観点からもJAMstack構成の大きなメリットです。

あとは、各フレームワークの方法に従って、ビルド時にJSONデータを読み込み、Reactコンポーネントなどに渡して表示する部分を実装してください。(例: Gatsbyではgatsby-node.jsでJSONを読み込みGraphQLデータレイヤーに追加、Next.jsではgetStaticProps内でfs.readFileを使ってJSONを読み込むなど)


まとめ:静的サイトでもAPI連携で人気記事一覧は実現できる!

JAMstackヘッドレスCMSを採用した静的サイト環境では、WordPressのような従来の動的CMSとは異なり、「人気記事一覧」をリアルタイムで表示することは困難です。

しかし、この記事で解説したように、Google Analytics Data API (GA4) を活用し、サイトのビルドプロセス前にアクセスデータを取得・整形してJSONファイルなどの形で保存し、それをビルド時に静的ページに埋め込むというアプローチを取ることで、静的サイトのメリット(高速表示、高セキュリティ、スケーラビリティ)を維持しつつ、最新の人気記事ランキングを表示することが可能になります。

この方法は、特定のCMSやフロントエンドフレームワークに強く依存しないため、Next.jsGatsby.jsだけでなく、様々なJAMstack構成に応用できます。サービスアカウントキーの安全な管理や、APIリクエストのフィルター設定など、いくつか注意点はありますが、一度仕組みを構築すれば、自動でランキングが更新される便利な機能を実現できます。

ぜひ、ご自身の静的ブログサイトやWebサイトの構成に合わせて、この手法を参考に「人気記事一覧」の実装に挑戦してみてください。

【VRChat】服の裏地が透ける/透明になる問題を修正!MeshFlipperの使い方

VRChatでマントやロングコートなど、丈の長い衣装を着ているアバターを使ったとき、「あれ? フレンド視点だと服の裏地が透明になって透けて見える…」と指摘された経験はありませんか?

自分視点では特に問題ないのに、他人から見るとコートの裏側などが描画されず、体が透けて見えてしまう…。これはVRChatでアバターを使っていると比較的よく遭遇する現象です。

この「衣装の裏地が透ける問題」、実は簡単なUnityツールで解決できる場合があります。この記事では、その原因と、解決策となるツール「MeshFlipper」の使い方について、備忘録も兼ねて解説します。


この記事の内容

  1. なぜVRChatで服の裏地が描画されない(透ける)のか?
  2. 解決策!「MeshFlipper」の導入と使い方(実装手順)
  3. (少し技術的な話)MeshFlipperが裏地問題を解決する仕組み
  4. まとめ:服の裏地が透けるならMeshFlipperを試そう!

なぜVRChatで服の裏地が描画されない(透ける)のか?

VRChat内でコートの裏地が透けて見えている状態の例

この現象の主な原因は、多くの3Dモデルで採用されている「片面レンダリング(または片面描画)」という仕組みにあります。

簡単に言うと、3Dモデルを構成するポリゴン(板のようなもの)は、基本的に「表面」だけを描画し、「裏面」は描画しないことで、コンピューターの描画負荷を軽くしています。体にぴったりフィットした服などは、外側(表面)だけが見えれば十分なので、この仕組みで問題ありません。

しかし、コート、マント、スカートのようにヒラヒラしたり、裾が長かったりする衣装の場合、キャラクターが動いたり、特定の角度から見たりすると、衣装の「裏面」が見えてしまうことがあります。

片面レンダリングでは、この「裏面」は描画対象外なので、結果として何も描画されず、背景や体が透けて見えてしまうのです。これが、他人視点や三人称視点のカメラで見たときに「裏地が透明になっている」「バグで描画されていない」ように見える正体です。

この問題を解決するには、単純に「衣装の裏面もちゃんと描画されるようにする」必要があります。そのための処理を簡単に行ってくれるのが、次にご紹介する「MeshFlipper」というツールです。


解決策!「MeshFlipper」の導入と使い方(実装手順)

衣装の裏地が透ける問題の解決方法を探していたところ、以下の記事で「MeshFlipper」というUnityエディタ拡張ツールの存在を知りました。(情報感謝です!)

Android(Quest)対応方法マニュアルAdvanced!! – もえぎつばさ 様

MeshFlipperは、Unity上で3Dモデルのメッシュデータ(形状データ)を加工し、裏面も描画されるように両面化してくれる非常に便利なツールです。fum1さんがBoothで無料配布してくれています。

【無料】メッシュの裏面を生成するツール / Mesh Flipper (BOOTH)

導入と基本的な使い方は以下の通り、とても簡単です。

MeshFlipperのウィンドウと設定オプション

  1. MeshFlipperをUnityプロジェクトにインポートする
    まず、上記BoothからMeshFlipperをダウンロードします。ダウンロードしたファイルに含まれるMeshFlipper.csというスクリプトファイルを、UnityプロジェクトのAssetsフォルダ内の好きな場所(例えばEditorフォルダなど)にドラッグ&ドロップしてインポートします。
  2. 裏地が透ける衣装のメッシュを選択する
    UnityのHierarchyウィンドウで、修正したいアバターを選択し、その中から裏地が透けてしまう衣装のパーツ(オブジェクト)を探します。そのオブジェクトにアタッチされているSkinned Mesh RendererまたはMesh Rendererコンポーネントを見つけてください。
  3. MeshFlipperウィンドウを開く
    Unityのメニューバーから fum1 > Mesh Flipper を選択し、MeshFlipperの専用ウィンドウを開きます。
  4. オプションを設定する(重要:TwoSidesを選択)
    MeshFlipperウィンドウが開いたら、対象の衣装パーツ(Skinned Mesh Rendererなどが付いたオブジェクト)を選択した状態で、以下のオプションを設定します。

    • TwoSides: このオプションにチェックを入れるのが基本です。これがメッシュを両面化する機能で、チェックを入れると裏面も描画されるようになります。
    • Flip: こちらはポリゴンの面の向き(法線)を反転させる機能です。通常、裏地が透ける問題の解決にはTwoSidesだけで十分です。

    ほとんどの場合、TwoSidesにチェックを入れるだけで裏地が透ける問題は解決します。

  5. 「Create Mesh」ボタンを押して実行する
    オプションを設定したら、「Create Mesh」ボタンをクリックします。すると、MeshFlipperが選択したメッシュを両面化処理し、新しいメッシュデータを作成して自動的に元のメッシュと差し替えてくれます。(元のメッシュデータもバックアップとして残る場合があります)

処理が完了したら、Unityのシーンビューで衣装の裏側から見てみたり、VRChatにアップロードしてフレンドに確認してもらったりしましょう。裏地がちゃんと描画され、透けなくなっていれば成功です!


(少し技術的な話)MeshFlipperが裏地問題を解決する仕組み

少しだけ技術的な話をすると、MeshFlipperは内部で以下のような処理を行っています。

  • 頂点データの複製と法線の反転: 元のメッシュの頂点データをコピーし、コピーした側のポリゴンの向き(法線)を反転させます。
  • メッシュの結合: 元のメッシュ(表面)と、法線を反転させたコピー(裏面用)を一つに結合します。

これにより、実質的に「表面用のポリゴン」と「裏面用のポリゴン」の両方を持つメッシュデータが作成されます。結果として、どちらの方向から見てもポリゴンが描画されるようになり、裏地が透ける問題が解決するという仕組みです。

要するに、MeshFlipperは「本来は存在しなかった(描画されなかった)服の裏側」を擬似的に作ってくれるツール、と理解しておけば大丈夫です。

この複雑な処理をボタン一つで実行してくれるので、特にコートやスカートなど、裏側が見えやすい衣装を扱う際には非常に重宝します。


まとめ:服の裏地が透けるならMeshFlipperを試そう!

VRChatでアバターの衣装(特にコートやマント、スカートなど)の裏地が透けてしまう透明になってしまうという問題に遭遇したら、まずはUnityエディタ拡張ツール「MeshFlipper」の利用を検討してみてください。

簡単な手順でメッシュを両面化でき、多くの場合、これだけで裏地が正常に描画されるようになります。

MeshFlipperは、開発者のfum1さんがBoothで無料配布してくれています。同じ悩みを持つVRChatユーザーやアバター改変を行う方は、ぜひ導入して試してみることをお勧めします!

【無料】メッシュの裏面を生成するツール / Mesh Flipper (BOOTH)

FontToolsでNoto Sans JPのサブセットを作成して読み込み速度を上げる

Webサイトの表示速度が遅い…その原因の一つに、Webフォントのファイルサイズが大きいことが挙げられます。特に日本語フォントは多くの文字を含むため、データ量が膨大になりがちです。この記事では、人気のある日本語フォント「Noto Sans JP」を例に、必要な文字だけを抽出して軽量化する「サブセット化」を行い、ページ読み込み速度を改善する方法を解説します。

様々なツールがある中で、当初「サブセットフォントメーカー」を試しましたが、私の環境では表示崩れが発生しました。最終的にPythonライブラリ「FontTools」を用いることで、OTF情報(文字詰めなどの見た目を整える情報)を維持したまま、Noto Sans JPフォントをWOFF2形式にサブセット化し、ファイルサイズを50%以上削減、読み込み速度を向上させることに成功しました。その具体的な手順と注意点を備忘録としてまとめます。

この記事の内容

  1. フォントのサブセット化とは?なぜページ速度改善に必要なのか
  2. 【失敗談】サブセットフォントメーカーでOTF情報が欠落し表示が崩れた件
  3. 解決策!FontToolsを使った高精度なサブセット作成手順
  4. まとめ:FontToolsによるサブセット化の効果とページ速度への貢献

1. フォントのサブセット化とは?なぜページ速度改善に必要なのか

フォントのサブセット化とは、簡単に言うと、フォントファイルの中からWebサイトで実際に使用する文字だけを抜き出し、不要な文字データを削除してファイルサイズを小さくする技術のことです。「普段使わない難しい漢字や特殊記号まで全部読み込むのは無駄だよね?使う文字だけに絞って軽くすれば、サイトがもっと速く表示されるはず!」という考え方に基づいています。

このブログでも使用している定番の日本語フォント「Noto Sans JP」は、Google Fontsからも入手できる高品質なフォントですが、非常に多くの文字(ひらがな、カタカナ、常用漢字、人名漢字、記号など)を網羅しています。

Noto Sans Japanese (Google Fonts)

そのため、ダウンロードしてそのままWebフォント(例えばWOFF形式)としてサイトに組み込むと、標準の太さ(Regular)や太字(Bold)だけで、それぞれ約4MBものファイルサイズになってしまいます。これでは、ユーザーがページを開くたびに大きなデータをダウンロードする必要があり、表示速度のボトルネックになりかねません。

サブセット化前のNoto Sans JPフォントファイルサイズ(各約4MB)

(↑サブセット化前のフォントファイル。サイズが大きいことがわかります。)

そこで重要になるのが、この巨大なフォントファイルを軽量化する「サブセット化」なのです。


2. 【失敗談】サブセットフォントメーカーでOTF情報が欠落し表示が崩れた件

フォントのサブセット化について調べると、「サブセットフォントメーカー」というGUIツールがよく紹介されています。私もいくつかの解説サイトを参考に、このツールと「WOFFコンバータ」を使ってNoto Sans JP(TTF形式)からサブセットWOFFフォントを作成してみました。

サブセットフォントメーカーの画面

しかし、生成されたフォントをサイトに適用したところ、予期せぬ表示崩れが発生してしまいました。

サブセットフォントメーカーで変換後の表示崩れ(文字間隔が広がる)

(↑左が元の表示、右がサブセットフォントメーカーで変換後の表示。記事タイトル部分の文字間隔が不自然に広がっています。)

原因を調査したところ、どうやら「サブセットフォントメーカー」がフォント変換を行う過程で、Noto Sans JPに含まれる重要なOTF(OpenType Font)情報の一部、特に文字間隔の調整(カーニング、ペアカーニング)を行うための情報(GPOSテーブルなど)を削除してしまったようです。

OTF情報は、文字の形だけでなく、文字と文字の間のアキを自動調整したり、特定の文字の組み合わせで合字(リガチャ)に置き換えたり(GSUBテーブル)といった、フォントの見た目を美しく整えるための重要なデータです。これが失われたために、文字間隔がデフォルトのままになり、レイアウトが崩れてしまったと考えられます。

軽量化はできても、見た目が損なわれては意味がありません。そこで、OTF情報を維持したまま、高精度なサブセット化ができるツールを探し、Python製のライブラリ「FontTools」にたどり着きました。


3. 解決策!FontToolsを使った高精度なサブセット作成手順

FontToolsは、フォントファイルを操作するための強力なPythonライブラリ群です。オープンソースで開発されており、TTFやOTF形式のフォントに対して、サブセット化はもちろん、情報の編集、形式変換など、様々な高度な処理を行うことができます。コマンドラインから手軽に利用できるのも魅力です。

FontTools (GitHubリポジトリ)

FontToolsを使ってNoto Sans JPのサブセットを作成する手順は以下の通りです。

3-1. FontToolsのインストール

FontToolsはPythonライブラリなので、まずお使いの環境にPythonがインストールされていることを確認してください。Pythonが利用できる環境であれば、ターミナル(コマンドプロンプト)で以下のpipコマンドを実行してFontToolsをインストールします。

pip install fonttools brotli zopfli

※ WOFF2形式の扱いや、より高い圧縮率(--with-zopfliオプション)を実現するために、brotlizopfli も一緒にインストールしておくと良いでしょう。

3-2. サブセット化コマンドの実行

次に、ターミナルでpyftsubsetコマンドを使ってサブセット化を実行します。Noto Sans JPの元フォントファイル(例: NotoSansJP-Regular.ttf)があるディレクトリで、以下のコマンドを実行してください。(ファイル名やパスはご自身の環境に合わせて変更してください。)

# NotoSansJP-Regular.ttf からサブセット NotoSansJP-Regular.woff2 を作成する例
pyftsubset NotoSansJP-Regular.ttf \
  --output-file=NotoSansJP-Regular.woff2 \
  --flavor=woff2 \
  --layout-features='*' \
  --unicodes='U+0020-007E,U+3000-30FF,U+4E00-9FAF,U+FF01-FF60,U+FF65-FF9F' \
  --with-zopfli \
  --verbose

同様に、Bold(太字)など他のウェイトのフォントもサブセット化する場合は、元ファイル名と出力ファイル名を変更してコマンドを実行します。

コマンドオプションの解説:

  • NotoSansJP-Regular.ttf

    サブセット化の元となるフォントファイル(TTFまたはOTF)。

  • --output-file=NotoSansJP-Regular.woff2

    出力するサブセットフォントのファイル名とパスを指定。

  • --flavor=woff2

    出力形式をWOFF2に指定。WOFF2はWebフォント用に最適化された形式で、圧縮率が高くファイルサイズを小さくできます。

  • --layout-features='*'

    【重要】 これがOTF情報を保持するためのオプションです。'*'を指定することで、カーニング(文字詰め)やリガチャ(合字)などのOpenTypeレイアウト機能に関する情報をすべて保持します。これにより、サブセットフォントメーカーで発生したような表示崩れを防ぎます。

  • --unicodes='...'

    【重要】 サブセットに含める文字のUnicode範囲を指定します。ここで指定した範囲外の文字はフォントに含まれなくなり、表示できなくなる(文字化けする)ので慎重に設定します。上記コマンド例の範囲は以下をカバーしています。

    • U+0020-007E: 基本的な半角英数字と記号 (ASCII)
    • U+3000-30FF: 全角スペース、句読点、ひらがな、カタカナなど
    • U+4E00-9FAF: CJK統合漢字(一般的に使われる漢字の多くをカバー)
    • U+FF01-FF60: 全角の英数字や記号の一部
    • U+FF65-FF9F: 半角カタカナ

    ※ サイトで使用する文字に合わせて、この範囲を調整する必要があります。例えば、特定の記号や第二水準漢字なども使う場合は、対応するUnicode範囲を追加します。

  • --with-zopfli

    Googleが開発したZopfli圧縮アルゴリズムを使用し、WOFF2ファイルをさらに高圧縮します。ファイルサイズ削減に効果的です。(zopfliライブラリのインストールが必要)

  • --verbose

    サブセット化の処理中に詳細なログを出力します。エラーの原因調査や、どの情報が含まれたか/除外されたかを確認するのに役立ちます。

3-3. 生成されたWOFF2ファイルをCSSで読み込む

コマンドが正常に完了すると、指定した場所に軽量化されたWOFF2形式のサブセットフォントファイルが生成されます。あとは、このファイルをWebサーバーにアップロードし、CSSの@font-face規則を使って読み込むように設定を変更します。

/* Regular (標準) */
@font-face {
  font-family: 'Noto Sans JP'; /* フォント名を指定 */
  /* ↓ 生成したWOFF2ファイルのパスを指定 */
  src: url('/path/to/your/fonts/NotoSansJP-Regular.woff2') format('woff2');
  font-weight: 400; /* または normal */
  font-style: normal;
  /* font-display: swap; はフォント読み込み中の挙動を指定するプロパティ。設定推奨 */
  font-display: swap;
}

/* Bold (太字) */
@font-face {
  font-family: 'Noto Sans JP';
  /* ↓ 太字用WOFF2ファイルのパスを指定 */
  src: url('/path/to/your/fonts/NotoSansJP-Bold.woff2') format('woff2');
  font-weight: 700; /* または bold */
  font-style: normal;
  font-display: swap;
}

/* 必要に応じて他のウェイトも同様に設定 */

/* body や 各要素で font-family を指定 */
body {
  font-family: 'Noto Sans JP', sans-serif;
}

これで、軽量化されたサブセットフォントがWebサイトで利用されるようになります。


4. まとめ:FontToolsによるサブセット化の効果とページ速度への貢献

FontToolsを使ってNoto Sans JPのサブセット化を行った結果、以下のような効果が得られました。

FontToolsでサブセット化した後のフォントファイルサイズ(各約1.5MB)

(↑FontToolsでサブセット化後。ファイルサイズが大幅に削減されています!)

これにより、ブラウザがダウンロードするデータ量が減り、ページの読み込み時間も改善されました。以下のネットワーク分析結果は、変更前と変更後のフォント読み込み時間を示しています。

変更前(サブセット化前):

サブセット化前のフォント読み込み時間

変更後(FontToolsでサブセット化後):

FontToolsでサブセット化後のフォント読み込み時間(改善)

ファイルサイズ削減に伴い、読み込み時間も短縮されていることが確認できます。これは、Core Web Vitalsなどのページ速度指標の改善にも繋がります。

FontToolsはコマンドラインツールですが、一度コマンドを理解すれば、OTF情報を保持したまま高精度なサブセット化が可能です。Webサイトの表示速度を改善したい、特に日本語フォントの重さにお悩みの方は、ぜひFontToolsによるサブセット化を試してみてはいかがでしょうか。含める文字範囲(--unicodes)をさらに絞り込むなど、工夫次第でさらなる軽量化も可能です。

SSDをクローン換装してCドライブの容量を500GBから2TBに拡張した備忘録

4年ほど使っている自作PCで、最近以下のような気になる動作が増えてきました。

  • エクスプローラでフォルダを開いたり、ファイルを表示したりするのに妙に時間がかかる。
  • ファイル名の変更中など、ファイル操作をしていると表示が一瞬リセットされる(入力が確定されてイライラ…)。
  • ごく稀にPC全体がプチフリーズし、Windowsのタスクバーなどが再読み込みされるような挙動をする。

メモリ診断やGPUドライバ更新、不要ファイルの削除などを試しても改善せず、「そろそろPCの寿命かな…」と考え始めていました。しかし、その前にふとPCの心臓部とも言えるCドライブの状態を確認してみると…

容量が限界に近いCドライブの状態(赤色表示)

真っ赤!残りの空き容量は5%未満という危険水域でした。

一般的に、WindowsがインストールされているCドライブは、常に10%~15%程度の空き容量を確保しておくことが推奨されています。空き容量が極端に少ないと、Windowsの一時ファイル作成、ページングファイル(仮想メモリ)の確保、システムアップデートなどに支障をきたし、結果としてシステムの不安定化、パフォーマンス低下、読み書き速度の低下(特にSSDの場合)など、様々な不具合を引き起こす原因となります。

そこで今回、この容量不足を解消すべく、現在のCドライブ(約500GBのM.2 SSD)の内容を丸ごと新しい大容量SSD(2TBの2.5インチSSD)にコピー(クローン)して交換(換装)することに挑戦しました。結果的に容量拡張は成功したものの、途中でWindowsが起動しなくなるトラブルにも遭遇し、かなり苦戦しました…。

この記事では、そのSSDクローン換装の具体的な手順、使用したツール、そして遭遇した起動エラー「0xc000000e」の対処法などを、備忘録として詳しくまとめていきます。同じようにCドライブの容量不足に悩んでいる方や、SSD換装を検討している方の参考になれば幸いです。


SSDクローン換装の手順概要

この記事で解説する手順

  1. 事前準備:必要なもの(SSD、ソフト、USBメモリ等)
  2. 換装手順の詳細:クローンからトラブル解決まで
    1. SSDクローンの作成 (Macrium Reflect Free)
    2. Windowsインストールメディアの作成(トラブル対策用)
    3. SSDの物理的な取り付けとBIOS設定、そして起動エラー対処
    4. パーティションの拡張(容量を使い切る)
  3. 換装完了と結果:容量拡張とPCの安定化

事前準備:必要なもの(SSD、ソフト、USBメモリ等)

今回のSSDクローン換装で使用した主な物品とソフトウェアは以下の通りです。

  • 新しいSSD: シリコンパワー 2TB SSD 3D NAND A58 (2.5インチ SATA)
    • 換装先のSSDです。容量や規格(M.2 NVMe, 2.5インチ SATA等)、メーカーはお好みで。今回はセールで安価だったこちらを選びました。元のM.2から2.5インチへの変更ですが、マザーボードに空きSATAポートがあれば問題ありません。

    シリコンパワー 2TB SSD 3D NAND A58 (Amazon)

  • SSDクローンソフト: Macrium Reflect Free
    • 元のSSDの内容を新しいSSDに丸ごとコピー(クローン)するためのソフトウェア。様々なソフトがありますが、今回は無料で評価も高かったこちらを使用しました。

    Macrium Reflect Free – 窓の杜 /
    [参考記事] Macrium Reflect Freeを使ってSSDをクローンし、大容量のSSDに移行する – combat-travor 様

  • USBメモリ: 16GB以上のもの
    • 換装後にWindowsが起動しなくなった場合の修復作業で使用します。Windowsのインストールメディアを作成するために必要です。【重要】この作業は事前にやっておくことを強く推奨します。

    Windows 10メディア作成ツール – Microsoft (Windows 11の場合はこちら)

  • パーティション管理ソフト: Paragon Hard Disk Manager 15 (または同等の機能を持つソフト)
    • 換装後、新しいSSDの全容量をCドライブとして使えるように、パーティションサイズを調整(拡張)するために使用しました。Windows標準の「ディスクの管理」でも可能ですが、より柔軟な操作ができる専用ソフトが便利です。今回は手持ちのソフトを使いましたが、無料のパーティション管理ソフトもあります。
  • SATA-USB変換ケーブル/ケース (任意):
    • 新しいSSDをPC内部に取り付ける前に、USB接続でクローン作業を行う場合に必要です。PC内部に直接接続できる場合は不要。

SSDやソフトウェアは上記以外のものでも構いません。ご自身の環境や予算に合わせて選択してください。ただし、起動トラブルに備えて、Windowsインストールメディアだけは事前に作成しておくことをお勧めします。

BCD (Boot Configuration Data) とは、Windowsの起動に必要な構成情報(どのディスクからOSを起動するかなど)を格納したファイルです。SSD換装後に起動エラーが出る場合、このBCD情報が新しい環境と合わなくなっていることが原因の一つとして考えられます。


換装手順の詳細:クローンからトラブル解決まで

それでは、具体的な換装手順と、私が遭遇したトラブルシューティングについて解説します。

【Step 1】SSDクローンの作成 (Macrium Reflect Free)

まず、現在のCドライブの内容を、新しいSSDに丸ごとコピー(クローン)します。

1. 新しいSSDをPCに接続します。(SATA-USB変換ケーブルを使うか、PC内部の空きポートに接続)

2. クローンソフト(今回はMacrium Reflect Free)を起動します。

3. ソフトの指示に従い、コピー元ドライブ(現在のCドライブ)とコピー先ドライブ(新しいSSD)を選択し、クローン処理を開始します。

Macrium Reflect Freeでのクローン設定画面例

(具体的な操作手順は、前述のcombat-travor様の参考記事が非常に分かりやすいです)

Macrium Reflect Freeでのクローン完了画面

私の環境では、約450GB使用していたCドライブのクローンに約3時間40分かかりました。時間は環境やデータ量によって大きく変動します。

【ポイント】クローン時のパーティションサイズ

クローンソフトの設定で、コピー先のパーティションサイズを指定できる場合があります。基本的には、コピー元と同じサイズでクローンするのが安全です。新しいSSDの残りの容量は、クローン完了時点では「未割り当て」領域として残しておきます。この未割り当て領域は、後ほどStep 4でCドライブと結合します。

💡 クローン時のパーティションサイズは、元のドライブと同じサイズに設定するのが推奨されます。大容量SSDの残りは一旦「未割り当て」のままにします。

クローン完了後、Windowsの「ディスクの管理」(`diskmgmt.msc`)やパーティション管理ソフトで、新しいSSDに元のCドライブと同じ構成のパーティションが作成され、残りが未割り当て領域になっていることを確認しましょう。

パーティション管理ソフトでクローン後のSSDを確認

(↑元のCドライブの内容がコピーされ、残りが未割り当てになっている状態)


【Step 2】Windowsインストールメディアの作成(トラブル対策用)

SSDの換装後、すんなりWindowsが起動すれば良いのですが、環境によっては起動エラーが発生することがあります。私の場合は、以下のブルースクリーンエラーが表示されました。

エラーコード 0xc000000e のブルースクリーン画面

エラーコード「0xc000000e」は、Windowsが起動に必要なデバイス(この場合は新しいSSD)にアクセスできない、または起動構成データ(BCD)に問題がある場合に発生することが多いエラーです。

このエラーを修復するには、Windowsの回復環境からコマンドプロンプトを起動する必要があります。そのために、事前にWindowsインストールメディア(USBメモリ)を作成しておきます。

1. Microsoftの公式サイトから「メディア作成ツール」をダウンロードします。

Windows 10メディア作成ツール / Windows 11メディア作成ツール

2. 16GB以上の空のUSBメモリをPCに接続します。

3. ダウンロードしたメディア作成ツールを実行し、画面の指示に従って「別の PC のインストール メディアを作成する (USB フラッシュ ドライブ、DVD、または ISO ファイル)」を選択し、USBメモリにインストールメディアを作成します。

Windowsメディア作成ツールの画面

このUSBメモリがあれば、万が一Windowsが起動しなくなっても、修復作業を行うことができます。

[参考記事] Windows 10でエラーコード0xc000000eを修正する方法 – MiniTool

[参考記事] 【SSD換装】クローンしたSSDから起動できない時の原因と対処法まとめ – ドクター・エムプレイス


【Step 3】SSDの物理的な取り付けとBIOS設定、そして起動エラー対処

クローン作業とインストールメディア作成が終わったら、いよいよSSDの交換です。

1. PCの電源を完全に切り、電源ケーブルを抜きます。

2. PCケースを開け、古いSSD(元のCドライブ)を取り外し、新しいSSD(クローン済みのもの)を取り付けます。(※静電気対策を忘れずに!)

3. PCケースを閉じ、電源ケーブルを接続し、PCの電源を入れます。

4. 電源を入れた直後(メーカーロゴが表示されている間)に、指定のキー(多くはDELキーかF2キー)を押して、BIOS(UEFI)設定画面に入ります。

5. BIOS設定画面で、「Boot」や「起動」といったメニューを探し、起動順位(Boot Options / Boot Priority)を確認します。ここで、新しく取り付けたSSDが「Windows Boot Manager」として認識され、起動順位の1番目に設定されていることを確認します。(もし認識されていない、または順位が低い場合は設定を変更します)

6. 設定を保存してBIOSを終了し、PCを再起動します。

【トラブル発生】BIOSでは認識されるのに 0xc000000e エラーで起動しない!

私の環境では、ここが最大の難関でした。BIOS上では新しいSSDが起動ドライブとして正しく認識されているにも関わらず、Windowsを起動しようとすると前述のブルースクリーンエラー「0xc000000e」が発生してしまうのです。

最初はクローン失敗を疑い、別のソフト(Paragon)でクローンし直したりしましたが、結果は同じでした。

【解決策】Windowsインストールメディアから起動し、BCDを再構築する

最終的に、Step 2で作成したWindowsインストールメディア(USBメモリ)を使って以下の手順を行うことで解決しました。これは、Windowsの起動構成データ(BCD)を修復・再構築する作業です。

1. PCの電源を切った状態で、Windowsインストールメディア(USBメモリ)を接続します。

2. PCの電源を入れ、すぐにBIOS設定画面に入ります。

3. 起動順位を変更し、USBメモリを最優先(1番目)にして設定を保存・再起動します。

4. USBメモリからWindowsセットアップ画面が起動したら、「コンピューターを修復する」>「トラブルシューティング」>「詳細オプション」>「コマンド プロンプト」を選択します。

5. コマンドプロンプトで、以下のコマンドを順番に実行します。これは、ブートセクタの修復とBCDの再構築を行うためのコマンドです。(詳細な手順は下記の参考記事を参照してください)

  • bootrec /fixmbr
  • bootrec /fixboot (※後述の注意点あり)
  • bootrec /scanos
  • bootrec /rebuildbcd

(場合によっては、diskpartコマンドでEFIパーティションにドライブ文字を割り当てる作業が必要になることもあります)

[参考記事] 【bootrec /fixboot アクセスは拒否されました】コマンドプロンプトからUEFIを修復してWindowsを起動可能にする方法 – ぼくんちのTV 別館

【注意】bootrec /fixboot で「アクセスが拒否されました」エラーが出る場合

bootrec /fixboot でアクセス拒否のエラー

上記のコマンド実行中、bootrec /fixboot で「アクセスが拒否されました (Access is denied.)」というエラーが表示されることがあります。これは、最近のWindows(特にUEFIモードでインストールされている場合)でよく見られる現象のようです。

私の場合は、このエラーを無視して、次の bootrec /scanosbootrec /rebuildbcd を実行したところ、結果的に問題なくWindowsが起動するようになりましたfixbootコマンドは主に古いMBR形式のディスク修復に使われるもので、UEFI環境では必ずしも必要ではない、あるいは別の手順(diskpartを使ったEFIパーティション操作など)が必要な場合があるようです。

もしこのエラーに遭遇し、rebuildbcdまで実行しても起動しない場合は、以下の参考記事にあるような追加の対処法を試す必要があるかもしれません。

[参考記事] 「bootrec /fixboot」でアクセスが拒否されましたと表示される時の対処法! – Windows10 – IT HOOK

BCDの再構築が成功し、コマンドプロンプトを終了してPCを再起動すると、無事に新しいSSDからWindowsが起動するはずです!


【Step 4】パーティションの拡張(容量を使い切る)

無事にWindowsが起動したら、最後の大仕事です。現在、新しいSSDには元のCドライブと同じサイズのパーティションしかなく、残りの大容量スペースは「未割り当て」領域として使えない状態になっています。この未割り当て領域をCドライブと結合し、SSDの全容量を使えるようにします。

パーティション管理ソフトでCドライブと未割り当て領域を表示

この作業は、Windows標準の「ディスクの管理」でも可能ですが、回復パーティションなどが間に挟まっていると拡張できない場合があるため、専用のパーティション管理ソフトを使うのが確実です。

今回は手持ちの「Paragon Hard Disk Manager 15」を使用しました。「パーティションサイズの変更/移動」のような機能を選択し、Cドライブのパーティションを選択して、後方の未割り当て領域を取り込むようにサイズを最大まで広げます。

Paragon Hard Disk Managerでパーティションサイズを拡張する設定

設定を適用すると、通常はPCの再起動が求められ、Windows起動前の画面でパーティションの変更処理が実行されます。処理が完了し、再度Windowsが起動すれば、Cドライブの容量が新しいSSDの最大容量(今回は約2TB)まで拡張されているはずです。

換装完了と結果:容量拡張とPCの安定化

容量が拡張されたCドライブの状態(空き容量十分)

以上の手順を経て、無事にCドライブのSSDを500GBから2TBに換装し、容量を大幅に拡張することができました!

Cドライブの空き容量が十分に確保された(15%以上)ことで、以前発生していたエクスプローラの遅延や表示の再描画、プチフリーズといったPCの不調も嘘のように解消されました。やはり、Cドライブの空き容量不足はシステムの安定性に大きな影響を与えるようです。ドライブが赤色の状態は放置せず、早めに対処(不要ファイルの削除、または今回のような容量拡張)することが重要ですね。

SSDのクローン換装は、手順自体はそれほど複雑ではありませんが、環境によっては起動トラブルが発生する可能性もあります。特にUEFI環境での換装は、BCD周りの問題が起きやすいようです。この記事で紹介したトラブルシューティングが、同じ問題に直面した方の助けになれば幸いです。(※作業は自己責任でお願いします)

【RPGツクールMV/MZ】簡単なカットシーン作成術&カメラ演出で魅力UP!(Galv_CamControl編)

カメラ演出を加えたRPGツクールのカットシーン例

RPGツクールでゲームにドラマティックなカットシーン(イベントシーン)を盛り込みたい!と思ったとき、実はUnityやUnreal Engineといった他のゲームエンジンと比較して、RPGツクールでは驚くほど簡単に基本的なカットシーンを作成できます。

この記事では、RPGツクールの標準機能を使った基本的なカットシーンの作り方から、さらに表現力を豊かにするためのカメラ演出の追加方法までを解説します。カメラ演出には、定番のプラグイン「Galv_CamControl.js」を使用します。

これらのテクニックを使えば、あなたのゲームの物語をより魅力的に、そしてプレイヤーの記憶に残るものにできるはずです。

この記事の内容

  1. 基本的なカットシーンの作り方(RPGツクール標準機能)
  2. カメラ演出の追加方法(Galv_CamControlプラグイン)
  3. リッチなカットシーンの完成へ

基本的なカットシーンの作り方(RPGツクール標準機能)

まずは、プラグインを使わずにRPGツクールの標準機能だけでカットシーンを作成する方法です。

RPGツクールの標準機能だけで作成したシンプルなカットシーン

(↑標準機能だけでも、このようなシーンは作成可能です)

RPGツクールのイベントコマンド設定例(基本的なカットシーン)

RPGツクールのイベントコマンドにある、以下の基本機能を組み合わせるだけで、キャラクター同士の会話や動きを含むカットシーンを簡単に作成できます。

  • 文章の表示: キャラクターのセリフやナレーションを表示します。顔グラフィックと組み合わせることで、誰が話しているかを明確にできます。
  • フキダシアイコンの表示: キャラクターの頭上に「!」や「?」などのアイコンを表示し、感情や状態を視覚的に表現します。
  • 移動ルートの設定: イベントキャラクターやプレイヤーを指定した経路で移動させます。向きの変更、ウェイト(待ち時間)、スイッチ操作なども組み込めます。対象キャラを「このイベント」や名前で指定できるのが非常に直感的です。
  • 透明状態の変更: プレイヤーキャラクターなどを一時的に画面から見えなくします。イベントシーンへの導入時や終了時に便利です。

【Tips】イベントには分かりやすい名前を付けよう!

イベント設定画面でイベント名を設定する

移動ルートの設定でイベント名を指定する場面

他のゲームエンジン経験者から見ると、RPGツクールのイベント作成機能、特にキャラクター指定(「プレイヤー」「このイベント」「イベントID:1」など)や移動ルート設定の手軽さは驚くほど洗練されています。

ここで一つ重要なポイントは、マップ上に配置するキャラクターやオブジェクトなどのイベントには、必ず分かりやすい名前(例:「村人A」「宝箱_洞窟」など)を付けておくことです。イベントコマンドで対象を指定する際に名前で選択できるため、管理が非常に楽になります。これは個人開発であっても、後々の修正やデバッグ時に「あのイベントどれだっけ?」と迷う時間を減らし、将来の自分を助けることにつながります。ゲーム制作が進むほどデータは複雑になるので、こうした小さな心がけが大切です。

さて、標準機能だけでもカットシーンは作れますが、ずっと同じ画角だと少し単調に見えてしまうかもしれません。そこで次に、カメラワークを追加してみましょう。

カメラ演出の追加方法(Galv_CamControlプラグイン)

基本的なカットシーンにカメラワークを加えることで、シーンの臨場感を高めたり、プレイヤーの視線を誘導したりと、より印象的な演出が可能になります。RPGツクールMV/MZでカメラ制御を実現するには、プラグインを利用するのが一般的です。

今回は、多くのツクールユーザーに利用されている定番のカメラ制御プラグイン「Galv_CamControl.js」を使用します。

プラグイン配布元:Galv’s Scripts – MV Cam Control (※MZで利用する場合は、有志による改変版などが必要になる場合があります。別途検索・ご確認ください)

【プラグインの導入】

  1. 上記サイト(または対応版を探して)からプラグインファイル(`Galv_CamControl.js`)をダウンロードします。
  2. RPGツクールのプロジェクトフォルダ内にある `js/plugins` フォルダに、ダウンロードしたファイルをコピーします。
  3. RPGツクールエディタを開き、「ツール」メニューから「プラグイン管理」を選択します。
  4. プラグイン管理ウィンドウで、空いている行をダブルクリックし、「名前」のドロップダウンリストから「Galv_CamControl」を選択して「OK」をクリックします。
  5. 状態が「ON」になっていることを確認し、「OK」をクリックしてプラグイン管理ウィンドウを閉じます。

これでプラグインが有効になり、イベントコマンドの「プラグインコマンド」からカメラ制御の命令を実行できるようになります。

Galv_CamControlのプラグインコマンド入力例

Galv_CamControlの基本的な使い方 (プラグインコマンド)

イベントコマンドの「プラグインコマンド」を使って、以下のような命令を実行することでカメラを制御できます。(これはMVベースの書式例です。MZや特定の改変版では書式が若干異なる場合がありますので、プラグインのヘルプ等をご確認ください)

  • 特定のイベントにカメラを向ける(追従させる):
    例: CAM EVENT 1 (イベントIDが1のキャラクターにカメラを向ける)
    例: CAM EVENT 2 (イベントIDが2のキャラクターにカメラを向ける)
  • プレイヤーにカメラを戻す(追従させる):
    CAM PLAYER
  • 指定したマップ座標にカメラを移動させる:
    CAM MAP X Y (例: CAM MAP 10 15 で座標(10, 15)にカメラを移動)
  • カメラの追従を解除(現在の位置で固定)する:
    CAM TARGET 0

【補足:カメラの移動時間(スクロール)】
上記のコマンドの後に、半角スペースを空けて数字(フレーム数)を指定すると、カメラがその時間をかけてスムーズに移動します。例えば、CAM EVENT 1 60 と入力すると、60フレーム(1秒)かけてイベント1の位置までカメラがスクロールします。時間を指定しない場合は、カメラは瞬時に移動します。

これらのコマンドを、イベントコマンドの「文章の表示」や「移動ルートの設定」、「ウェイト」などと組み合わせることで、会話の話し手にカメラをフォーカスさせたり、重要なアイテムや場所にカメラを向けたりといった演出が可能になります。

【カメラ演出の応用:見せて伝えるゲームデザイン】

カメラを宝箱に向ける演出例

優れたゲームデザインでは、プレイヤーに「どこへ行け」「何を取れ」と指示するだけでなく、目的地や対象物をカメラで一度映し出すことで、プレイヤーが直感的に理解できるように誘導します。

Galv_CamControlのようなカメラ制御プラグインは、カットシーンの演出強化だけでなく、このような「見せて伝える」ゲームデザインを実現するためにも非常に有効です。例えば、NPCからクエストを受けたら、その目的地や関連するオブジェクトに一瞬カメラをパンさせる、といった使い方です。これにより、プレイヤーは次に何をすべきか分かりやすくなり、ゲーム体験が向上します。

💡 応用テクニック:対峙シーンの演出
キャラクター同士が対峙するような緊迫したシーンでは、二人の間に透明な空のイベントを配置し、そのイベントにカメラを固定(例: CAM EVENT [空イベントID] [時間]CAM TARGET 0)することで、キャラクターが画面の両端に配置され、中央に空間ができるような、映画的な構図を作り出すことも可能です。

リッチなカットシーンの完成へ

カメラ演出を加えたRPGツクールのカットシーン完成例

基本的なイベントコマンド(会話、移動、フキダシなど)に、Galv_CamControlによるカメラワークを加えるだけで、最初のシンプルなカットシーンがよりダイナミックで、見ごたえのあるものになったのがお分かりいただけるかと思います。

特にRPGツクールのような2Dベースのゲームでは、画面に動きがないとイベントシーンが単調に見えがちです。カメラを効果的に動かすことで、プレイヤーの視点を誘導し、シーンの重要性を高め、感情的なインパクトを与え、プレイヤーを飽きさせない工夫を凝らしましょう。

RPGツクールの手軽なイベント作成機能と、プラグインによるカメラ制御を組み合わせることで、あなたのゲームはさらに魅力的なものになるはずです。


【VRChat】初めてのアバター購入&改変!マヌカちゃんで実践したモデル・服・髪の導入手順と注意点

VRChat内で改変したマヌカアバター

VRChatに興味があるけど、「アバターってどうやって用意するの?」「改変って難しそう…」と感じている方も多いのではないでしょうか。実は最近、VRChatのアバター導入や改変プロセスは、以前に比べてかなり分かりやすく、始めやすくなっています。

この記事では、VRChat初心者だった筆者が、人気アバター「マヌカ」ちゃんをBoothで購入し、初めてのアバター改変(着せ替え、テクスチャの色や瞳の変更、髪型変更など)に挑戦した際の記録をまとめました。

特に、公式ツール「VCC (VRChat Creator Companion)」のおかげで、Unityを使ったアバターのアップロード作業が驚くほど簡単になっています。この記事が、これからVRChatでアバターを使ってみたい、アバター改変を始めてみたいという方の参考になれば幸いです。

(筆者は3Dモデル制作の学習の一環としてVRChatアバター改変を始めました。学習ステップは以下の通り考えています)

  1. 既存販売アバターの基本的な改変(着せ替え、色変更、簡単なギミック等) ※本記事の内容
  2. VRoid Studioで作成したモデルをVRChatへ導入(テクスチャ作成等の練習)
  3. Blender等によるフルスクラッチモデル制作(最終目標)

今回は、ステップ1の体験談と手順、つまずいた点などを詳しくご紹介します。


目次

  1. ベースモデル「マヌカ」購入と導入(VCCが超便利!)
  2. モデルの改変:服装の着せ替え(対応衣装と注意点)
  3. モデルの改変:瞳と服の色の変更(テクスチャ編集とシェイプキー)
  4. モデルの改変:髪型の変更(対応髪型とエラー対処)
  5. まとめ:初めてのアバター改変は学びが多くて楽しい!
  6. おまけ:初めての自作ワールド挑戦と失敗

ベースモデル「マヌカ」購入と導入(VCCが超便利!)

購入したマヌカモデルをUnityに導入した様子

今回、初めてのアバター改変のベースとして選んだのは、Studio DINGOさんが制作・販売されている大人気3Dモデル「マヌカ」ちゃんです。

オリジナル3Dモデル「マヌカ」ver1.02 – JINGO CHANNEL (Booth)

ちょうどアバターを探していた時期に、作者様がX(旧Twitter)でブラックフライデーセール(50%OFF!)を実施されていたのが購入の決め手でした。さすが人気モデル、クオリティが高くて可愛いです!

【Tips】Boothでのセール情報: VRChatアバターや衣装が多く販売されているBoothでは、クリエイターさんが個別にセールを行うことがあります。気になるモデルを見つけたら、作者さんのXアカウントなどをフォローしておくと、お得な情報を見逃さずに済むかもしれません。

アバターの導入手順(UnityへのインポートとVRChatへのアップロード)については、「メタカル最前線」さんの以下の記事が非常に分かりやすかったです。画像付きで丁寧に解説されているので、初心者の方はまずこちらを読むのがおすすめです。

【徹底解説】VRChatのアバターアップロード・導入方法。困ったときのトラブルシューティング付き | メタカル最前線

VCC (VRChat Creator Companion) がとにかく便利!

VRChat Creator Companion (VCC) のメニュー画面

今回のアバター導入で特に感動したのが、VRChat公式ツール「VCC (VRChat Creator Companion)」の存在です。以前(2018年頃)はUnityのセットアップやVRChat用コンポーネントの導入がもっと複雑だった記憶がありますが、VCCを使えば驚くほど簡単でした。

VCC上で作りたいもの(アバターかワールドか)を選んでプロジェクトを新規作成するだけで、必要なものが揃ったUnityプロジェクトが自動でセットアップされます。Unity Hubから手動で設定する手間が省け、非常にストレスフリーです。プロジェクト管理画面も見やすく、初心者にとって大きな助けになるツールだと感じました。

VCCでのプロジェクト管理画面


モデルの改変:服装の着せ替え(対応衣装と注意点)

購入した衣装をマヌカちゃんに着せた様子

アバターの導入ができたら、次はいよいよ改変の第一歩、服装の着せ替えです。通常、別売りの衣装アセットはアバターの体型に合わせてUnity上で微調整が必要ですが、「マヌカ」ちゃんのような人気アバターの場合、多くのクリエイターさんが「マヌカ対応」として、マヌカちゃんに最適化された衣装をBoothで販売してくれています。これは初心者にとって非常にありがたい点です。

今回は、デフォルトの元気な雰囲気から、少し落ち着いたミステリアスな雰囲気に変えたかったので、オーバーサイズのテックウェアを探していました。そこで見つけたのが、hajimata雑貨店さんの「マヌカ対応衣装【Tech Wear】」です。

マヌカ対応衣装【Tech Wear】 – hajimata (Booth)

探していた日にちょうど発売されたという偶然もあり、即購入。デザインもクオリティも素晴らしい衣装です!

Unity上でマヌカちゃんにTech Wearを着せている様子

「マヌカ対応」衣装なので、導入は非常に簡単。基本的には、購入した衣装のPrefab(プレハブ:設定済みの部品セット)を、UnityのHierarchyウィンドウにあるマヌカちゃんアバターのオブジェクトに入れるだけでOKです。(元の服や不要なパーツは非表示にします。今回はケモミミも非表示にしました)

衣装の着せ替え方法についても、先ほど紹介した「メタカル最前線」さんの記事が大変参考になりました。

【2024年最新版】 VRChat初心者必見!BOOTHで買った衣装をUnityで簡単に改変(カスタマイズ)する方法を解説 | メタカル最前線

【つまずきポイント】衣装小物の追従設定ミス

Tech Wearに付属していた防弾メガネ(ゴーグル)の配置で少しミスをしました。

最初、衣装本体と同じ階層にメガネのPrefabを配置してしまったため、メガネが体の動きには追従するものの、頭の動きには追従せず、結果的に頭の中に埋まってしまいました。

メガネが頭に埋まってしまう失敗例

【解決策】 メガネのような頭部に追従させたい小物は、アバターの骨格構造(Armature)の中にある「Head」(頭ボーン)の子オブジェクトとして配置する必要があります。具体的には、Armature/Hips/Spine/Chest/Neck/Head の下にメガネのPrefabを移動させます。これで頭の動きに合わせてメガネも動くようになります。

正しいメガネの配置場所(Headボーンの下)

アバターの親子関係(ヒエラルキー構造)を理解することが、小物を正しく配置する鍵になります。


モデルの改変:瞳と服の色の変更(テクスチャ編集とシェイプキー)

服装の次は、アバターの印象を大きく左右する瞳と服の色を変更してみました。

瞳の改変には、Boothで販売されている瞳テクスチャを購入して差し替えるのが最も簡単な方法です。しかし今回は、今後の3Dモデル制作の練習も兼ねて、マヌカちゃんの元の顔テクスチャファイルに直接加筆修正する方法を試しました。

【手順】

  1. Unityプロジェクト内にあるマヌカちゃんの顔テクスチャファイル(.pngや.psdなど)を見つけ、作業用フォルダにコピーする。
  2. PhotoshopやCLIP STUDIO PAINTなどの画像編集ソフトで、コピーしたテクスチャファイルを開き、瞳の部分を描き変える。(今回は瞳孔の形を変え、色を緑色に変更)
  3. 編集したテクスチャをPNG形式で出力する。
  4. 出力したPNGファイルを、Unityプロジェクト内の元のテクスチャファイルと同じフォルダに、同じファイル名で上書き保存する。

ファイルを上書きすると、Unityが自動的に変更を検知し、アバターの見た目に反映してくれます。非常に便利です。

編集前後の瞳テクスチャ比較

【つまずきポイント】消したはずのハイライトが表示される? → シェイプキーの罠

瞳テクスチャを更新した際、「あれ?テクスチャ編集で消したはずの瞳のハイライトやクローバー柄が表示されている…?」という現象に遭遇しました。

【原因と解決策】 これは、テクスチャではなく「シェイプキー」で制御されている要素でした。シェイプキーとは、アバターの特定の部位の形状をスライダーで変化させられる機能のことで、表情の変化(目パチ、口パク)や、こうした細かい装飾の表示/非表示に使われることがあります。

UnityのInspectorウィンドウで、アバターの顔や体のメッシュ(Skinned Mesh Renderer)を選択し、「BlendShapes」(シェイプキーのこと)の項目を確認します。そこにハイライトや柄に対応する名前のスライダーがあれば、その値を調整することで表示を消すことができました。(つまり、テクスチャから消す必要はなかった…!)

UnityのInspectorでシェイプキー(BlendShapes)を調整する様子

ついでに、落ち着いた雰囲気にするために瞼を少し下げるシェイプキーも調整。シェイプキーはアバターの個性を出す上で非常に強力な機能ですね。

服の色の変更については、瞳の色に合わせて、元の黒色ベースの服テクスチャに紺色のレイヤーを重ねて色調を変更したものを、同様に上書きする方法で対応しました。もっと凝るなら、模様を描き足したりするのも面白そうです。

瞳と服の色を改変した後のマヌカちゃん

これで、だいぶ目標としていた「落ち着いてミステリアス」なイメージに近づいてきました。


モデルの改変:髪型の変更(対応髪型とエラー対処)

新しい髪型に変更したマヌカちゃん

仕上げに髪型も変更します。ここでも「マヌカ対応」の髪型アセットがBoothに豊富にあり、イメージに合うものをすぐに見つけることができました。人気アバターならではの利点ですね。

今回は、かやすとあさんの「みみだしボブ」を購入しました。

みみだしボブ【Manuka Hairstyle】 – かやすとあ (Booth)

マヌカちゃんデフォルトのお団子ヘアも可愛いですが、今回のコンセプトにはボブの落ち着いたシルエットが合うと考えました。(付属のリボンはアクセントとして残し、サイズを最大に変更しました)

髪型とリボンを変更した完成形のマヌカちゃん

【つまずきポイント】髪型セットアップ時のエラー

衣装と同様に、購入した髪型のPrefabをアバターのオブジェクトに入れてセットアップしようとした際に、エラーが発生することがありました。(特にModular Avatarなどのツールを使っている場合)

髪型セットアップ時のエラーメッセージ例

【解決策】 このような場合、髪型オブジェクトに「MA Bone Proxy」(Modular Avatarに含まれるコンポーネント)を追加し、そのコンポーネントの「Bone Reference」にアバターの「Head」ボーンを指定することで解決できる場合があります。これにより、髪が頭に正しく追従するようになります。(この設定を行えば、再度セットアップツールを適用する必要はありません)

MA Bone Proxyコンポーネントの設定例

アセットによっては導入方法が異なる場合があるので、付属のReadmeなどをよく確認することが大切です。


まとめ:初めてのアバター改変は学びが多くて楽しい!

改変したアバターの集合写真

今回は「はじめてのVRChatモデル導入と改変」として、人気アバター「マヌカ」ちゃんをベースに、衣装や髪型の購入・導入、瞳や服のテクスチャ編集・色変更に挑戦しました。

VRChat公式ツール「VCC」の登場や、Boothでの豊富な対応アセット、そして多くの先人たちが残してくれた分かりやすい解説記事のおかげで、初心者でも比較的スムーズに、そして楽しくアバター改変を進めることができました。関係者の皆様に感謝です。

目標としていた「落ち着いてミステリアス」な雰囲気のマヌカちゃんも、なんとか形になったのではないかと思います。

最終目標であるBlenderでのフルスクラッチモデル制作への道はまだ遠いですが、今回のような改変作業を通して、テクスチャ編集やUnityの操作、アバターの構造(Armatureやシェイプキー)についての理解を少しずつ深めることができました。今後もVRoidモデルの導入などを試しつつ、学習を続けていけば、いつか目標に到達できるかもしれない、と感じています。

何よりも、自分の手でアバターが変化していく過程は非常に面白かったです。この記事が、これからVRChatアバターの世界に足を踏み入れようとしている方、初めてのアバター改変に挑戦しようとしている方の、何かしらの参考になれば幸いです。次回は「ギミック組み込み」など、もう少し複雑な改変にも挑戦してみたいと思います!


おまけ:初めての自作ワールド挑戦と失敗

自作ワールドでの失敗シーン

アバター改変と並行して、VRChatの「ワールド制作」にも少しだけ挑戦してみました。「ワールド作るならアスレチックでしょ!」と安易に考えた結果、見事に壁にぶつかりました。

特に難しかったのが「移動する床にプレイヤーを乗せる」という処理です。通常のゲーム開発の感覚で動く床を配置しても、VRChatではプレイヤーが床の動きに追従せず、そのまま下に落ちてしまいます。これは、VRChatがオンラインゲームであり、複数プレイヤーの位置情報を常に同期させる必要があるため、単純な物理演算だけではうまくいかないようです。

椅子に座らせるなどのギミックを使えば回避できるそうですが、移動床を実現するにはかなりテクニカルな実装が必要になるとのこと。まずは基本的なワールド構築から学んでいこうと思います。

【RPGツクールMV/MZ】マップ単位でキャラクターを自動切り替えするプラグイン UM_MapActorSetting.js

RPGツクールMVRPGツクールMZで、複数の主人公が登場したり、特定のマップでは特定のキャラクターを操作したりするようなゲームを作りたいと思ったことはありませんか?

通常、マップごとに操作キャラクターを切り替えるには、マップ遷移イベントや場所移動イベントの中に「パーティリーダーの変更」コマンドを配置する必要があります。しかし、対象となるマップが多い場合、この方法は以下のような課題があります。

  • マップごとにイベントを設定・コピーする手間がかかる
  • 設定漏れやキャラクターの指定ミスなど、バグの原因になりやすい。
  • どのマップでどのキャラクターがリーダーになるのか、後から確認・管理するのが大変

これらの課題を解決するために、マップのメモ欄に簡単なタグを記述するだけで、そのマップに入った際に自動的に指定したキャラクターに操作を切り替えるプラグイン「UM_MapActorSetting.js」を作成しました。

この記事では、この自作プラグインの機能、導入方法、設定手順、そして具体的な使用例について解説します。イベントコマンドを使わずに、もっと手軽にキャラクター切り替えを実装したい方におすすめです。

マップ移動時に自動で操作キャラクターが切り替わる様子


この記事の内容

  1. プラグインの概要とメリット
  2. プラグインのインストール方法
  3. 基本的な設定手順 (パラメータとマップメモ)
  4. 具体的な使用例 (勇者と姫の切り替え)
  5. 使用上の注意点
  6. プラグインコード (UM_MapActorSetting.js)

プラグインの概要とメリット

前述の通り、RPGツクールMV/MZでマップごとに操作キャラクターを切り替える標準的な方法は、イベントコマンド「パーティリーダーの変更」を使用することです。しかし、この方法はマップ数が多くなるほど設定が煩雑になり、管理も大変です。

UM_MapActorSetting.js プラグインは、この問題を解決するために開発されました。

主な機能とメリット:

  • マップのメモ欄で指定: どのマップでどのキャラクターを操作させるかを、各マップの「メモ」欄に簡単なタグ(例: ``)で指定します。
  • 自動切り替え: プレイヤーがメモタグを設定したマップに移動すると、プラグインが自動的にパーティの先頭キャラクター(操作キャラクター)を指定されたアクターに入れ替えます。
  • イベント不要: マップごとに切り替え用のイベントを作成・配置する必要がなくなります。
  • 設定がシンプル: プラグインパラメータで「識別子」と「アクターID」を紐付け、マップメモに識別子を書くだけなので、設定が簡単で、後からの確認や変更も容易です。

これにより、複数キャラクターを切り替えるゲームの開発がよりスムーズになります。

プラグインのインストール方法

プラグインの導入は簡単です。

  1. この記事の最後にあるプラグインコードをコピーし、テキストエディタ(メモ帳など)に貼り付けて、ファイル名を `UM_MapActorSetting.js` として保存します。
  2. 作成した `UM_MapActorSetting.js` ファイルを、あなたのRPGツクールプロジェクトフォルダ内の `js/plugins` フォルダに配置します。
  3. RPGツクールエディタを開き、「ツール」メニューから「プラグイン管理」を開きます。
  4. プラグインリストの空いている行をダブルクリックし、「名前」のドロップダウンから `UM_MapActorSetting` を選択し、「状態」を「ON」にして「OK」をクリックします。

RPGツクールMV/MZのプラグイン管理画面でUM_MapActorSettingを有効化

これでプラグインが有効になりました。

基本的な設定手順 (パラメータとマップメモ)

次に、プラグインが正しく動作するように設定を行います。

プラグインパラメータの設定

まず、マップのメモ欄で使う「識別子(任意の文字列)」と、実際に切り替える「アクター(キャラクター)」を紐付けます。

  1. プラグイン管理画面で `UM_MapActorSetting` をダブルクリック(または選択してEnter)し、右側の「パラメータ」欄を開きます。
  2. 「ActorSettings」(アクター設定リスト)という項目をダブルクリックします。
  3. リストの空いている行をダブルクリック(または下の「+」ボタン的なものを操作)して、新しい設定を追加します。
  4. 追加した行で、以下の2つの項目を設定します。
    • Character ID (キャラクターID): マップのメモ欄で使用する任意の識別子(半角英数字推奨、例: `hero`, `princess`, `actor1` など)を入力します。
    • Actor (アクター): 右側のプルダウンメニューから、この識別子に対応させたいアクターをデータベースから選択します。
  5. 切り替えたいキャラクターの数だけ、この設定を追加します。
  6. 設定が終わったら「OK」をクリックして閉じます。

プラグインパラメータActorSettingsの設定画面を開く

Character IDとActorを設定する

マップメモの設定

次に、操作キャラクターを切り替えたいマップ側で設定を行います。

  1. RPGツクールエディタで、操作キャラクターを自動で切り替えたいマップを開きます。
  2. マップ編集画面で、マップ名を右クリック(または編集モードでマップを選択)し、「マップ設定」(または「マップのプロパティ」)を開きます。
  3. 右下にある「メモ」欄に、以下の形式でタグを記述します。
    <Player:識別子>

    識別子 の部分には、プラグインパラメータで設定した「Character ID」を正確に入力します。(例: `<Player:hero>`)

  4. 設定したら「OK」をクリックして閉じます。

マップ設定のメモ欄にタグを記述する

これで、プレイヤーがこのマップに移動してきた際に、<Player:識別子> タグで指定された識別子に対応するアクターが、自動的にパーティの先頭(操作キャラクター)になります。

具体的な使用例 (勇者と姫の切り替え)

例として、「アクターID: 1」が「勇者」、「アクターID: 2」が「姫」としてデータベースに登録されているとします。

1. プラグインパラメータの設定:

プラグイン管理画面で以下のように設定します。

勇者(hero)と姫(princess)のパラメータ設定例

  • 設定1:
    • Character ID: hero
    • Actor: 0001: 勇者 (データベースのアクターID 1)
  • 設定2:
    • Character ID: princess
    • Actor: 0002: 姫 (データベースのアクターID 2)

プラグインパラメータ設定後のリスト表示

2. マップメモの設定:

例えば、2つのマップに対して以下のようにメモを設定します。

  • マップ1(勇者の街)のメモ欄:
    <Player:hero>
  • マップ2(お城)のメモ欄:
    <Player:princess>

結果:

  • プレイヤーが「勇者の街」マップに入ると、操作キャラクターが自動的に「勇者」になります。
  • プレイヤーが「お城」マップに入ると、操作キャラクターが自動的に「姫」になります。

マップ移動でキャラクターが切り替わるデモ

このように、イベントコマンドを一切使わずに、マップごとの操作キャラクター切り替えを実現できます。

使用上の注意点

  • キャラクターの切り替えは、マップ遷移時(場所移動コマンド実行後など)とゲームロード時に自動的に行われます。
  • マップのメモ欄に記述するタグ <Player:識別子> の「識別子」部分は、プラグインパラメータで設定した「Character ID」と完全に一致させてください。大文字・小文字も区別されます。記述を間違えると切り替えは機能しません。
  • プラグインは、指定されたアクターをパーティの先頭に入れ替える(元々いた場合は先頭にし、いなければ追加して先頭にする)シンプルな動作をします。パーティメンバー全体の入れ替えや並び順の制御は行いません。もし元々パーティにいないアクターを指定した場合、そのアクターがパーティに追加されてリーダーになります。(元のリーダーはパーティから外れます)
  • データベースで新しいアクターを追加・変更した場合や、プラグインパラメータの「Character ID」を変更した場合は、必ずプラグインパラメータの設定も更新してください。
  • 他のパーティメンバー変更系プラグインと競合する可能性はあります。併用する場合はご注意ください。

プラグインコード (UM_MapActorSetting.js)

このプラグインコードはご自由にお使いください。改変なども問題ありません。


//=============================================================================
// UM_MapActorSetting
//=============================================================================

/*:
 * @plugindesc マップのメモタグに基づいて、自動的にプレイヤーキャラクターを切り替えます。
 * @author UHIMA
 *
 * @param MapActorSettings
 * @text アクター設定
 * @type struct<ActorConfig>[]
 * @desc 各アクターの設定
 *
 * @help
 * ============================================================================
 * ■ 概要
 * ============================================================================
 * このプラグインは、マップのメモタグに基づいて自動的にプレイヤーキャラクターを
 * 切り替えることを可能にします。
 *
 * ============================================================================
 * ■ 使用方法
 * ============================================================================
 * プレイヤーキャラクターを切り替えたいマップには、以下のメモタグを追加してください:
 *
 * <Player:characterId>
 *
 * プラグインパラメータで「データベース」のアクターIDとキャラクター名を紐づけることができます。
 * これにより<Player:harold>のような簡易的な記述でアクターを切り替えることができます。
 * 新規キャラクターを追加した場合やアクターIDを変更した場合は、このプラグインの紐づけも対応させてください。
 *
 * 例:
 * <Player:harold>
 */

/*~struct~ActorConfig:
 * @param Character ID
 * @text キャラクターID
 * @type string
 * @desc マップメモタグで使用する識別子(例:harold)
 *
 * @param Actor
 * @text アクター
 * @type actor
 * @desc 切り替えるアクター
 */

(function () {
  var parameters = PluginManager.parameters("UM_MapActorSetting");
  var MapActorSettings = JSON.parse(parameters["MapActorSettings"] || "[]").map(
    (setting) => JSON.parse(setting)
  );

  var _Game_Player_performTransfer = Game_Player.prototype.performTransfer;
  Game_Player.prototype.performTransfer = function () {
    _Game_Player_performTransfer.call(this);
    switchActorByMap();
  };

  function switchActorByMap() {
    if ($dataMap && $dataMap.meta.Player) {
      var characterId = $dataMap.meta.Player;
      var actorConfig = MapActorSettings.find(
        (config) => config["Character ID"] === characterId
      );

      if (actorConfig) {
        var newActorId = Number(actorConfig.Actor);
        var currentLeader = $gameParty.leader();
        var currentLeaderId = currentLeader ? currentLeader.actorId() : null;

        if (currentLeaderId !== newActorId) {
          if (currentLeaderId) {
            $gameParty.removeActor(currentLeaderId);
          }
          $gameParty.addActor(newActorId);
          $gamePlayer.refresh();
        }
      }
    }
  }

  var _Scene_Map_start = Scene_Map.prototype.start;
  Scene_Map.prototype.start = function () {
    _Scene_Map_start.call(this);
    switchActorByMap();
  };
})();