<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Unity | アリッシアの朝</title>
	<atom:link href="https://alicia-ing.com/category/programming/unity/feed/" rel="self" type="application/rss+xml" />
	<link>https://alicia-ing.com</link>
	<description></description>
	<lastBuildDate>Sun, 18 Oct 2026 15:42:37 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.3</generator>

<image>
	<url>https://alicia-ing.com/wp-content/uploads/2023/05/cropped-alicia-32x32.webp</url>
	<title>Unity | アリッシアの朝</title>
	<link>https://alicia-ing.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>【Unity】矢印キーで2Dプレイヤーを1マスずつ移動</title>
		<link>https://alicia-ing.com/programming/unity/2dplayermove/</link>
					<comments>https://alicia-ing.com/programming/unity/2dplayermove/#respond</comments>
		
		<dc:creator><![CDATA[アリッシア]]></dc:creator>
		<pubDate>Sun, 27 Sep 2026 04:43:53 +0000</pubDate>
				<category><![CDATA[Unity]]></category>
		<category><![CDATA[タイルマップ]]></category>
		<guid isPermaLink="false">https://alicia-ing.com/?p=8971</guid>

					<description><![CDATA[昔のRPGのように、キャラクターがマス目にそってカクカクと動く移動するゲームは3Dゲームよりも制作の負担もなく現在もレトロゲームや同人ゲームとして人気が強いです。 Tilemapでマップを作ったあと、「プレイヤーを1マス [&#8230;]]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-cocoon-blocks-label-box-1 label-box block-box not-nested-style cocoon-block-label-box"><div class="label-box-label block-box-label box-label fab-flag"><span class="label-box-label-text block-box-label-text box-label-text">本記事を読むと以下の実行ができます</span></div><div class="label-box-content block-box-content box-content">
<p class="wp-block-paragraph">矢印キーで2Dプレイヤーをタイル1マスずつ動かし、長押しでの連続移動と、進む方向に合わせた向きの画像の切り替えができるようになります。</p>



<figure class="wp-block-image size-full"><img decoding="async" src="https://alicia-ing.com/wp-content/uploads/2026/09/complete-1.webp" alt=""/></figure>
</div></div>



<p class="wp-block-paragraph">昔のRPGのように、<strong>キャラクターがマス目にそってカクカクと動く移動するゲーム</strong>は3Dゲームよりも制作の負担もなく現在もレトロゲームや同人ゲームとして人気が強いです。</p>



<p class="wp-block-paragraph">Tilemapでマップを作ったあと、「プレイヤーを1マスずつ動かすにはどうすればいいの？」とつまずく人も多いはずです。</p>



<p class="wp-block-paragraph">本記事では、2dキャラクターの実装として、Input.GetKeyを使ったキー入力から1マスずつの移動・向きの切り替えまでを解説します。キーを押しっぱなしにしたときの連続移動や、2つのキーを同時に押したときの優先順位など、実際に遊ぶと気になる動きにも対応しています。</p>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-info-circle"></span>3Dのキャラクター移動を解説しています。</span></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together">

<a target="_self" href="https://alicia-ing.com/programming/unity/3dplayermove/" title="【Unity】Rigidbody+CapsuleColliderを用いたプレイヤー移動" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img fetchpriority="high" decoding="async" width="320" height="180" src="https://alicia-ing.com/wp-content/uploads/2026/07/3dplayermove-320x180.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://alicia-ing.com/wp-content/uploads/2026/07/3dplayermove-320x180.webp 320w, https://alicia-ing.com/wp-content/uploads/2026/07/3dplayermove-240x135.webp 240w, https://alicia-ing.com/wp-content/uploads/2026/07/3dplayermove-640x360.webp 640w" sizes="(max-width: 320px) 100vw, 320px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【Unity】Rigidbody+CapsuleColliderを用いたプレイヤー移動</div><div class="blogcard-snippet internal-blogcard-snippet">UnityでCharacterControllerからRigidbody+CapsuleColliderへ移動処理を移行する方法を解説。カメラ相対移動、FixedUpdateでの速度制御、移行の判断基準まで紹介します。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img decoding="async" src="https://www.google.com/s2/favicons?domain=https://alicia-ing.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">alicia-ing.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2026.07.13</div></div></div></div></a>
</div>



<div class="wp-block-cocoon-blocks-label-box-1 label-box block-box cocoon-block-label-box"><div class="label-box-label block-box-label box-label fab-check"><span class="label-box-label-text block-box-label-text box-label-text">本記事は次の人におすすめ</span></div><div class="label-box-content block-box-content box-content">
<ul class="wp-block-list">
<li>矢印キーで2Dキャラクターを1マスずつ動かしたい人</li>



<li>Tilemapで作ったマップの上をプレイヤーに歩かせたい人</li>



<li>unity キー 入力（GetKey・GetKeyDown）の違いと使い分けを知りたい人</li>



<li>キーを押しっぱなしにしたときに、ちょうど良い速さで連続移動させたい人</li>



<li>進む方向に合わせてキャラクターの画像を上下左右に切り替えたい人</li>
</ul>
</div></div>



<h2 class="wp-block-heading">Input.GetKey（キー入力）</h2>



<figure class="wp-block-image size-full"><img decoding="async" width="1672" height="941" src="https://alicia-ing.com/wp-content/uploads/2026/09/input-getkey.webp" alt="" class="wp-image-8981" srcset="https://alicia-ing.com/wp-content/uploads/2026/09/input-getkey.webp 1672w, https://alicia-ing.com/wp-content/uploads/2026/09/input-getkey-300x169.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/09/input-getkey-768x432.webp 768w, https://alicia-ing.com/wp-content/uploads/2026/09/input-getkey-1024x576.webp 1024w, https://alicia-ing.com/wp-content/uploads/2026/09/input-getkey-1536x864.webp 1536w, https://alicia-ing.com/wp-content/uploads/2026/09/input-getkey-240x135.webp 240w, https://alicia-ing.com/wp-content/uploads/2026/09/input-getkey-320x180.webp 320w, https://alicia-ing.com/wp-content/uploads/2026/09/input-getkey-640x360.webp 640w" sizes="(max-width: 1672px) 100vw, 1672px" /></figure>



<p class="wp-block-paragraph">Input.GetKeyは、<strong>キーボードのキーが押されているかどうか</strong>を調べる関数です。矢印キーでキャラクターを動かす、スペースキーでジャンプする、Escキーでメニューを開くなど、<strong>キーボードで操作するゲーム</strong>のほとんどで使われます。</p>



<p class="wp-block-paragraph">使い方は、調べたいキーをKeyCodeで指定するだけです。矢印キーはそれぞれ次のKeyCodeに対応しています。</p>



<figure class="wp-block-table"><div class="scrollable-table"><table class="has-fixed-layout"><thead><tr><th>キー</th><th>Keycode</th></tr></thead><tbody><tr><td>↑　上</td><td>KeyCode.UpArrow</td></tr><tr><td>↓　下</td><td>KeyCode.DownArrow</td></tr><tr><td>→　右</td><td>KeyCode.RightArrow</td></tr><tr><td>←　左</td><td>KeyCode.LeftArrow</td></tr></tbody></table></div></figure>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>if (Input.GetKey(KeyCode.RightArrow))
{
    // →キーが押されている間、毎フレーム実行される
}</code></pre></div>



<p class="wp-block-paragraph">キー入力の処理は、毎フレーム呼ばれるUpdate()の中に書きます。</p>



<p class="wp-block-paragraph">参考：<a target="_self" href="https://docs.unity3d.com/ja/current/ScriptReference/Input.GetKey.html">Input.GetKey &#8211; Unity スクリプトリファレンス</a></p>



<h3 class="wp-block-heading">GetKey・GetKeyDown・GetKeyUpの違い</h3>



<p class="wp-block-paragraph">キー入力を調べる関数は3種類あり、trueを返すタイミングが違います。</p>



<figure class="wp-block-table"><div class="scrollable-table"><table class="has-fixed-layout"><thead><tr><th class="has-text-align-left" data-align="left">関数</th><th class="has-text-align-left" data-align="left">trueになるタイミング</th><th class="has-text-align-left" data-align="left">主な用途</th></tr></thead><tbody><tr><td>Input.GetKey</td><td>キーを押している間ずっと（毎フレーム）</td><td>押しっぱなしで動き続ける移動・ダッシュ</td></tr><tr><td>Input.GetKeyDown</td><td>キーを押した瞬間の1フレームだけ</td><td>ジャンプ・決定・1回だけの移動</td></tr><tr><td>Input.GetKeyUp</td><td>キーを離した瞬間の1フレームだけ</td><td>ため攻撃の発射・長押しの終了</td></tr></tbody></table></div></figure>



<p class="wp-block-paragraph">1マスずつ動かしたい場合、GetKeyだけを使うと毎フレーム1マス進んでしまい、一瞬で画面の端まで飛んでいってしまいます。反対にGetKeyDownだけを使うと、押すたびに1マスしか進まず、長い距離を歩くときにキーを何度も叩くことになります。</p>



<p class="wp-block-paragraph">そこで本記事のコードでは、2つを組み合わせています。</p>



<ul class="wp-block-list">
<li><strong>GetKeyDown：</strong> どのキーが「新しく押されたか」を調べる</li>



<li><strong>GetKey：</strong> そのキーが「まだ押され続けているか」を調べ、一定の間隔で連続移動する</li>
</ul>



<h2 class="wp-block-heading">event Action（C#のイベント）で処理をつなぐ</h2>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1672" height="941" src="https://alicia-ing.com/wp-content/uploads/2026/09/event-action.webp" alt="" class="wp-image-8982" srcset="https://alicia-ing.com/wp-content/uploads/2026/09/event-action.webp 1672w, https://alicia-ing.com/wp-content/uploads/2026/09/event-action-300x169.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/09/event-action-768x432.webp 768w, https://alicia-ing.com/wp-content/uploads/2026/09/event-action-1024x576.webp 1024w, https://alicia-ing.com/wp-content/uploads/2026/09/event-action-1536x864.webp 1536w, https://alicia-ing.com/wp-content/uploads/2026/09/event-action-240x135.webp 240w, https://alicia-ing.com/wp-content/uploads/2026/09/event-action-320x180.webp 320w, https://alicia-ing.com/wp-content/uploads/2026/09/event-action-640x360.webp 640w" sizes="(max-width: 1672px) 100vw, 1672px" /></figure>



<p class="wp-block-paragraph">eventは、<strong>「何かが起きたこと」を他のスクリプトに知らせるためのC#の仕組み</strong>です。Actionと組み合わせると、知らせるときに値（移動方向など）も一緒に渡せます。</p>



<p class="wp-block-paragraph">例えば「キーが押された」ことを入力のスクリプトが知らせ、それを受け取った移動のスクリプトがプレイヤーを動かす、という使い方をします。</p>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>// 知らせる側
public event Action&lt;Vector3&gt; MoveRequested;   // Vector3（方向）を一緒に渡すイベント
MoveRequested?.Invoke(Vector3.up);            // 登録されている処理をまとめて呼ぶ

// 受け取る側
input.MoveRequested += OnMoveRequested;       // 登録
input.MoveRequested -= OnMoveRequested;       // 解除</code></pre></div>



<figure class="wp-block-table"><div class="scrollable-table"><table class="has-fixed-layout"><thead><tr><th class="has-text-align-left" data-align="left">書き方</th><th class="has-text-align-left" data-align="left">意味</th></tr></thead><tbody><tr><td>event Action</td><td>値を渡さないイベント</td></tr><tr><td>event Action&lt;T></td><td>値を1つ渡すイベント</td></tr><tr><td>event Action&lt;T1, T2></td><td>値を2つ渡すイベント</td></tr><tr><td>?.Invoke(&#8230;)</td><td>登録している処理があれば呼び出す（誰も登録していなければ何もしない）</td></tr></tbody></table></div></figure>



<p class="wp-block-paragraph">イベントを使うと、入力・移動・画像の切り替えを別々のスクリプトに分けられます。それぞれのスクリプトはお互いの中身を知らなくてよいため、後から「NPCにも同じ移動を使いたい」「入力をゲームパッドに変えたい」となったときに、一部だけを差し替えられます。</p>



<p class="wp-block-paragraph">なお、Unityには<strong>Inspectorから登録できるUnityEvent</strong>もあります。本記事ではコードの中だけで完結させるため、C#のeventを使っています。</p>



<p class="wp-block-paragraph">参考：<a target="_self" href="https://learn.microsoft.com/ja-jp/dotnet/csharp/programming-guide/events/">イベント &#8211; C# プログラミング ガイド（Microsoft Learn）</a></p>



<h2 class="wp-block-heading">SpriteRenderer.spriteで画像を差し替える</h2>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1672" height="941" src="https://alicia-ing.com/wp-content/uploads/2026/09/spriteRenderer.webp" alt="" class="wp-image-8983" srcset="https://alicia-ing.com/wp-content/uploads/2026/09/spriteRenderer.webp 1672w, https://alicia-ing.com/wp-content/uploads/2026/09/spriteRenderer-300x169.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/09/spriteRenderer-768x432.webp 768w, https://alicia-ing.com/wp-content/uploads/2026/09/spriteRenderer-1024x576.webp 1024w, https://alicia-ing.com/wp-content/uploads/2026/09/spriteRenderer-240x135.webp 240w, https://alicia-ing.com/wp-content/uploads/2026/09/spriteRenderer-1536x864.webp 1536w, https://alicia-ing.com/wp-content/uploads/2026/09/spriteRenderer-320x180.webp 320w, https://alicia-ing.com/wp-content/uploads/2026/09/spriteRenderer-640x360.webp 640w" sizes="(max-width: 1672px) 100vw, 1672px" /></figure>



<p class="wp-block-paragraph">SpriteRendererは、<strong>2Dの画像（スプライト）を画面に表示するコンポーネント</strong>です。<br>spriteプロパティに別のスプライトを代入すると、表示している画像をその場で差し替えられます。</p>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>playerRenderer.sprite = spriteUp;   // 上向きの画像に切り替える</code></pre></div>



<p class="wp-block-paragraph">キャラクターの向きを変える方法には、ほかにAnimatorでアニメーションを切り替える方法もあります。</p>



<p class="wp-block-paragraph"><strong>歩きのアニメーションまで作り込みたい場合はAnimatorが向いています</strong>が、上下左右の4枚の画像を切り替えるだけなら、spriteを差し替える方法の方が設定が少なく済みます。</p>



<figure class="wp-block-table"><div class="scrollable-table"><table class="has-fixed-layout"><thead><tr><th class="has-text-align-left" data-align="left">方法</th><th class="has-text-align-left" data-align="left">向いている場面</th></tr></thead><tbody><tr><td>SpriteRenderer.spriteの差し替え</td><td>上下左右の静止画を切り替えるだけのとき（本記事）</td></tr><tr><td>Animator（Blend Tree）</td><td>方向ごとに歩きのアニメーションを付けたいとき</td></tr></tbody></table></div></figure>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-info-circle"></span>オブジェクトが表示されないエラーについて紹介しています。</span></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together">

<a target="_self" href="https://alicia-ing.com/programming/unity/render-camera/" title="【Unity】2D/3Dオブジェクトが表示されない原因と対処方法" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://alicia-ing.com/wp-content/uploads/2024/06/Screen-Space-Camera-160x90.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://alicia-ing.com/wp-content/uploads/2024/06/Screen-Space-Camera-160x90.webp 160w, https://alicia-ing.com/wp-content/uploads/2024/06/Screen-Space-Camera-120x68.webp 120w, https://alicia-ing.com/wp-content/uploads/2024/06/Screen-Space-Camera-320x180.webp 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【Unity】2D/3Dオブジェクトが表示されない原因と対処方法</div><div class="blogcard-snippet internal-blogcard-snippet">2D/3Dオブジェクトが表示されない原因は、カメラワークの不具合が考えられます。「Screen Space - Camera」にして、MainCameraをアタッチすると正しく表示されます。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img decoding="async" src="https://www.google.com/s2/favicons?domain=https://alicia-ing.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">alicia-ing.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2024.11.10</div></div></div></div></a>
</div>



<p class="wp-block-paragraph">参考：<a target="_self" href="https://docs.unity3d.com/ja/current/ScriptReference/SpriteRenderer-sprite.html">SpriteRenderer.sprite &#8211; Unity スクリプトリファレンス</a></p>



<h2 class="wp-block-heading">矢印キーで1マスずつ動く2Dプレイヤー移動</h2>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1672" height="941" src="https://alicia-ing.com/wp-content/uploads/2026/09/keymove.webp" alt="" class="wp-image-8984" srcset="https://alicia-ing.com/wp-content/uploads/2026/09/keymove.webp 1672w, https://alicia-ing.com/wp-content/uploads/2026/09/keymove-300x169.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/09/keymove-768x432.webp 768w, https://alicia-ing.com/wp-content/uploads/2026/09/keymove-1024x576.webp 1024w, https://alicia-ing.com/wp-content/uploads/2026/09/keymove-240x135.webp 240w, https://alicia-ing.com/wp-content/uploads/2026/09/keymove-320x180.webp 320w, https://alicia-ing.com/wp-content/uploads/2026/09/keymove-1536x864.webp 1536w, https://alicia-ing.com/wp-content/uploads/2026/09/keymove-640x360.webp 640w" sizes="(max-width: 1672px) 100vw, 1672px" /></figure>



<p class="wp-block-paragraph">ここまでに説明したInput.GetKey・event Action・SpriteRenderer.spriteを組み合わせて、Tilemapの上を1マスずつ歩く2Dプレイヤーを作ります。実装する動きは次のとおりです。</p>



<ul class="wp-block-list">
<li><strong>1マスずつ移動：</strong> 矢印キーを押すと、上下左右に1マス分だけ移動する</li>



<li><strong>長押しで連続移動：</strong> キーを押しっぱなしにすると、少し待ってから一定の間隔で進み続ける</li>



<li><strong>同時押しの優先：</strong> 2つのキーを押したときは、後から押したキーの方向へ進む（斜めには進まない）</li>



<li><strong>向きの切り替え：</strong> 進む方向に合わせて、キャラクターの画像を上下左右に切り替える</li>



<li><strong>止まったときの表示：</strong> キーを離したら「待機画像」か「最後に向いた方向」のどちらかを表示する</li>
</ul>



<p class="wp-block-paragraph">処理は役割ごとに5つのスクリプトに分けています。</p>



<figure class="wp-block-table"><div class="scrollable-table"><table class="has-fixed-layout"><thead><tr><th class="has-text-align-left" data-align="left">スクリプト</th><th class="has-text-align-left" data-align="left">役割</th></tr></thead><tbody><tr><td>PlayerInput.cs</td><td>矢印キーの入力から動く方向を決める</td></tr><tr><td>GridMover.cs</td><td>対象を1マス動かし「動こうとした」「動いた」と知らせる</td></tr><tr><td>PlayerDirectionSprite.cs</td><td>向きに合わせて画像を差し替える</td></tr><tr><td>PlayerSpawner.cs</td><td>ゲーム開始時の位置と向きを決める</td></tr><tr><td>PlayerController.cs</td><td>上の4つをイベントでつなぐ</td></tr></tbody></table></div></figure>



<h3 class="wp-block-heading">ソースコード</h3>



<h4 class="wp-block-heading">PlayerInput.cs</h4>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>using System;
using System.Collections.Generic;
using UnityEngine;

/// &lt;summary&gt;
/// 矢印キーから移動の要求
/// &lt;/summary&gt;
public class PlayerInput : MonoBehaviour
{
    [SerializeField] private float repeatDelay = 0.2f;     
    [SerializeField] private float repeatInterval = 0.1f;  
    private float repeatTimer;      

    public event Action&lt;Vector3&gt; MoveRequested; 
    public event Action Released;              
    //入力キーと方向を対応させる
    private static readonly (KeyCode key, Vector3 direction)[] bindings =
    {
        (KeyCode.UpArrow, Vector3.up),
        (KeyCode.DownArrow, Vector3.down),
        (KeyCode.RightArrow, Vector3.right),
        (KeyCode.LeftArrow, Vector3.left),
    };

    // 押された順に並べたbindingsの添字。最後が現在有効なキー
    private readonly List&lt;int&gt; heldKeys = new List&lt;int&gt;();
    private const int None = -1;  // キーを押していない
    private int CurrentIndex =&gt; heldKeys.Count &gt; 0 ? heldKeys[heldKeys.Count - 1] : None;

    private void Update()
    {
        int previousIndex = CurrentIndex;

        heldKeys.RemoveAll(i =&gt; !Input.GetKey(bindings[i].key));
        for (int i = 0; i &lt; bindings.Length; i++)
        {
            if (Input.GetKeyDown(bindings[i].key) && !heldKeys.Contains(i))
                heldKeys.Add(i);
        }
        
        int currentIndex = CurrentIndex;
        if (currentIndex == None)
        {
            if (previousIndex != None) Released?.Invoke();
            return;
        }

        if (currentIndex != previousIndex)
        {
            repeatTimer = repeatDelay;
            MoveRequested?.Invoke(bindings[currentIndex].direction);
            return;
        }

        repeatTimer -= Time.deltaTime;
        if (repeatTimer &lt;= 0f)
        {
            repeatTimer = repeatInterval;
            MoveRequested?.Invoke(bindings[currentIndex].direction);
        }
    }
}</code></pre></div>



<h4 class="wp-block-heading">GridMover.cs</h4>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>using System;
using UnityEngine;

/// &lt;summary&gt;
/// 対象を1マスずつ動かす。向き・移動の通知を行う
/// &lt;/summary&gt;
public class GridMover : MonoBehaviour
{
    [SerializeField] private Transform target;
    [SerializeField] private float gridSize = 1f;

    public event Action&lt;Vector3&gt; MoveAttempted;
    public event Action&lt;Vector3, Vector3&gt; Moved;

    //移動処理
    public bool TryMove(Vector3 direction)
    {
        if (direction == Vector3.zero || target == null) return false;

        MoveAttempted?.Invoke(direction);

        Vector3 nextPos = target.position + direction * gridSize; //移動先

        target.position = nextPos;  //位置更新
        Moved?.Invoke(nextPos, direction);
        return true;
    }
}
</code></pre></div>



<h4 class="wp-block-heading">PlayerDirectionSprite.cs</h4>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>using UnityEngine;

/// &lt;summary&gt;
/// プレイヤーの進行で画像差し替え
/// &lt;/summary&gt;
public class PlayerDirectionSprite : MonoBehaviour
{
    //止まっているときの状態
    private enum IdleFacingMode
    {
        IdleSprite, //待機
        LastDirection //最後に向いている方向
    }

    [SerializeField] private SpriteRenderer playerRenderer;
    [SerializeField] private Sprite spriteIdle;
    [SerializeField] private Sprite spriteUp;
    [SerializeField] private Sprite spriteDown;
    [SerializeField] private Sprite spriteLeft;
    [SerializeField] private Sprite spriteRight;
    [SerializeField] private IdleFacingMode idleFacingMode = IdleFacingMode.LastDirection;

    private Vector3 lastFacingDirection = Vector3.zero;

    //指定した方向を向く
    public void Face(Vector3 direction)
    {
        if (direction == Vector3.zero) return; 

        lastFacingDirection = direction;
        SetSprite(GetSpriteForDirection(direction));
    }

    //止まったときの画像にする
    public void ShowIdle()
    {
        bool hasLastFacing = lastFacingDirection != Vector3.zero;
        bool keepLastFacing = idleFacingMode == IdleFacingMode.LastDirection && hasLastFacing;

        SetSprite(keepLastFacing ? GetSpriteForDirection(lastFacingDirection) : null);
    }

    //画像の差し替え
    private void SetSprite(Sprite sprite)
    {
        if (playerRenderer == null) return;

        Sprite nextSprite = sprite ?? spriteIdle;
        if (nextSprite != null && playerRenderer.sprite != nextSprite)
            playerRenderer.sprite = nextSprite;
    }

    //対応する画像を呼び出す
    private Sprite GetSpriteForDirection(Vector3 direction)
    {
        if (direction == Vector3.up && spriteUp != null) return spriteUp;
        if (direction == Vector3.down && spriteDown != null) return spriteDown;
        if (direction == Vector3.left && spriteLeft != null) return spriteLeft;
        if (direction == Vector3.right && spriteRight != null) return spriteRight;
    
        return null;
    }
}
</code></pre></div>



<h4 class="wp-block-heading">PlayerSpawner.cs</h4>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>using UnityEngine;

/// &lt;summary&gt;
/// シーン開始時のプレイヤーの位置と向きを決める
/// &lt;/summary&gt;
public class PlayerSpawner : MonoBehaviour
{
    [SerializeField] private Transform target;
    [SerializeField] private Vector3 startPosition = new Vector3(0.5f, 0.5f, 0f); 

    // 開始位置に置き、開始時の向きを startFacing に入れる
    public void Spawn(out Vector3 startFacing)
    {
        if (target == null) target = transform;

        target.position = startPosition;
        startFacing = Vector3.zero;
    }
}
</code></pre></div>



<p class="wp-block-paragraph"></p>



<h4 class="wp-block-heading">PlayerController.cs</h4>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>using UnityEngine;

/// &lt;summary&gt;
/// プレイヤーの各コンポーネントの接続
/// 入力 → 移動 → 向きの画像
/// &lt;/summary&gt;
public class PlayerController : MonoBehaviour
{
    [SerializeField] private PlayerInput input;
    [SerializeField] private GridMover mover;
    [SerializeField] private PlayerSpawner spawner;
    [SerializeField] private PlayerDirectionSprite directionSprite; // 向きスプライト制御

    // イベントの登録/解除
    private void OnEnable()
    {
        if (input != null)
        {
            input.MoveRequested += OnMoveRequested; 
            input.Released += OnReleased;
        }
        if (mover != null)
        {
            mover.MoveAttempted += OnMoveAttempted;
        }
    }

    private void OnDisable()
    {
        if (input != null)
        {
            input.MoveRequested -= OnMoveRequested;
            input.Released -= OnReleased;
        }
        if (mover != null)
        {
            mover.MoveAttempted -= OnMoveAttempted;
        }
    }

    private void Start()
    {
        Vector3 startFacing = Vector3.zero;
        if (spawner != null) spawner.Spawn(out startFacing);

        if (directionSprite == null) return;
        if (startFacing == Vector3.zero) directionSprite.ShowIdle();
        else directionSprite.Face(startFacing);
    }

    ///イベントを受け取る
    private void OnMoveRequested(Vector3 direction) =&gt; mover?.TryMove(direction);
    private void OnReleased() =&gt; directionSprite?.ShowIdle();
    private void OnMoveAttempted(Vector3 direction) =&gt; directionSprite?.Face(direction);
}
</code></pre></div>



<h3 class="wp-block-heading">解説</h3>



<ul class="wp-block-list">
<li><strong>名前空間（モジュール）</strong></li>
</ul>



<figure class="wp-block-table"><div class="scrollable-table"><table class="has-fixed-layout"><thead><tr><th class="has-text-align-left" data-align="left">名前空間</th><th class="has-text-align-left" data-align="left">使っている理由</th></tr></thead><tbody><tr><td>UnityEngine</td><td>MonoBehaviour・Input・Vector3・SpriteRendererなど、Unityの基本機能を使うため</td></tr><tr><td>System</td><td>イベントの型Actionを使うため（PlayerInput・GridMover）</td></tr><tr><td>System.Collections.Generic</td><td>押しているキーを順番に覚えるList&lt;int>を使うため（PlayerInput）</td></tr></tbody></table></div></figure>



<ul class="wp-block-list">
<li><strong><strong>イベント</strong></strong></li>
</ul>



<figure class="wp-block-table"><div class="scrollable-table"><table class="has-fixed-layout"><thead><tr><th class="has-text-align-left" data-align="left">スクリプト</th><th class="has-text-align-left" data-align="left">イベント</th><th class="has-text-align-left" data-align="left">知らせる内容</th></tr></thead><tbody><tr><td>PlayerInput</td><td>MoveRequested</td><td>「この方向に動きたい」（方向）</td></tr><tr><td>PlayerInput</td><td>Released</td><td>「矢印キーがすべて離された」</td></tr><tr><td>GridMover</td><td>MoveAttempted</td><td>「この方向に動こうとした」（方向）</td></tr><tr><td>GridMover</td><td>Moved</td><td>「動いた」（移動後の位置・方向）</td></tr></tbody></table></div></figure>



<p class="wp-block-paragraph">処理の流れをまとめると、次のようになります。</p>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-plain"><code>[PlayerInput] 矢印キーを押す → MoveRequested
      ↓
[PlayerController] OnMoveRequested → GridMover.TryMove()
      ↓
[GridMover] MoveAttempted → 1マス移動 → Moved
      ↓
[PlayerController] OnMoveAttempted → PlayerDirectionSprite.Face()（画像を切り替え）

[PlayerInput] キーを離す → Released → PlayerDirectionSprite.ShowIdle()</code></pre></div>



<h4 class="wp-block-heading">キー長押しで連続移動する（repeatDelay・repeatInterval）</h4>



<p class="wp-block-paragraph">PlayerInputのUpdate()では、キーを押したときと、押し続けているときで処理を分けています。</p>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>// 有効なキーが変わった：即移動
if (currentIndex != previousIndex)
{
    repeatTimer = repeatDelay;
    MoveRequested?.Invoke(bindings[currentIndex].direction);
    return;
}

//同じキーを押し続ける
repeatTimer -= Time.deltaTime;
if (repeatTimer &lt;= 0f)
{
    repeatTimer = repeatInterval;
    MoveRequested?.Invoke(bindings[currentIndex].direction);
}
</code></pre></div>



<p class="wp-block-paragraph">キーを押した瞬間はすぐに1マス進み、タイマーにrepeatDelay（0.2秒）をセットします。そのまま押し続けると、タイマーが0になったところで次の1マスに進み、以降はrepeatInterval（0.1秒）ごとに進みます。</p>



<p class="wp-block-paragraph">パソコンでキーを押しっぱなしにしたとき、1文字目のあとに少し間が空いてから文字が連続で入力されるのと同じ仕組みです。最初に少し待つことで、<strong>「1マスだけ動きたかったのに2マス進んでしまった」という誤操作を防げます。</strong></p>



<p class="wp-block-paragraph">Time.deltaTime（前のフレームからの経過時間）を引いているため、フレームレートが変わっても同じ速さで進みます。<strong>歩く速さを変えたいときは、InspectorでRepeat Intervalの値を調整</strong>してください。値を小さくするほど速く歩きます。</p>



<h4 class="wp-block-heading">キー同時押しの優先度</h4>



<p class="wp-block-paragraph">2つの矢印キーを同時に押したときにどちらへ進むかは、heldKeysリストで決めています。</p>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>//リスト更新（離されたキーを外し、新しく押されたキーを末尾に追加）
heldKeys.RemoveAll(i =&gt; !Input.GetKey(bindings[i].key));
for (int i = 0; i &lt; bindings.Length; i++)
{
    if (Input.GetKeyDown(bindings[i].key) && !heldKeys.Contains(i))
        heldKeys.Add(i);
}</code></pre></div>



<ol class="wp-block-list">
<li>RemoveAllで、もう押されていないキーをリストから外す</li>



<li>GetKeyDownで新しく押されたキーを見つけ、リストの<strong>末尾</strong>に追加する</li>
</ol>



<p class="wp-block-paragraph">リストの末尾が「一番最後に押したキー」になり、CurrentIndexはこの末尾のキーを返します。</p>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>private int CurrentIndex =&gt; heldKeys.Count &gt; 0 ? heldKeys[heldKeys.Count - 1] : None;</code></pre></div>



<p class="wp-block-paragraph">例えば、→キーを押しながら↑キーを押すと↑方向へ進みます。そのあと↑キーだけを離すと、リストには→キーが残っているため、すぐに→方向へ戻って進みます。</p>



<p class="wp-block-paragraph">入力をif文で上から順に調べる書き方だと、「↑と→を同時に押すと、いつも↑が勝つ」「同時に押すと斜めに進む」といった動きになりがちです。押した順番を覚えておくことで、プレイヤーの操作に素直に反応する移動になります。</p>



<h2 class="wp-block-heading">実装</h2>



<p class="wp-block-paragraph">5つのスクリプトは、プレイヤーのオブジェクトと、画像を表示するオブジェクトにアタッチします。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1917" height="967" src="https://alicia-ing.com/wp-content/uploads/2026/09/attach-2.webp" alt="" class="wp-image-8990" srcset="https://alicia-ing.com/wp-content/uploads/2026/09/attach-2.webp 1917w, https://alicia-ing.com/wp-content/uploads/2026/09/attach-2-300x151.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/09/attach-2-767x387.webp 767w, https://alicia-ing.com/wp-content/uploads/2026/09/attach-2-1024x517.webp 1024w, https://alicia-ing.com/wp-content/uploads/2026/09/attach-2-1536x775.webp 1536w" sizes="(max-width: 1917px) 100vw, 1917px" /></figure>



<p class="wp-block-paragraph">各スクリプトは[RequireComponent]を使っていないため、必要なコンポーネントは自動で追加されません。SpriteRendererの追加と、PlayerControllerの参照の設定は、忘れずに手動で行ってください。</p>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">本記事では、Tilemapの上で2Dプレイヤーを矢印キーで1マスずつ動かす方法として、次の内容を解説しました。</p>



<ul class="wp-block-list">
<li>Input.GetKeyとGetKeyDownを組み合わせて、押した瞬間の移動と長押しの連続移動を作る</li>



<li>押したキーの順番をListで覚えて、同時押しでは後から押したキーを優先する</li>



<li>SpriteRenderer.spriteを差し替えて、進む方向に合わせて画像を切り替える</li>
</ul>



<p class="wp-block-paragraph">スクリプトを役割ごとに分けているため、ここから機能を足していくのも簡単です。次のステップとして、GridMoverに壁の判定を加えて「壁の方を向くだけで進めない」動きにしたり、Movedイベントを使ってマップの端で別のシーンへ切り替えたりすると、<strong>RPGのマップ移動らしく</strong>なります。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://alicia-ing.com/programming/unity/2dplayermove/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Unity】Input Systemでゲームパッド対応</title>
		<link>https://alicia-ing.com/programming/unity/gamepad-player/</link>
					<comments>https://alicia-ing.com/programming/unity/gamepad-player/#respond</comments>
		
		<dc:creator><![CDATA[アリッシア]]></dc:creator>
		<pubDate>Sat, 26 Sep 2026 12:01:56 +0000</pubDate>
				<category><![CDATA[Unity]]></category>
		<guid isPermaLink="false">https://alicia-ing.com/?p=8956</guid>

					<description><![CDATA[Unityでプレイヤー操作実装する際に、キーボード操作だけでなく「ゲームパッド（コントローラー）にも対応したい」という場面が出てきます。 特にアクションゲームやプラットフォーマーでは、スティックでの移動とボタンでのジャン [&#8230;]]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-cocoon-blocks-label-box-1 label-box block-box not-nested-style cocoon-block-label-box"><div class="label-box-label block-box-label box-label fab-flag"><span class="label-box-label-text block-box-label-text box-label-text">本記事を読むと以下の実行ができます</span></div><div class="label-box-content block-box-content box-content">
<p class="wp-block-paragraph">Input SystemのInputActionReferenceを使って、ゲームパッドでキャラクターの移動とジャンプを操作できるようになります。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="960" height="540" src="https://alicia-ing.com/wp-content/uploads/2026/09/complete.webp" alt="" class="wp-image-8967" srcset="https://alicia-ing.com/wp-content/uploads/2026/09/complete.webp 960w, https://alicia-ing.com/wp-content/uploads/2026/09/complete-300x169.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/09/complete-768x432.webp 768w, https://alicia-ing.com/wp-content/uploads/2026/09/complete-240x135.webp 240w, https://alicia-ing.com/wp-content/uploads/2026/09/complete-320x180.webp 320w, https://alicia-ing.com/wp-content/uploads/2026/09/complete-640x360.webp 640w" sizes="(max-width: 960px) 100vw, 960px" /></figure>
</div></div>



<p class="wp-block-paragraph">Unityでプレイヤー操作実装する際に、キーボード操作だけでなく「ゲームパッド（コントローラー）にも対応したい」という場面が出てきます。</p>



<p class="wp-block-paragraph">特にアクションゲームやプラットフォーマーでは、スティックでの移動とボタンでのジャンプはほぼ必須の操作です。</p>



<p class="wp-block-paragraph">本記事では、Unityの新しいInput SystemとInputActionReferenceを使い、移動・ジャンプという最小構成でゲームパッド対応を実装する方法を分かりやすく解説します。</p>



<p class="wp-block-paragraph">Gamepad.currentを直接参照する方法やPlayerInputコンポーネントに依存する方法とは違う、疎結合で使い回しやすい設計です。</p>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-info-circle"></span>マウス操作の導入を紹介しています。</span></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together">

<a target="_self" href="https://alicia-ing.com/programming/unity/mouse-input/" title="【Unity】マウス操作をゲームに導入する画面クリックで処理" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://alicia-ing.com/wp-content/uploads/2022/12/mouse-input-1-160x90.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://alicia-ing.com/wp-content/uploads/2022/12/mouse-input-1-160x90.webp 160w, https://alicia-ing.com/wp-content/uploads/2022/12/mouse-input-1-120x68.webp 120w, https://alicia-ing.com/wp-content/uploads/2022/12/mouse-input-1-320x180.webp 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【Unity】マウス操作をゲームに導入する画面クリックで処理</div><div class="blogcard-snippet internal-blogcard-snippet">UnityでCSVのテキストをマウスクリックで１つずつ進めるには、if文でメソッド「Input.GetMouseButtonDown(0)」を使用します。ノベルゲームは画面のクリック回数に応じてテキストを表示するシステムに近づきます。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://alicia-ing.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">alicia-ing.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2025.08.11</div></div></div></div></a>
</div>



<div class="wp-block-cocoon-blocks-label-box-1 label-box block-box cocoon-block-label-box"><div class="label-box-label block-box-label box-label fab-check"><span class="label-box-label-text block-box-label-text box-label-text">本記事は次の人におすすめ</span></div><div class="label-box-content block-box-content box-content">
<ul class="wp-block-list">
<li>Unityでゲームパッド（コントローラー）対応を実装したい人</li>



<li>新しいUnity Input Systemの基本的な使い方を知りたい人</li>



<li>InputActionReferenceを使った疎結合な入力処理の設計を学びたい人</li>



<li>Gamepad.currentを直接参照するコードから卒業したい人</li>



<li>ジャンプ入力の判定でバグが起きて困っている人</li>
</ul>
</div></div>



<h2 class="wp-block-heading">Input System</h2>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1672" height="941" src="https://alicia-ing.com/wp-content/uploads/2026/09/Input-System.webp" alt="" class="wp-image-8960" srcset="https://alicia-ing.com/wp-content/uploads/2026/09/Input-System.webp 1672w, https://alicia-ing.com/wp-content/uploads/2026/09/Input-System-300x169.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/09/Input-System-768x432.webp 768w, https://alicia-ing.com/wp-content/uploads/2026/09/Input-System-1024x576.webp 1024w, https://alicia-ing.com/wp-content/uploads/2026/09/Input-System-1536x864.webp 1536w, https://alicia-ing.com/wp-content/uploads/2026/09/Input-System-240x135.webp 240w, https://alicia-ing.com/wp-content/uploads/2026/09/Input-System-320x180.webp 320w, https://alicia-ing.com/wp-content/uploads/2026/09/Input-System-640x360.webp 640w" sizes="(max-width: 1672px) 100vw, 1672px" /></figure>



<p class="wp-block-paragraph">Input Systemは、キーボード・マウス・ゲームパッドなどの入力をまとめて扱える、Unityの新しい入力の仕組みです。</p>



<p class="wp-block-paragraph">XboxコントローラーやPlayStationコントローラー（DualSense）などのゲームパッドに対応したいときや、同じ操作をキーボードとゲームパッドの両方で行えるようにしたいときに使います。</p>



<p class="wp-block-paragraph">従来の<strong>Input.GetAxis()</strong>などを使う古い入力システム（Input Manager）でもある程度のゲームパッド対応は可能でしたが、デバイスごとの差異を吸収しづらく、<strong>コードが複雑になりがち</strong>でした。</p>



<p class="wp-block-paragraph">Input Systemでは、実際の入力デバイスと、ゲーム内の意味（「移動する」「ジャンプする」）を<strong>Input Actionという単位</strong>で分けられます。そのため、デバイスが変わってもコード側を変更せずに済みます。</p>



<p class="wp-block-paragraph">Input Systemを使うには、パッケージの導入と、入力を定義するInput Actionsアセットの作成が必要です。</p>



<p class="wp-block-paragraph">参考：<a target="_self" href="https://docs.unity3d.com/ja/current/Manual/com.unity.inputsystem.html">Input System &#8211; Unity マニュアル</a></p>



<h3 class="wp-block-heading">Input Systemパッケージの導入</h3>



<p class="wp-block-paragraph">Unity Input Systemは標準では有効になっていないため、<strong>Package Managerからインストール</strong>する必要があります。</p>



<ol class="wp-block-list">
<li>メニューから&nbsp;Window &gt; Package Manager&nbsp;を開きます</li>



<li>検索欄で「Input System」を検索し、Install&nbsp;をクリックします</li>



<li>インストール後、「新しい入力システムに切り替えますか？」という確認ダイアログが表示されるので&nbsp;Yes&nbsp;を選択します（Unityの再起動が必要です）</li>
</ol>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1917" height="980" src="https://alicia-ing.com/wp-content/uploads/2026/09/packageManager.webp" alt="" class="wp-image-8961" srcset="https://alicia-ing.com/wp-content/uploads/2026/09/packageManager.webp 1917w, https://alicia-ing.com/wp-content/uploads/2026/09/packageManager-300x153.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/09/packageManager-767x392.webp 767w, https://alicia-ing.com/wp-content/uploads/2026/09/packageManager-1024x523.webp 1024w, https://alicia-ing.com/wp-content/uploads/2026/09/packageManager-1536x785.webp 1536w" sizes="(max-width: 1917px) 100vw, 1917px" /></figure>



<div class="wp-block-cocoon-blocks-icon-box common-icon-box block-box alert-box">
<p class="wp-block-paragraph">Yesを選ぶと、Edit &gt; Project Settings &gt; Player &gt; Active Input Handling が Input System Package (New) に切り替わります。従来のInput Managerを使うコードが他にある場合は、動作しなくなる点に注意してください。両方を併用したい場合は Both を選択します。</p>
</div>



<h3 class="wp-block-heading">Input Actionsアセットとゲームパッドのバインディング設定</h3>



<p class="wp-block-paragraph">次に、実際の入力を定義するInput Actionsアセットを作成します。</p>



<ol class="wp-block-list">
<li>Projectウィンドウで右クリックし、Create &gt; Input Actions を選択してアセットを作成します</li>



<li>作成したアセットをダブルクリックしてエディタを開きます</li>



<li>Action Mapsに「Player」などの名前でマップを作成します</li>
</ol>



<p class="wp-block-paragraph">各アクションの+ボタンからバインディングを追加し、Listen機能を使って実際にゲームパッドを操作するとバインディング候補が自動検出されるので、それを選択すると設定が楽になります。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1360" height="562" src="https://alicia-ing.com/wp-content/uploads/2026/09/Input-Actions.webp" alt="" class="wp-image-8962" srcset="https://alicia-ing.com/wp-content/uploads/2026/09/Input-Actions.webp 1360w, https://alicia-ing.com/wp-content/uploads/2026/09/Input-Actions-300x124.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/09/Input-Actions-767x317.webp 767w, https://alicia-ing.com/wp-content/uploads/2026/09/Input-Actions-1024x423.webp 1024w" sizes="(max-width: 1360px) 100vw, 1360px" /></figure>



<p class="wp-block-paragraph">設定が終わったら忘れずにSave Assetをクリックしてください。</p>



<h2 class="wp-block-heading">InputActionReference</h2>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1672" height="941" src="https://alicia-ing.com/wp-content/uploads/2026/09/InputActionReference.webp" alt="" class="wp-image-8963" srcset="https://alicia-ing.com/wp-content/uploads/2026/09/InputActionReference.webp 1672w, https://alicia-ing.com/wp-content/uploads/2026/09/InputActionReference-300x169.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/09/InputActionReference-768x432.webp 768w, https://alicia-ing.com/wp-content/uploads/2026/09/InputActionReference-1024x576.webp 1024w, https://alicia-ing.com/wp-content/uploads/2026/09/InputActionReference-1536x864.webp 1536w, https://alicia-ing.com/wp-content/uploads/2026/09/InputActionReference-240x135.webp 240w, https://alicia-ing.com/wp-content/uploads/2026/09/InputActionReference-320x180.webp 320w, https://alicia-ing.com/wp-content/uploads/2026/09/InputActionReference-640x360.webp 640w" sizes="(max-width: 1672px) 100vw, 1672px" /></figure>



<p class="wp-block-paragraph">InputActionReferenceは、Input Actionsアセットの中にある特定のInput Actionを、Inspectorから参照するための型です。スクリプトにアクション名を文字列で書かずに、「どのアクションを使うか」をInspectorで選べます。</p>



<figure class="wp-block-table is-style-regular"><div class="scrollable-table"><table class="has-fixed-layout"><thead><tr><th>方法</th><th>特徴</th></tr></thead><tbody><tr><td>Gamepad.currentを直接参照</td><td>コード量は少ないが、デバイスの差し替えや複数デバイス対応がしづらい</td></tr><tr><td>PlayerInputコンポーネント</td><td>イベント駆動で扱いやすいが、コンポーネントへの依存度が高くなる</td></tr><tr><td>InputActionReference</td><td>Inspector上でアクションを差し替え可能。専用の入力ハンドラークラスに集約でき、疎結合な設計にしやすい</td></tr></tbody></table></div></figure>



<p class="wp-block-paragraph">InputActionReferenceは、同じ入力ハンドラークラスを別のキャラクターやプレハブで使い回したり、テスト用に別のInput Actionsアセットへ差し替えたりしやすくなります。</p>



<p class="wp-block-paragraph">参考：<a target="_self" href="https://docs.unity3d.com/Packages/com.unity.inputsystem@1.14/api/UnityEngine.InputSystem.InputActionReference.html">InputActionReference &#8211; Input System ドキュメント</a></p>



<h2 class="wp-block-heading">InputActionReferenceで実装する移動・ジャンプ入力</h2>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1672" height="941" src="https://alicia-ing.com/wp-content/uploads/2026/09/gamepad_Controller.webp" alt="" class="wp-image-8964" srcset="https://alicia-ing.com/wp-content/uploads/2026/09/gamepad_Controller.webp 1672w, https://alicia-ing.com/wp-content/uploads/2026/09/gamepad_Controller-300x169.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/09/gamepad_Controller-768x432.webp 768w, https://alicia-ing.com/wp-content/uploads/2026/09/gamepad_Controller-1024x576.webp 1024w, https://alicia-ing.com/wp-content/uploads/2026/09/gamepad_Controller-1536x864.webp 1536w, https://alicia-ing.com/wp-content/uploads/2026/09/gamepad_Controller-240x135.webp 240w, https://alicia-ing.com/wp-content/uploads/2026/09/gamepad_Controller-320x180.webp 320w, https://alicia-ing.com/wp-content/uploads/2026/09/gamepad_Controller-640x360.webp 640w" sizes="(max-width: 1672px) 100vw, 1672px" /></figure>



<p class="wp-block-paragraph">本記事では、InputActionReferenceを使って、ゲームパッドの移動（左スティック）とジャンプ（ボタン）を取得する入力ハンドラーを実装します。</p>



<p class="wp-block-paragraph">入力の取得だけを専用クラス（PlayerInputHandler）に切り出し、実際の移動処理・ジャンプ処理からはMoveInput・JumpWasPressedThisFrameという2つのプロパティを参照するだけで済むようにすることで、<strong>キーボードやマウスなど他の入力方式にも差し替えやすい設計</strong>を目指します。</p>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-info-circle"></span>実装にはこちらのゲームパッドを使用しました。手ごろで普段のゲームでも使うことができます。</span></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together">

<a target="_self" href="https://alicia-ing.com/life/best-buy/f310r/" title="F310r-Windows11で使えるゲームパッド実機レビュー" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://alicia-ing.com/wp-content/uploads/2023/08/logi-f310r-160x90.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://alicia-ing.com/wp-content/uploads/2023/08/logi-f310r-160x90.webp 160w, https://alicia-ing.com/wp-content/uploads/2023/08/logi-f310r-120x68.webp 120w, https://alicia-ing.com/wp-content/uploads/2023/08/logi-f310r-320x180.webp 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">F310r-Windows11で使えるゲームパッド実機レビュー</div><div class="blogcard-snippet internal-blogcard-snippet">Logicool F310ゲームパッドの実機レビュー。Windows 11対応の設定方法やドライバ情報を解説。スペックや操作手順を紹介。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://alicia-ing.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">alicia-ing.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2025.03.28</div></div></div></div></a>
</div>


		<div class="pochipp-box"
			data-id="8031"
			data-img="l"
			data-lyt-pc="dflt"
			data-lyt-mb="vrtcl"
			data-btn-style="dflt"
			data-btn-radius="off"
			data-sale-effect="flash"
			 data-cvkey="ffbaab34"		>
							<div class="pochipp-box__image">
					<a rel="nofollow" target="_self" href="https://www.amazon.co.jp/dp/B00CDG799E?tag=b0420e-22">
						<img loading="lazy" decoding="async" src="https://m.media-amazon.com/images/I/519-CQdsB+L._SL400_.jpg" alt="" width="120" height="120" />					</a>
				</div>
						<div class="pochipp-box__body">
				<div class="pochipp-box__title">
					<a rel="nofollow" target="_self" href="https://www.amazon.co.jp/dp/B00CDG799E?tag=b0420e-22">
						Logicool G ゲームパッド F310r ゲーム コントローラー 有線 USB 接続 FF14 steam PC PS5 PS4 windows F310 国内正規品 【 ファイナルファンタジー XIV 推奨モデル 】					</a>
				</div>

				
									<div class="pochipp-box__price">
						¥2,527						<span>（2026/09/26 19:01時点 | Amazon調べ）</span>
					</div>
				
							</div>
				<div class="pochipp-box__btns"
		data-maxclmn-pc="fit"
		data-maxclmn-mb="1"
	>
					<div class="pochipp-box__btnwrap -amazon">
								<a rel="nofollow" target="_self" href="https://www.amazon.co.jp/dp/B00CDG799E?tag=b0420e-22" class="pochipp-box__btn">
					<span>
						Amazon					</span>
									</a>
			</div>
							<div class="pochipp-box__btnwrap -rakuten">
								<a rel="nofollow" target="_self" href="https://af.moshimo.com/af/c/click?a_id=4016319&#038;p_id=54&#038;pc_id=54&#038;pl_id=616&#038;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2FF310r" class="pochipp-box__btn">
					<span>
						楽天市場					</span>
					<img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=4016319&#038;p_id=54&#038;pc_id=54&#038;pl_id=616" width="1" height="1" style="border:none;">				</a>
			</div>
										<div class="pochipp-box__btnwrap -yahoo -long-text">
								<a rel="nofollow" target="_self" href="https://shopping.yahoo.co.jp/search?p=F310r" class="pochipp-box__btn">
					<span>
						Yahooショッピング					</span>
									</a>
			</div>
									</div>
								<div class="pochipp-box__logo">
					<img loading="lazy" decoding="async" src="https://alicia-ing.com/wp-content/plugins/pochipp/assets/img/pochipp-logo-t1.png" alt="" width="32" height="32">
					<span>ポチップ</span>
				</div>
					</div>
	


<h3 class="wp-block-heading">ソースコード</h3>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerInputHandler : MonoBehaviour
{
    [SerializeField] private InputActionReference moveAction;
    [SerializeField] private InputActionReference jumpAction;

    public Vector2 MoveInput { get; private set; }
    public bool JumpWasPressedThisFrame { get; private set; }

    private void OnEnable()
    {
        moveAction.action.Enable();
        jumpAction.action.Enable();
    }

    private void OnDisable()
    {
        moveAction.action.Disable();
        jumpAction.action.Disable();
    }

    private void Update()
    {
        MoveInput = moveAction.action.ReadValue&lt;Vector2&gt;();
        JumpWasPressedThisFrame = jumpAction.action.WasPressedThisFrame();
    }
}
</code></pre></div>



<h3 class="wp-block-heading">解説</h3>



<ul class="wp-block-list">
<li><strong>名前空間</strong></li>
</ul>



<figure class="wp-block-table"><div class="scrollable-table"><table class="has-fixed-layout"><tbody><tr><td>UnityEngine</td><td>MonoBehaviour・Vector2など、Unityの基本機能を使うため</td></tr><tr><td>UnityEngine.InputSystem</td><td>InputActionReferenceなど、Input Systemの機能を使うため（パッケージの導入が必要）</td></tr></tbody></table></div></figure>



<ul class="wp-block-list">
<li><strong><strong>フィールド・プロパティ</strong></strong></li>
</ul>



<figure class="wp-block-table"><div class="scrollable-table"><table class="has-fixed-layout"><tbody><tr><td>moveAction</td><td>移動に使うMoveアクションの参照。Inspectorで設定する</td></tr><tr><td>jumpAction</td><td>ジャンプに使うJumpアクションの参照。Inspectorで設定する</td></tr><tr><td>MoveInput</td><td>スティックの傾き（-1〜1のVector2）。ほかのスクリプトから読み取る</td></tr><tr><td>JumpWasPressedThisFrame</td><td>このフレームでジャンプボタンが押されたか。ほかのスクリプトから読み取る</td></tr></tbody></table></div></figure>



<p class="wp-block-paragraph">MoveInput・JumpWasPressedThisFrameは{ get; private set; }としているため、ほかのスクリプトからは読み取りだけができ、書き換えはできません。</p>



<h3 class="wp-block-heading">InputActionReferenceでアクションを参照</h3>



<p class="wp-block-paragraph">InputActionReferenceは、Input Actionsアセット内の特定のInput ActionをInspector上から参照できる型です。</p>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>[SerializeField] private InputActionReference moveAction;
[SerializeField] private InputActionReference jumpAction;</code></pre></div>



<p class="wp-block-paragraph">コード内に直接アクション名を文字列で書く必要がなく、Inspectorから見た目でどのアクションを使っているか確認できます。</p>



<p class="wp-block-paragraph">Gamepad.currentを直接参照する実装と違って、キーボード用のInput ActionsアセットとゲームパッドMap用のアセットを差し替えるだけで入力元を切り替えられます。</p>



<p class="wp-block-paragraph">同じPlayerInputHandlerを別のプレハブで使い回す際にも、参照先のアクションを変えるだけで対応できる点が疎結合設計のメリットです。</p>



<h3 class="wp-block-heading">移動入力をVector2で取得する</h3>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>MoveInput = moveAction.action.ReadValue&lt;Vector2&gt;();</code></pre></div>



<p class="wp-block-paragraph">MoveアクションはAction TypeをValue（Vector2）に設定しているため、ReadValue()でスティックの<strong>傾き具合をVector2として取得</strong>できます。x軸が左右、y軸が上下の入力値（-1〜1の範囲）です。</p>



<p class="wp-block-paragraph">取得したMoveInputは、別のスクリプト（プレイヤーの移動処理を担うクラスなど）からplayerInputHandler.MoveInputとして参照し、transform.TranslateやRigidbody.linearVelocityなどに渡してキャラクターを動かすといった使い方をします。</p>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-info-circle"></span>Rigidbodyで移動させる処理はこちらで解説しています。</span></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together">

<a target="_self" href="https://alicia-ing.com/programming/unity/3dplayermove/" title="【Unity】Rigidbody+CapsuleColliderを用いたプレイヤー移動" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="320" height="180" src="https://alicia-ing.com/wp-content/uploads/2026/07/3dplayermove-320x180.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://alicia-ing.com/wp-content/uploads/2026/07/3dplayermove-320x180.webp 320w, https://alicia-ing.com/wp-content/uploads/2026/07/3dplayermove-240x135.webp 240w, https://alicia-ing.com/wp-content/uploads/2026/07/3dplayermove-640x360.webp 640w" sizes="(max-width: 320px) 100vw, 320px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【Unity】Rigidbody+CapsuleColliderを用いたプレイヤー移動</div><div class="blogcard-snippet internal-blogcard-snippet">UnityでCharacterControllerからRigidbody+CapsuleColliderへ移動処理を移行する方法を解説。カメラ相対移動、FixedUpdateでの速度制御、移行の判断基準まで紹介します。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://alicia-ing.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">alicia-ing.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2026.07.13</div></div></div></div></a>
</div>



<h3 class="wp-block-heading">ジャンプ入力を1フレームだけ検知する（WasPressedThisFrame）</h3>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>JumpWasPressedThisFrame = jumpAction.action.WasPressedThisFrame();</code></pre></div>



<p class="wp-block-paragraph">WasPressedThisFrame()は、そのボタンが「このフレームで押された瞬間」かどうかを返すメソッドです。</p>



<p class="wp-block-paragraph">ジャンプのように「押した瞬間に1回だけ処理を実行したい」動作には、このWasPressedThisFrame()を使うのが適切です。</p>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-info-circle"></span>キャラクターのジャンプ処理はこちらで解説しています。</span></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together">

<a target="_self" href="https://alicia-ing.com/programming/unity/player-jump/" title="【Unity】キャラクターをジャンプさせる自然な動きを実装" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="320" height="180" src="https://alicia-ing.com/wp-content/uploads/2026/09/player-jump-320x180.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://alicia-ing.com/wp-content/uploads/2026/09/player-jump-320x180.webp 320w, https://alicia-ing.com/wp-content/uploads/2026/09/player-jump-240x135.webp 240w, https://alicia-ing.com/wp-content/uploads/2026/09/player-jump-640x360.webp 640w" sizes="(max-width: 320px) 100vw, 320px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【Unity】キャラクターをジャンプさせる自然な動きを実装</div><div class="blogcard-snippet internal-blogcard-snippet">本記事を読むと以下の実行ができますRigidbodyを使ったキャラクターのジャンプ実装と、SphereCastによる正確...</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://alicia-ing.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">alicia-ing.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2026.09.20</div></div></div></div></a>
</div>



<h4 class="wp-block-heading">isPressedにしない理由</h4>



<p class="wp-block-paragraph">InputActionにはisPressed（現在押されているかどうか）とWasPressedThisFrame()（このフレームで押された瞬間かどうか）という似た名前のプロパティ・メソッドがあります。</p>



<p class="wp-block-paragraph">ジャンプ処理をisPressedで判定してしまうと、<strong>ボタンを押し続けている間、毎フレーム「押されている」と判定</strong>され続けてしまいます。その結果、Update()が呼ばれるたびにジャンプ処理が実行され、意図せず連続ジャンプしてしまうバグにつながります。</p>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>// 悪い例：ボタンを押している間ずっとtrueになる
if (jumpAction.action.IsPressed())
{
    Jump(); // 毎フレーム呼ばれてしまう
}

// 良い例：押した瞬間の1フレームだけtrueになる
if (jumpAction.action.WasPressedThisFrame())
{
    Jump(); // 1回だけ呼ばれる
}</code></pre></div>



<p class="wp-block-paragraph">ジャンプやポーズメニューの開閉など、「1回の入力につき1回だけ処理したい」動作では、必ずWasPressedThisFrame()を使うようにしましょう。</p>



<p class="wp-block-paragraph">逆に、ダッシュのように「押している間だけ継続する」動作にはisPressedが向いています。用途によって使い分けることが重要です。</p>



<h2 class="wp-block-heading">実演</h2>



<p class="wp-block-paragraph">空のGameObject、またはプレイヤーオブジェクトにアタッチします。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1917" height="966" src="https://alicia-ing.com/wp-content/uploads/2026/09/Attach-1.webp" alt="" class="wp-image-8965" srcset="https://alicia-ing.com/wp-content/uploads/2026/09/Attach-1.webp 1917w, https://alicia-ing.com/wp-content/uploads/2026/09/Attach-1-300x151.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/09/Attach-1-768x387.webp 768w, https://alicia-ing.com/wp-content/uploads/2026/09/Attach-1-1024x516.webp 1024w, https://alicia-ing.com/wp-content/uploads/2026/09/Attach-1-1536x774.webp 1536w" sizes="(max-width: 1917px) 100vw, 1917px" /></figure>



<p class="wp-block-paragraph">設定が完了すると、他のスクリプトからplayerInputHandler.MoveInput・playerInputHandler.JumpWasPressedThisFrameを参照するだけで、ゲームパッドからの入力を取得できるようになります。</p>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">本記事では、Unity Input SystemのInputActionReferenceを使い、ゲームパッドでの移動とジャンプを実装する方法を解説しました。</p>



<ul class="wp-block-list">
<li>InputActionReferenceをInspectorで参照することで、入力元を差し替えやすい疎結合な設計にできる</li>



<li>移動はReadValue()、ジャンプはWasPressedThisFrame()で取得する</li>



<li>ジャンプなど「1回だけ処理したい」入力はisPressedではなくWasPressedThisFrame()を使う</li>
</ul>



<p class="wp-block-paragraph">今回紹介したPlayerInputHandlerは移動とジャンプの最小構成ですが、同じ考え方でダッシュ・攻撃・ポーズメニューの開閉など他のアクションにも応用できます。</p>



<p class="wp-block-paragraph">まずはこの最小構成で「ゲームパッドで動くもの」を作り、そこから少しずつアクションを増やしていくと理解が深まるのでおすすめです。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://alicia-ing.com/programming/unity/gamepad-player/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Unity】キャラクターをジャンプさせる自然な動きを実装</title>
		<link>https://alicia-ing.com/programming/unity/player-jump/</link>
					<comments>https://alicia-ing.com/programming/unity/player-jump/#respond</comments>
		
		<dc:creator><![CDATA[アリッシア]]></dc:creator>
		<pubDate>Sun, 20 Sep 2026 06:10:09 +0000</pubDate>
				<category><![CDATA[Unity]]></category>
		<guid isPermaLink="false">https://alicia-ing.com/?p=8940</guid>

					<description><![CDATA[Unityでキャラクターをジャンプさせることはゲーム開発での基礎ですが、「ボタンを押しても反応しない」「空中で何度もジャンプできてしまう」といった問題によくぶつかります。 これは多くの場合、接地判定（キャラクターが地面に [&#8230;]]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-cocoon-blocks-label-box-1 label-box block-box not-nested-style cocoon-block-label-box"><div class="label-box-label block-box-label box-label fab-flag"><span class="label-box-label-text block-box-label-text box-label-text">本記事を読むと以下の実行ができます</span></div><div class="label-box-content block-box-content box-content">
<p class="wp-block-paragraph">Rigidbodyを使ったキャラクターのジャンプ実装と、SphereCastによる正確な接地判定を組み合わせて、二段ジャンプや無限ジャンプを起こさない自然なジャンプ動作</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1280" height="720" src="https://alicia-ing.com/wp-content/uploads/2026/09/complete.gif" alt="" class="wp-image-8946"/></figure>
</div></div>



<p class="wp-block-paragraph">Unityでキャラクターをジャンプさせることはゲーム開発での基礎ですが、「ボタンを押しても反応しない」「空中で何度もジャンプできてしまう」といった問題によくぶつかります。</p>



<p class="wp-block-paragraph">これは多くの場合、接地判定（キャラクターが地面に着いているかどうかの判定）が不十分なことが原因です。</p>



<p class="wp-block-paragraph">本記事では、RigidbodyとPhysics.SphereCastを使い、CapsuleColliderの実際のサイズに連動した接地判定と、目標到達高さから逆算したジャンプ初速の計算方法をあわせて解説します。</p>



<div class="wp-block-cocoon-blocks-label-box-1 label-box block-box cocoon-block-label-box"><div class="label-box-label block-box-label box-label fab-check"><span class="label-box-label-text block-box-label-text box-label-text">本記事は次の人におすすめ</span></div><div class="label-box-content block-box-content box-content">
<ul class="wp-block-list">
<li>Unityでキャラクターのジャンプ処理を実装したい人</li>



<li>AddForceやvelocity直接指定でジャンプを作ったが、二段ジャンプ・無限ジャンプが直らず困っている人</li>



<li>タグ判定やisGroundedだけの簡易な接地判定から、より正確な判定方法にステップアップしたい人</li>



<li>ジャンプの高さを感覚ではなく数値（目標到達高さ）から計算して設定したい人</li>



<li>UpdateとFixedUpdateの役割分担を理解して、物理挙動が絡む処理を正しく設計したい人</li>
</ul>
</div></div>



<h2 class="wp-block-heading">ジャンプ実装に必要な要素（SphereCast）とは？</h2>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1672" height="940" src="https://alicia-ing.com/wp-content/uploads/2026/09/sphereCast_jump.webp" alt="" class="wp-image-8947" srcset="https://alicia-ing.com/wp-content/uploads/2026/09/sphereCast_jump.webp 1672w, https://alicia-ing.com/wp-content/uploads/2026/09/sphereCast_jump-300x169.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/09/sphereCast_jump-767x431.webp 767w, https://alicia-ing.com/wp-content/uploads/2026/09/sphereCast_jump-1024x576.webp 1024w, https://alicia-ing.com/wp-content/uploads/2026/09/sphereCast_jump-1536x864.webp 1536w, https://alicia-ing.com/wp-content/uploads/2026/09/sphereCast_jump-240x135.webp 240w, https://alicia-ing.com/wp-content/uploads/2026/09/sphereCast_jump-320x180.webp 320w, https://alicia-ing.com/wp-content/uploads/2026/09/sphereCast_jump-640x360.webp 640w" sizes="(max-width: 1672px) 100vw, 1672px" /></figure>



<p class="wp-block-paragraph">Unityでジャンプ実装を検索すると、「unity rigidbody ジャンプ」「unity 接地判定」といったキーワードで多くの記事がヒットしますが、実装方式は大きく2つの系統に分かれます。</p>



<ol class="wp-block-list">
<li><strong>ジャンプそのものの実装</strong>（AddForceやvelocityでY方向に力・速度を加える）</li>



<li><strong>接地判定の実装</strong>（タグ判定・Raycast・CheckSphere・SphereCast・isGroundedなど）</li>
</ol>



<p class="wp-block-paragraph">この2つは別々に解説されがちですが、実際に「ちゃんと動くジャンプ」を作るには両方を組み合わせる必要があります。</p>



<p class="wp-block-paragraph">特に接地判定が甘いと、空中にいるのにジャンプ入力を受け付けてしまい、二段ジャンプ・無限ジャンプというよくあるバグにつながります。</p>



<p class="wp-block-paragraph">本記事で採用するPhysics.SphereCastは、球（Sphere）を指定方向に飛ばして衝突を検出するUnityの物理判定です。</p>



<p class="wp-block-paragraph">単純なRaycast（線を1本飛ばすだけ）と違い、球という「太さ」を持つ判定なので、地面のわずかな段差や傾斜でも安定して接地を検出できます。</p>



<h2 class="wp-block-heading">SphereCastを使ったジャンプ処理</h2>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1672" height="940" src="https://alicia-ing.com/wp-content/uploads/2026/09/jump.webp" alt="" class="wp-image-8948" srcset="https://alicia-ing.com/wp-content/uploads/2026/09/jump.webp 1672w, https://alicia-ing.com/wp-content/uploads/2026/09/jump-300x169.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/09/jump-767x431.webp 767w, https://alicia-ing.com/wp-content/uploads/2026/09/jump-1024x576.webp 1024w, https://alicia-ing.com/wp-content/uploads/2026/09/jump-1536x864.webp 1536w, https://alicia-ing.com/wp-content/uploads/2026/09/jump-240x135.webp 240w, https://alicia-ing.com/wp-content/uploads/2026/09/jump-320x180.webp 320w, https://alicia-ing.com/wp-content/uploads/2026/09/jump-640x360.webp 640w" sizes="(max-width: 1672px) 100vw, 1672px" /></figure>



<p class="wp-block-paragraph">今回のジャンプ実装は、以下の4ステップで構成されています。</p>



<div class="wp-block-cocoon-blocks-timeline timeline-box cf block-box not-nested-style cocoon-block-timeline"><div class="timeline-title">ジャンプ処理の実装</div><ul class="timeline">
<li class="wp-block-cocoon-blocks-timeline-item timeline-item cf"><div class="timeline-item-label">step1</div><div class="timeline-item-content cf"><div class="timeline-item-title">入力で、ジャンプボタンが押されたかどうかをUpdateで検知する</div><div class="timeline-item-snippet">
<p class="wp-block-paragraph"></p>
</div></div></li>



<li class="wp-block-cocoon-blocks-timeline-item timeline-item cf"><div class="timeline-item-label">step2</div><div class="timeline-item-content cf"><div class="timeline-item-title">SphereCastを使い接地判定を行う</div><div class="timeline-item-snippet"></div></div></li>



<li class="wp-block-cocoon-blocks-timeline-item timeline-item cf"><div class="timeline-item-label">step3</div><div class="timeline-item-content cf"><div class="timeline-item-title">地面以外のコライダーやトリガーを誤検知しないようにする<br></div><div class="timeline-item-snippet"></div></div></li>
</ul></div>



<h3 class="wp-block-heading">ソースコード</h3>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>using UnityEngine;

[RequireComponent(typeof(Rigidbody), typeof(CapsuleCollider), typeof(PlayerInputHandler))]
public class PlayerJump : MonoBehaviour
{
    [SerializeField] private float jumpHeight = 1.5f;
    [SerializeField] private LayerMask groundMask = ~0;

    private Rigidbody rb;
    private CapsuleCollider capsule;
    private PlayerInputHandler input;
    private bool jumpRequested;

    private void Awake()
    {
        rb = GetComponent&lt;Rigidbody&gt;();
        capsule = GetComponent&lt;CapsuleCollider&gt;();
        input = GetComponent&lt;PlayerInputHandler&gt;();
    }

    private void Update()
    {
        if (input.JumpWasPressedThisFrame)
        {
            jumpRequested = true;
        }
    }

    private void FixedUpdate()
    {
        Vector3 velocity = rb.linearVelocity;

        if (jumpRequested && IsGrounded())
        {
            velocity.y = Mathf.Sqrt(jumpHeight * -2f * Physics.gravity.y);
        }
        jumpRequested = false;

        rb.linearVelocity = velocity;
    }

    private bool IsGrounded()
    {
        Vector3 origin = transform.TransformPoint(capsule.center);
        float castRadius = capsule.radius * 0.9f;
        float castDistance = capsule.height * 0.5f + 0.15f;
        return Physics.SphereCast(origin, castRadius, Vector3.down, out _, castDistance, groundMask, QueryTriggerInteraction.Ignore);
    }
}
</code></pre></div>



<h3 class="wp-block-heading">解説</h3>



<ul class="wp-block-list">
<li><strong>入力の検知とFixedUpdateでの物理処理を分離する設計</strong></li>
</ul>



<p class="wp-block-paragraph">ジャンプボタンの入力検知をUpdate、実際の速度変更をFixedUpdateに分けています。</p>



<ul class="wp-block-list">
<li>Updateはフレームごとに呼ばれる（フレームレートに依存する）ため、入力の取りこぼしを防ぐのに向いています。</li>



<li>FixedUpdateは一定の時間間隔で呼ばれる（物理エンジンの更新タイミングに同期する）ため、Rigidbodyを操作する処理はここで行うのが基本です。</li>
</ul>



<p class="wp-block-paragraph">Update内で直接Rigidbodyの速度を書き換えてしまうと、フレームレートによって物理挙動が不安定になることがあります。そこで、UpdateではjumpRequestedというフラグを立てるだけにとどめ、実際の速度変更はFixedUpdateでまとめて行うように設計しています。</p>



<p class="wp-block-paragraph">FixedUpdateの先頭でjumpRequestedを判定した後、必ずfalseにリセットしている点もポイントです。これにより、1回のボタン入力に対してジャンプが1回だけ発生するようになります。</p>



<ul class="wp-block-list">
<li><strong>SphereCastでCapsuleColliderに連動した接地判定を行う</strong></li>
</ul>



<p class="wp-block-paragraph">IsGrounded()メソッドが接地判定の中心部分です。単純に固定の半径・距離を指定するのではなく、CapsuleColliderのプロパティから動的に計算しています。</p>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>Vector3 origin = transform.TransformPoint(capsule.center);
float castRadius = capsule.radius * 0.9f;
float castDistance = capsule.height * 0.5f + 0.15f;</code></pre></div>



<ul class="wp-block-list">
<li>origin：capsule.center（ローカル座標）をTransformPointでワールド座標に変換し、キャラクターの中心からキャストを開始します。</li>



<li>castRadius：コライダーの半径そのままだと壁際でわずかに引っかかることがあるため、0.9fを掛けて少し小さめに設定しています。</li>



<li>castDistance：カプセルの半分の高さ（中心から底面まで）に、地面との間に余裕を持たせる0.15fを加えています。</li>
</ul>



<p class="wp-block-paragraph">この値をキャラクターのサイズ（CapsuleCollider）から計算する設計にしておくことで、キャラクターモデルを差し替えてCapsuleColliderのサイズが変わっても、接地判定のコードを書き直す必要がありません。</p>



<ul class="wp-block-list">
<li><strong>ジャンプの初速を目標到達高さから逆算する</strong></li>
</ul>



<p class="wp-block-paragraph">ジャンプの高さを「なんとなくの数値」で調整すると、意図した高さにならず何度も微調整することになります。本実装では、到達させたい高さ（jumpHeight）から必要な初速を逆算しています。</p>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>velocity.y = Mathf.Sqrt(jumpHeight * -2f * Physics.gravity.y);</code></pre></div>



<p class="wp-block-paragraph">これは物理の等加速度運動の公式 v0 = √(2gH) をそのままコードにしたものです。Physics.gravity.yは通常マイナスの値（デフォルトは-9.81）なので、符号を合わせるために-2fを掛けています。</p>



<ul class="wp-block-list">
<li>H：到達させたい高さ（jumpHeight、インスペクターで調整可能）</li>



<li>g：重力加速度（Physics.gravity.yの絶対値）</li>



<li>v0：地面を離れる瞬間に必要な初速（Y方向の速度）</li>
</ul>



<p class="wp-block-paragraph">インスペクター上でjumpHeightの値を1.5から2.0に変えるだけで、「ちょうど2m飛び上がるジャンプ」を数値ベースで作れるようになります。感覚での調整に頼らず、狙った高さを確実に再現できるのがこの計算式の利点です。</p>



<ul class="wp-block-list">
<li>レイヤーマスクとQueryTriggerInteraction.Ignoreで誤検知を防ぐ</li>
</ul>



<p class="wp-block-paragraph">SphereCastはデフォルトのままだと、地面以外のコライダー（アイテムの当たり判定やエフェクト用のトリガーなど）にも反応してしまうことがあります。これを防ぐために2つの仕組みを併用しています。</p>



<ul class="wp-block-list">
<li>groundMask（レイヤーマスク）： SphereCastの判定対象を、あらかじめ設定した「地面」レイヤーのみに絞り込みます。プレイヤー自身や敵、アイテムなどのレイヤーを対象外にできます。</li>



<li>QueryTriggerInteraction.Ignore： IsTriggerが有効なコライダー（当たり判定はあるが物理的にすり抜けるコライダー）を接地判定の対象から除外します。これを指定しないと、トリガーに触れただけで「地面に着地した」と誤判定されることがあります。</li>
</ul>



<p class="wp-block-paragraph">この2つを組み合わせることで、地面用のコライダーだけを確実に検出できるようになります。レイヤーマスクの活用に触れていない競合記事も多いため、意図しない誤検知を防ぎたい場合は必ず設定しておきましょう。</p>



<h2 class="wp-block-heading">実演</h2>



<p class="wp-block-paragraph">Rigidbody・CapsuleCollider・PlayerInputHandlerを設定済みのプレイヤーオブジェクトにアタッチします（RequireComponentにより、この3つが未設定のオブジェクトにはアタッチできません）。</p>



<div class="wp-block-cocoon-blocks-timeline timeline-box cf block-box not-nested-style cocoon-block-timeline"><div class="timeline-title">アタッチの流れ</div><ul class="timeline">
<li class="wp-block-cocoon-blocks-timeline-item timeline-item cf"><div class="timeline-item-label">STEP1</div><div class="timeline-item-content cf"><div class="timeline-item-title">プレイヤーオブジェクトにRigidbody・CapsuleColliderを追加</div><div class="timeline-item-snippet">
<p class="wp-block-paragraph"></p>
</div></div></li>



<li class="wp-block-cocoon-blocks-timeline-item timeline-item cf"><div class="timeline-item-label">STEP2</div><div class="timeline-item-content cf"><div class="timeline-item-title">同じオブジェクトにスクリプトをアタッチする</div><div class="timeline-item-snippet"></div></div></li>



<li class="wp-block-cocoon-blocks-timeline-item timeline-item cf"><div class="timeline-item-label">STEP3</div><div class="timeline-item-content cf"><div class="timeline-item-title">InspectorでJump Height（到達させたい高さ）を設定する</div><div class="timeline-item-snippet"></div></div></li>



<li class="wp-block-cocoon-blocks-timeline-item timeline-item cf"><div class="timeline-item-label">Step 4</div><div class="timeline-item-content cf"><div class="timeline-item-title">InspectorでGround Maskに地面用のレイヤーを指定する</div><div class="timeline-item-snippet"></div></div></li>
</ul></div>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="2560" height="1299" src="https://alicia-ing.com/wp-content/uploads/2026/09/attach-scaled.webp" alt="" class="wp-image-8944" srcset="https://alicia-ing.com/wp-content/uploads/2026/09/attach-scaled.webp 2560w, https://alicia-ing.com/wp-content/uploads/2026/09/attach-300x152.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/09/attach-766x389.webp 766w, https://alicia-ing.com/wp-content/uploads/2026/09/attach-1024x520.webp 1024w, https://alicia-ing.com/wp-content/uploads/2026/09/attach-1536x780.webp 1536w, https://alicia-ing.com/wp-content/uploads/2026/09/attach-2048x1039.webp 2048w" sizes="(max-width: 2560px) 100vw, 2560px" /></figure>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">本記事では、Rigidbodyを使ったUnityのジャンプ実装を、以下の4つのポイントに分けて解説しました。</p>



<ul class="wp-block-list">
<li>入力検知（Update）と物理処理（FixedUpdate）を分離する設計</li>



<li>CapsuleColliderの実サイズに連動したSphereCast接地判定</li>



<li>目標到達高さから初速を逆算するv0 = √(2gH)の計算式</li>



<li>レイヤーマスクとQueryTriggerInteraction.Ignoreによる誤検知防止</li>
</ul>



<p class="wp-block-paragraph"><br>これらを組み合わせることで、二段ジャンプ・無限ジャンプといった典型的なバグを防ぎつつ、狙った高さに正確に跳ぶジャンプ処理を作れます。</p>



<p class="wp-block-paragraph">まずは本記事のコードをそのまま自分のプロジェクトに組み込み、jumpHeightやgroundMaskの値を自分のキャラクターに合わせて調整するところから始めてみてください。</p>



<p class="wp-block-paragraph">接地判定の考え方は壁ジャンプや二段ジャンプなど、他のアクションを追加する際の土台にもなります。</p>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://alicia-ing.com/programming/unity/player-jump/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Unity】三人称視点を滑らかに追従処理｜Lerp（位置）とSlerp（回転）</title>
		<link>https://alicia-ing.com/programming/unity/third-person-view-player/</link>
					<comments>https://alicia-ing.com/programming/unity/third-person-view-player/#respond</comments>
		
		<dc:creator><![CDATA[アリッシア]]></dc:creator>
		<pubDate>Thu, 16 Jul 2026 09:46:20 +0000</pubDate>
				<category><![CDATA[Unity]]></category>
		<guid isPermaLink="false">https://alicia-ing.com/?p=8909</guid>

					<description><![CDATA[3人称視点（TPS/TPP）のゲームを作っていると、カメラをプレイヤーにそのまま追従させただけではカクついたり、キャラクターの動きに機械的に張り付いてしまったりして、なめらかさに欠ける映像になってしまうことがあります。  [&#8230;]]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-cocoon-blocks-label-box-1 label-box block-box not-nested-style cocoon-block-label-box"><div class="label-box-label block-box-label box-label fab-flag"><span class="label-box-label-text block-box-label-text box-label-text">本記事を読むと以下の実行ができます</span></div><div class="label-box-content block-box-content box-content">
<p class="wp-block-paragraph">プレイヤーの後ろから滑らかに追従する、カクつきのない三人称カメラの実装</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1280" height="720" src="https://alicia-ing.com/wp-content/uploads/2026/07/complete-1.gif" alt="" class="wp-image-8927"/></figure>
</div></div>



<p class="wp-block-paragraph">3人称視点（TPS/TPP）のゲームを作っていると、カメラをプレイヤーにそのまま追従させただけではカクついたり、キャラクターの動きに機械的に張り付いてしまったりして、なめらかさに欠ける映像になってしまうことがあります。 </p>



<p class="wp-block-paragraph">本記事では、位置はVector3.Lerp、回転はQuaternion.Slerpという2つの異なる補間関数を組み合わせて、自然な三人称カメラの追従処理を実装する方法を解説します。</p>



<p class="wp-block-paragraph"> followSpeedやrotationSpeedなどのパラメータ調整方法や、カメラの動きが不自然になったときのチェックポイントまで、実際に手を動かしながら理解できる内容になっています。</p>



<div class="wp-block-cocoon-blocks-label-box-1 label-box block-box cocoon-block-label-box"><div class="label-box-label block-box-label box-label fab-check"><span class="label-box-label-text block-box-label-text box-label-text">本記事は次の人におすすめ</span></div><div class="label-box-content block-box-content box-content">
<ul class="wp-block-list">
<li>Unityで三人称視点（TPS/TPP）のカメラを実装したい人</li>



<li>Unityのカメラ追従を実装したがカクつく・不自然な動きになって困っている人</li>



<li>Vector3.LerpとQuaternion.Slerpの違いや使い分けを知りたい人</li>



<li>followSpeedやrotationSpeedなどのパラメータをどう調整すればいいか分からない人</li>
</ul>
</div></div>



<h2 class="wp-block-heading">三人称カメラの追従処理とは？</h2>



<figure class="wp-block-image aligncenter size-full"><img loading="lazy" decoding="async" width="1672" height="941" src="https://alicia-ing.com/wp-content/uploads/2026/07/camera-tracking.webp" alt="" class="wp-image-8930" srcset="https://alicia-ing.com/wp-content/uploads/2026/07/camera-tracking.webp 1672w, https://alicia-ing.com/wp-content/uploads/2026/07/camera-tracking-300x169.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/07/camera-tracking-768x432.webp 768w, https://alicia-ing.com/wp-content/uploads/2026/07/camera-tracking-1024x576.webp 1024w, https://alicia-ing.com/wp-content/uploads/2026/07/camera-tracking-1536x864.webp 1536w, https://alicia-ing.com/wp-content/uploads/2026/07/camera-tracking-240x135.webp 240w, https://alicia-ing.com/wp-content/uploads/2026/07/camera-tracking-320x180.webp 320w, https://alicia-ing.com/wp-content/uploads/2026/07/camera-tracking-640x360.webp 640w" sizes="(max-width: 1672px) 100vw, 1672px" /></figure>



<p class="wp-block-paragraph">三人称カメラ（TPS/TPPカメラ）とは、プレイヤーが操作するキャラクターの背後や斜め上から映すカメラのことです。アクションゲームやオープンワールドゲームなど、多くの3Dゲームで採用されている視点です。</p>



<p class="wp-block-paragraph">三人称カメラの追従処理を作るとき、意識すべきポイントは大きく分けて2つあります。</p>



<figure class="wp-block-table"><div class="scrollable-table"><table class="has-fixed-layout"><thead><tr><th>要素</th><th>内容</th></tr></thead><tbody><tr><td>位置追従</td><td>カメラのキャラクターを一定距離後ろに保ちつづける処理</td></tr><tr><td>回転の追従</td><td>カメラ向きをcharacter（注視点）へ向け続ける処理</td></tr></tbody></table></div></figure>



<p class="wp-block-paragraph">transform.positionをそのままキャラクターの位置に代入するだけでは、カメラが一瞬でキャラクターの真後ろにワープしたような、機械的で不自然な映像になってしまいます。</p>



<p class="wp-block-paragraph">そこで、位置と回転それぞれに<strong>補間（インターポレーション）</strong>をかけることで、カメラがワンテンポ遅れてついてくるような、滑らかな追従感を演出します。</p>



<p class="wp-block-paragraph">このとき重要なのが、位置の補間にはVector3.Lerp、回転の補間にはQuaternion.Slerpという異なる関数を使うという点です。</p>



<p class="wp-block-paragraph">位置は直線的な移動なので線形補間（Lerp）で十分ですが、回転は「角度」を扱うため、球面線形補間（Slerp）を使わないと不自然な回転になってしまいます。</p>



<p class="wp-block-paragraph">この違いについてはコードを解説するセクションで詳しく説明します。</p>



<h3 class="wp-block-heading">Vector3.LerpとQuaternion.Slerpで実装する三人称カメラ</h3>



<figure class="wp-block-image aligncenter size-full"><img loading="lazy" decoding="async" width="1672" height="941" src="https://alicia-ing.com/wp-content/uploads/2026/07/lerp-slerp.webp" alt="" class="wp-image-8931" srcset="https://alicia-ing.com/wp-content/uploads/2026/07/lerp-slerp.webp 1672w, https://alicia-ing.com/wp-content/uploads/2026/07/lerp-slerp-300x169.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/07/lerp-slerp-768x432.webp 768w, https://alicia-ing.com/wp-content/uploads/2026/07/lerp-slerp-1024x576.webp 1024w, https://alicia-ing.com/wp-content/uploads/2026/07/lerp-slerp-1536x864.webp 1536w, https://alicia-ing.com/wp-content/uploads/2026/07/lerp-slerp-240x135.webp 240w, https://alicia-ing.com/wp-content/uploads/2026/07/lerp-slerp-320x180.webp 320w, https://alicia-ing.com/wp-content/uploads/2026/07/lerp-slerp-640x360.webp 640w" sizes="(max-width: 1672px) 100vw, 1672px" /></figure>



<p class="wp-block-paragraph">三人称カメラの追従処理は、以下の3ステップで実装できます。</p>



<div class="wp-block-cocoon-blocks-timeline timeline-box cf block-box not-nested-style cocoon-block-timeline"><div class="timeline-title">実装までの流れ</div><ul class="timeline">
<li class="wp-block-cocoon-blocks-timeline-item timeline-item cf"><div class="timeline-item-label">step1</div><div class="timeline-item-content cf"><div class="timeline-item-title">オブジェクトの配置</div><div class="timeline-item-snippet">
<p class="wp-block-paragraph">カメラをキャラクターの子オブジェクトにせず、独立したオブジェクトとして配置する</p>
</div></div></li>



<li class="wp-block-cocoon-blocks-timeline-item timeline-item cf"><div class="timeline-item-label">step2</div><div class="timeline-item-content cf"><div class="timeline-item-title">カメラ追従</div><div class="timeline-item-snippet">
<p class="wp-block-paragraph">LateUpdate内で、キャラクター位置＋オフセットへVector3.Lerpでカメラを追従させる</p>
</div></div></li>



<li class="wp-block-cocoon-blocks-timeline-item timeline-item cf"><div class="timeline-item-label">step3</div><div class="timeline-item-content cf"><div class="timeline-item-title">回転によるカメラ向き合わせる</div><div class="timeline-item-snippet">
<p class="wp-block-paragraph">LateUpdate内で、注視点をQuaternion.LookRotationで計算し、Quaternion.Slerpでカメラの向きを滑らかに合わせる</p>
</div></div></li>
</ul></div>



<p class="wp-block-paragraph">カメラをキャラクターの子オブジェクトにしてしまうと、キャラクターの回転がそのままカメラの回転に伝わってしまい、独立した滑らかな動きを付けられなくなります。</p>



<p class="wp-block-paragraph">そのため、カメラはシーン上の独立したオブジェクトとして配置し、スクリプトで位置・回転を毎フレーム計算する構成にします。</p>



<h3 class="wp-block-heading">ソースコード</h3>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>using UnityEngine;

public class CameraFollow : MonoBehaviour
{
    [SerializeField] private Transform target;
    [SerializeField] private Vector3 offset = new Vector3(0f, 3.2f, -7f);
    [SerializeField] private float followSpeed = 5f;
    [SerializeField] private float rotationSpeed = 5f;
    [SerializeField] private float lookHeight = 1.5f;

    private void LateUpdate()
    {
        if (target == null)
        {
            return;
        }
        Vector3 desiredPosition = target.position + offset;
        transform.position = Vector3.Lerp(transform.position, desiredPosition, followSpeed * Time.deltaTime);

        Vector3 lookPoint = target.position + Vector3.up * lookHeight;
        Quaternion desiredRotation = Quaternion.LookRotation(lookPoint - transform.position);
        transform.rotation = Quaternion.Slerp(transform.rotation, desiredRotation, rotationSpeed * Time.deltaTime);
    }
}</code></pre></div>



<h3 class="wp-block-heading">解説</h3>



<ul class="wp-block-list">
<li><strong>位置の追従処理（Vector3.Lerp）</strong></li>
</ul>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>Vector3 desiredPosition = target.position + offset;
transform.position = Vector3.Lerp(transform.position, desiredPosition, followSpeed * Time.deltaTime);</code></pre></div>



<p class="wp-block-paragraph">まずtarget.position + offsetで、「カメラが本来いるべき理想の位置（desiredPosition）」を計算します。</p>



<p class="wp-block-paragraph">offsetは(0, 3.2, -7)のように、キャラクターから見て「上に3.2、後ろに7」といった相対位置を指定するベクトルです。</p>



<p class="wp-block-paragraph">次にVector3.Lerp(現在位置, 理想位置, 割合)で、現在のカメラ位置から理想位置へ少しずつ近づけます。第3引数のfollowSpeed * Time.deltaTimeが「1フレームでどれだけ理想位置に近づくか」の割合です。</p>



<p class="wp-block-paragraph">Time.deltaTimeを掛けることで、フレームレートが変わっても同じ速度で追従するようになります。</p>



<p class="wp-block-paragraph">Vector3.Lerpは2点間を直線的に補間する関数なので、位置の移動には自然にマッチします。<br>これが、いきなりtransform.position = desiredPositionと代入せず、Lerpを使う理由です。</p>



<ul class="wp-block-list">
<li><strong>注視点の回転処理（Quaternion.Slerp）</strong></li>
</ul>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>Vector3 lookPoint = target.position + Vector3.up * lookHeight;
Quaternion desiredRotation = Quaternion.LookRotation(lookPoint - transform.position);
transform.rotation = Quaternion.Slerp(transform.rotation, desiredRotation, rotationSpeed * Time.deltaTime);</code></pre></div>



<p class="wp-block-paragraph">回転の処理も基本的な流れは位置と同じで、「理想の回転（desiredRotation）」を計算してから、現在の回転を少しずつ近づけます。</p>



<p class="wp-block-paragraph">ただし、回転を補間する際はVector3.Lerpではなく<strong>Quaternion.Slerp（球面線形補間）</strong>を使う点に注意してください。</p>



<p class="wp-block-paragraph">回転は「角度」という性質上、直線的な補間（Lerp）をそのまま当てはめると、回転速度にムラが出たり、経由地点でおかしな姿勢を取ったりすることがあります。</p>



<p class="wp-block-paragraph">Quaternion.Slerpは球面上を一定の角速度で補間するため、回転が常に自然な速さで進みます。位置はLerp、回転はSlerpという使い分けは、Unityのカメラ制御において基本となる考え方です。</p>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-info-circle"></span>Vector3を使った補間・イージングの考え方を紹介しています。</span></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together">

<a target="_self" href="https://alicia-ing.com/programming/unity/easing/" title="【Unity】Vectorを使ったイージング、アニメーション動作" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://alicia-ing.com/wp-content/uploads/2023/03/vector-easing-160x90.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://alicia-ing.com/wp-content/uploads/2023/03/vector-easing-160x90.webp 160w, https://alicia-ing.com/wp-content/uploads/2023/03/vector-easing-120x68.webp 120w, https://alicia-ing.com/wp-content/uploads/2023/03/vector-easing-320x180.webp 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【Unity】Vectorを使ったイージング、アニメーション動作</div><div class="blogcard-snippet internal-blogcard-snippet">Vector2を使ったスクリプトでアニメーションを作成します。RectTransformで座標を決めて、線形補間「Leap」を実行します。本記事では、マウスのポインターの位置でアニメーションを稼働させるソースコードを公開・解説しています。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://alicia-ing.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">alicia-ing.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2025.08.11</div></div></div></div></a>
</div>



<ul class="wp-block-list">
<li><strong>LookRotationで注視点を計算する仕組み</strong></li>
</ul>



<p class="wp-block-paragraph">Quaternion.LookRotation(方向ベクトル)は、指定した方向を向く回転（Quaternion）を返す関数です。</p>



<p class="wp-block-paragraph">ここでは、lookPoint &#8211; transform.position（カメラから注視点への方向ベクトル）を渡すことで、「カメラから見て、注視点の方向を向いた回転」を計算しています。</p>



<p class="wp-block-paragraph">lookPointはtarget.position + Vector3.up * lookHeight、つまりキャラクターの位置から少し上にずらした点です。</p>



<p class="wp-block-paragraph">キャラクターの足元をそのまま注視点にすると、カメラが常に下向きになり圧迫感のある画になってしまうため、lookHeightで見上げるような角度にならないよう調整しています。</p>



<ul class="wp-block-list">
<li><strong>LateUpdateを使う理由</strong></li>
</ul>



<p class="wp-block-paragraph">このスクリプトでは、UpdateではなくLateUpdateを使っています。これは三人称カメラの実装において非常に重要なポイントです。</p>



<p class="wp-block-paragraph">Unityでは、シーン内の複数のUpdateがどの順番で実行されるかは保証されていません。もしキャラクターの移動処理と、カメラの追従処理が両方ともUpdateに書かれていた場合、カメラのUpdateがキャラクターのUpdateより先に実行されてしまうことがあります。</p>



<p class="wp-block-paragraph">それにより、カメラは「1フレーム前のキャラクター位置」を基準に追従することになり、映像がカクつく原因になります。</p>



<p class="wp-block-paragraph">LateUpdateは、シーン内のすべてのUpdateが終わった後に必ず呼ばれることが保証されています。そのため、キャラクターの移動処理が確実に終わった後の最新位置を使ってカメラを更新でき、カクつきのない滑らかな追従が実現できます。</p>



<p class="wp-block-paragraph">カメラ制御では「移動処理はUpdate、カメラ追従はLateUpdate」という役割分担を徹底しましょう。</p>



<h2 class="wp-block-heading">実装</h2>



<p class="wp-block-paragraph">シーン上に独立して配置したカメラオブジェクトにアタッチします。</p>



<div class="wp-block-cocoon-blocks-timeline timeline-box cf block-box not-nested-style cocoon-block-timeline"><div class="timeline-title"></div><ul class="timeline">
<li class="wp-block-cocoon-blocks-timeline-item timeline-item cf"><div class="timeline-item-label">STEP1</div><div class="timeline-item-content cf"><div class="timeline-item-title">カメラをキャラクターの子オブジェクトにせず、シーン上の独立したオブジェクトとして配置する</div><div class="timeline-item-snippet">
<p class="wp-block-paragraph"></p>
</div></div></li>



<li class="wp-block-cocoon-blocks-timeline-item timeline-item cf"><div class="timeline-item-label">STEP2</div><div class="timeline-item-content cf"><div class="timeline-item-title">カメラオブジェクトにスクリプトをアタッチする</div><div class="timeline-item-snippet">
<p class="wp-block-paragraph"></p>
</div></div></li>



<li class="wp-block-cocoon-blocks-timeline-item timeline-item cf"><div class="timeline-item-label">STEP3</div><div class="timeline-item-content cf"><div class="timeline-item-title">InspectorのTargetに、追従したいキャラクターのTransformをドラッグ＆ドロップで設定する</div><div class="timeline-item-snippet"></div></div></li>
</ul></div>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="2560" height="1265" src="https://alicia-ing.com/wp-content/uploads/2026/07/attach-scaled.webp" alt="" class="wp-image-8942" srcset="https://alicia-ing.com/wp-content/uploads/2026/07/attach-scaled.webp 2560w, https://alicia-ing.com/wp-content/uploads/2026/07/attach-300x148.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/07/attach-767x379.webp 767w, https://alicia-ing.com/wp-content/uploads/2026/07/attach-1024x506.webp 1024w, https://alicia-ing.com/wp-content/uploads/2026/07/attach-1536x759.webp 1536w, https://alicia-ing.com/wp-content/uploads/2026/07/attach-2048x1012.webp 2048w" sizes="(max-width: 2560px) 100vw, 2560px" /></figure>



<p class="wp-block-paragraph">offset・followSpeed・rotationSpeed・lookHeightはデフォルト値のままでも動作しますが、キャラクターのモデルサイズやゲームのジャンルに応じて調整が必要になることがほとんどです。</p>



<p class="wp-block-paragraph">値の目安は次の「パラメータ調整ガイド」を参照してください。</p>



<h3 class="wp-block-heading">パラメータ調整ガイド</h3>



<p class="wp-block-paragraph">スクリプトには4つの調整用パラメータがあります。それぞれの値を変えたときに、どのような体感の変化があるかをまとめました。</p>



<figure class="wp-block-table"><div class="scrollable-table"><table class="has-fixed-layout"><thead><tr><th>パラメータ</th><th>役割</th><th>値を大きくすると</th><th>値を小さくすると</th></tr></thead><tbody><tr><td>followSpeed</td><td>位置の追従の速さ</td><td>キャラクターにピッタリ張り付く</td><td>ワンテンポ遅れてついてくる（重厚感）</td></tr><tr><td>rotationSpeed</td><td>回転の追従の速さ</td><td>向きの切り替えが機敏になる</td><td>ゆったりと視線が追いつく</td></tr><tr><td>lookHeight</td><td>注視点の高さ</td><td>見下ろすような画角になる</td><td>水平に近い、圧迫感のある画角になる</td></tr><tr><td>offset</td><td>カメラの距離・画角</td><td>引きの画（広い視界）</td><td>寄りの画（迫力のある視界）</td></tr></tbody></table></div></figure>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-info-circle"></span>キリのいいパラメータ値に吸着させる機能を紹介しています。</span></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together">

<a target="_self" href="https://alicia-ing.com/programming/slidersnap/" title="【Unity】スライダーを特定の位置にスナップ（吸着）させる方法" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://alicia-ing.com/wp-content/uploads/2026/06/slidersnap-160x90.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://alicia-ing.com/wp-content/uploads/2026/06/slidersnap-160x90.webp 160w, https://alicia-ing.com/wp-content/uploads/2026/06/slidersnap-120x68.webp 120w, https://alicia-ing.com/wp-content/uploads/2026/06/slidersnap-320x180.webp 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【Unity】スライダーを特定の位置にスナップ（吸着）させる方法</div><div class="blogcard-snippet internal-blogcard-snippet">UnityのSliderに任意の位置へのスナップ（吸着）機能を実装する方法を解説。IPointerUpHandlerとonValueChangedを組み合わせ、snapPointsとsnapThresholdで吸着位置・距離を自由に設定できます。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://alicia-ing.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">alicia-ing.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2026.06.18</div></div></div></div></a>
</div>



<h4 class="wp-block-heading">followSpeed（追従の重さ）</h4>



<p class="wp-block-paragraph">followSpeedは、カメラがキャラクターの理想位置にどれだけ速く近づくかを決める値です。値が大きいほど追従が速く（キャラクターに張り付くような動き）、値が小さいほど追従が遅く（ワンテンポ遅れてついてくる、重厚感のある動き）なります。</p>



<p class="wp-block-paragraph">目安として、アクション性の高いゲームではfollowSpeed = 8〜10程度、じっくり見せたい探索系のゲームではfollowSpeed = 3〜5程度から調整を始めるとよいでしょう。</p>



<p class="wp-block-paragraph">極端に小さくしすぎると、キャラクターが素早く動いたときにカメラが置いていかれ、画面外にキャラクターが消えてしまうことがあるので注意してください。</p>



<h4 class="wp-block-heading">rotationSpeed（回転の追従感）</h4>



<p class="wp-block-paragraph">rotationSpeedは、カメラの向きが理想の回転にどれだけ速く追いつくかを決める値です。この値がfollowSpeedと極端に違うと、後述する「不自然な動き」の原因になりやすいため、基本的には<strong>followSpeedと近い値</strong>からスタートするのがおすすめです。</p>



<h4 class="wp-block-heading">lookHeight（注視点の高さ）</h4>



<p class="wp-block-paragraph">lookHeightは、カメラがキャラクターのどの高さを見つめるかを決める値です。キャラクターの頭上あたり（1.5前後）に設定すると自然な見下ろし角度になり、値を大きくしすぎるとカメラが必要以上に見下ろす形になります。</p>



<p class="wp-block-paragraph">逆に0に近づけると、キャラクターの足元付近を注視点にすることになり、水平に近い圧迫感のある画角になります。</p>



<h4 class="wp-block-heading">offset（カメラ距離・画角）</h4>



<p class="wp-block-paragraph">offsetはキャラクターから見たカメラの相対位置で、(左右, 上下, 前後)のベクトルで指定します。Y成分を大きくするとカメラの高さが上がり、Z成分（マイナス方向）を大きくするとキャラクターとの距離が離れて引きの画になります。</p>



<p class="wp-block-paragraph">壁際でカメラがめり込まないようにする「衝突回避」は本記事のスコープ外としていますが、offsetの距離を調整するだけでも、狭い通路でのめり込みはある程度軽減できます。</p>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">本記事では、Unityで三人称カメラの追従処理を実装する方法を解説しました。</p>



<ul class="wp-block-list">
<li>位置の追従にはVector3.Lerp、回転の追従にはQuaternion.Slerpを使う（直線補間と球面補間の使い分け）</li>



<li>Quaternion.LookRotationで注視点への方向を計算し、lookHeightで見上げ角度を調整する</li>



<li>カメラの更新処理はUpdateではなくLateUpdateに書き、実行順序によるカクつきを防ぐ</li>



<li>followSpeedとrotationSpeedは近い値に揃えることで、首振りのような不自然な動きを防げる</li>
</ul>



<p class="wp-block-paragraph">まずは本記事のパラメータの目安値から始めて、実際にゲームを動かしながらfollowSpeed・rotationSpeed・lookHeight・offsetの4つを少しずつ調整し、自分のゲームに合った「気持ちいい」カメラワークを探ってみてください。</p>



<p class="wp-block-paragraph">壁のめり込み対策やCinemachineの活用など、さらに踏み込んだカメラ制御は次のステップとして挑戦してみるとよいでしょう。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://alicia-ing.com/programming/unity/third-person-view-player/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Unity】Rigidbody+CapsuleColliderを用いたプレイヤー移動</title>
		<link>https://alicia-ing.com/programming/unity/3dplayermove/</link>
					<comments>https://alicia-ing.com/programming/unity/3dplayermove/#respond</comments>
		
		<dc:creator><![CDATA[アリッシア]]></dc:creator>
		<pubDate>Mon, 13 Jul 2026 13:19:16 +0000</pubDate>
				<category><![CDATA[Unity]]></category>
		<guid isPermaLink="false">https://alicia-ing.com/?p=8882</guid>

					<description><![CDATA[Unityでキャラクター移動を実装する際、CharacterControllerが使われます。他の物理オブジェクトと自然に衝突させたい、坂道や段差の挙動を物理演算に任せたいといった場面では、CharacterContro [&#8230;]]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-cocoon-blocks-label-box-1 label-box block-box not-nested-style cocoon-block-label-box"><div class="label-box-label block-box-label box-label fab-flag"><span class="label-box-label-text block-box-label-text box-label-text">本記事を読むと以下の実行ができます</span></div><div class="label-box-content block-box-content box-content">
<p class="wp-block-paragraph">Rigidbody＋CapsuleColliderだけでカメラ相対移動・回転・落下リスポーンに対応した3Dプレイヤー移動処理を実装できます。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1280" height="720" src="https://alicia-ing.com/wp-content/uploads/2026/07/complete.gif" alt="" class="wp-image-8889"/></figure>
</div></div>



<p class="wp-block-paragraph">Unityでキャラクター移動を実装する際、CharacterControllerが使われます。他の物理オブジェクトと自然に衝突させたい、坂道や段差の挙動を物理演算に任せたいといった場面では、CharacterControllerだと限界を感じることがあります。</p>



<p class="wp-block-paragraph">本記事では、<strong>Rigidbody＋CapsuleColliderへの移動処理</strong>を、カメラ相対移動・回転処理・落下時のリスポーンまで含めて解説します。unity rigidbody 移動の実装で「Transformによるめり込み」や「カメラのカクつき」に悩んでいる人にも役立つ内容です。</p>



<div class="wp-block-cocoon-blocks-label-box-1 label-box block-box cocoon-block-label-box"><div class="label-box-label block-box-label box-label fab-check"><span class="label-box-label-text block-box-label-text box-label-text">本記事は次の人におすすめ</span></div><div class="label-box-content block-box-content box-content">
<ul class="wp-block-list">
<li>CharacterControllerからRigidbodyへ移動処理を移行したい人</li>



<li>unity rigidbody 移動の実装方法を知りたい人</li>



<li>CharacterControllerとRigidbodyの違い・使い分けを知りたい人</li>



<li>Rigidbody移動で「Transformによるめり込み」「カメラのカクつき」に困っている人</li>



<li>カメラの向きを基準にした移動（カメラ相対移動）を実装したい人</li>
</ul>
</div></div>



<h2 class="wp-block-heading">CapsuleCollider</h2>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1672" height="941" src="https://alicia-ing.com/wp-content/uploads/2026/07/CapsuleCollider.webp" alt="" class="wp-image-8895" srcset="https://alicia-ing.com/wp-content/uploads/2026/07/CapsuleCollider.webp 1672w, https://alicia-ing.com/wp-content/uploads/2026/07/CapsuleCollider-300x169.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/07/CapsuleCollider-1024x576.webp 1024w, https://alicia-ing.com/wp-content/uploads/2026/07/CapsuleCollider-768x432.webp 768w, https://alicia-ing.com/wp-content/uploads/2026/07/CapsuleCollider-1536x864.webp 1536w, https://alicia-ing.com/wp-content/uploads/2026/07/CapsuleCollider-240x135.webp 240w, https://alicia-ing.com/wp-content/uploads/2026/07/CapsuleCollider-320x180.webp 320w, https://alicia-ing.com/wp-content/uploads/2026/07/CapsuleCollider-640x360.webp 640w" sizes="(max-width: 1672px) 100vw, 1672px" /></figure>



<p class="wp-block-paragraph">まず、プレイヤーの当たり判定に使うCapsuleCollider（カプセルコライダー）について説明します。</p>



<p class="wp-block-paragraph">CapsuleColliderは、上下に半球が付いた円柱状の当たり判定です。人型キャラクターの当たり判定としてよく使われており、実はCharacterControllerも内部的にはカプセル形状の判定を使っています。</p>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-info-circle"></span>Blenderで作成した3Dモデルをキャラクターとして導入する手順を紹介しています。</span></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together">

<a target="_self" href="https://alicia-ing.com/programming/unity/blender-import-material/" title="【Unity】Blenderで作った3Dモデルをインポートする" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://alicia-ing.com/wp-content/uploads/2023/09/blender-import-material-1-160x90.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://alicia-ing.com/wp-content/uploads/2023/09/blender-import-material-1-160x90.webp 160w, https://alicia-ing.com/wp-content/uploads/2023/09/blender-import-material-1-120x68.webp 120w, https://alicia-ing.com/wp-content/uploads/2023/09/blender-import-material-1-320x180.webp 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【Unity】Blenderで作った3Dモデルをインポートする</div><div class="blogcard-snippet internal-blogcard-snippet">UnityでBlenderで作成した3Dモデルをインポートする方法を紹介します。FBXファイルやOBJ形式のimport、Unity内でのモデルアニメーションの読み込みなどを解説しています。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://alicia-ing.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">alicia-ing.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2025.08.11</div></div></div></div></a>
</div>



<p class="wp-block-paragraph">Hierarchyでプレイヤーのオブジェクトを選択し、Inspectorの<strong>Add ComponentからPhysics &gt; Capsule Collider</strong>を追加すると導入できます。</p>



<figure class="wp-block-image aligncenter size-full"><img loading="lazy" decoding="async" width="964" height="331" src="https://alicia-ing.com/wp-content/uploads/2026/07/Add_CapsuleCollider.webp" alt="" class="wp-image-8900" srcset="https://alicia-ing.com/wp-content/uploads/2026/07/Add_CapsuleCollider.webp 964w, https://alicia-ing.com/wp-content/uploads/2026/07/Add_CapsuleCollider-300x103.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/07/Add_CapsuleCollider-768x264.webp 768w" sizes="(max-width: 964px) 100vw, 964px" /></figure>



<figure class="wp-block-table"><div class="scrollable-table"><table class="has-fixed-layout"><thead><tr><th>項目</th><th>説明</th></tr></thead><tbody><tr><td>Radius</td><td>カプセルの半径。キャラクターの横幅方向の判定に影響</td></tr><tr><td>Height</td><td>カプセルの高さ</td></tr><tr><td>Direction</td><td>カプセルの向き（通常はY軸方向）</td></tr><tr><td>Center</td><td>判定の中心位置。オブジェクトの原点からのオフセット</td></tr><tr><td>Material</td><td>摩擦・反発の設定。地面でスムーズに移動させたい場合は摩擦0に近いマテリアルを使うことがあります</td></tr></tbody></table></div></figure>



<div class="wp-block-cocoon-blocks-tab-caption-box-1 tab-caption-box block-box has-border-color has-red-border-color not-nested-style cocoon-block-tab-caption-box" style="--cocoon-custom-border-color:#e60033"><div class="tab-caption-box-label block-box-label box-label fab-check"><span class="tab-caption-box-label-text block-box-label-text box-label-text">注意</span></div><div class="tab-caption-box-content block-box-content box-content">
<p class="wp-block-paragraph">CapsuleColliderだけではキャラクターは物理演算の影響を受けません。<strong>次に説明するRigidbodyと組み合わせて</strong>初めて、重力や衝突による移動制御ができるようになります。</p>
</div></div>



<h2 class="wp-block-heading">Rigidbody</h2>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1672" height="941" src="https://alicia-ing.com/wp-content/uploads/2026/07/Rigidbody.webp" alt="" class="wp-image-8896" srcset="https://alicia-ing.com/wp-content/uploads/2026/07/Rigidbody.webp 1672w, https://alicia-ing.com/wp-content/uploads/2026/07/Rigidbody-300x169.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/07/Rigidbody-1024x576.webp 1024w, https://alicia-ing.com/wp-content/uploads/2026/07/Rigidbody-768x432.webp 768w, https://alicia-ing.com/wp-content/uploads/2026/07/Rigidbody-1536x864.webp 1536w, https://alicia-ing.com/wp-content/uploads/2026/07/Rigidbody-240x135.webp 240w, https://alicia-ing.com/wp-content/uploads/2026/07/Rigidbody-320x180.webp 320w, https://alicia-ing.com/wp-content/uploads/2026/07/Rigidbody-640x360.webp 640w" sizes="(max-width: 1672px) 100vw, 1672px" /></figure>



<p class="wp-block-paragraph">Rigidbodyは、オブジェクトに物理演算（重力・衝突・力の伝達など）を適用するためのコンポーネントです。<strong>Add ComponentからPhysics &gt; Rigidbody</strong>を追加すると、そのオブジェクトはUnityの物理エンジンの管理下に置かれます。</p>



<p class="wp-block-paragraph">今回紹介するPlayerMove.csのAwake()で設定している値を例に、代表的な設定項目を紹介します。</p>



<figure class="wp-block-image aligncenter size-full"><img loading="lazy" decoding="async" width="967" height="388" src="https://alicia-ing.com/wp-content/uploads/2026/07/Add_Rigidbody.webp" alt="" class="wp-image-8901" srcset="https://alicia-ing.com/wp-content/uploads/2026/07/Add_Rigidbody.webp 967w, https://alicia-ing.com/wp-content/uploads/2026/07/Add_Rigidbody-300x120.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/07/Add_Rigidbody-768x308.webp 768w" sizes="(max-width: 967px) 100vw, 967px" /></figure>



<figure class="wp-block-table"><div class="scrollable-table"><table class="has-fixed-layout"><thead><tr><th>項目</th><th>値</th><th>役割</th></tr></thead><tbody><tr><td>useGravity</td><td>true</td><td>重力の影響を受けるようにする</td></tr><tr><td>interpolation</td><td>RigidbodyInterpolation.Interpolate</td><td>物理演算（FixedUpdate）と描画（Update）のタイミングのズレを補間し、カメラのカクつきを抑える</td></tr><tr><td>collisionDetectionMode</td><td>CollisionDetectionMode.ContinuousDynamic</td><td>高速移動時に薄い壁などをすり抜けないようにする連続衝突判定</td></tr><tr><td>constraints</td><td>FreezeRotationX | FreezeRotationZ</td><td>X軸・Z軸の回転を固定し、キャラクターが物理演算で倒れてしまわないようにする</td></tr></tbody></table></div></figure>



<h3 class="wp-block-heading">Rigidbodyのメリット</h3>



<ul class="wp-block-list">
<li>他のRigidbodyを持つオブジェクトと自然に衝突・押し合いができる</li>



<li>坂道や段差の挙動を物理演算にまかせられるため、個別にコードで実装しなくて済む</li>



<li>velocity（速度）やAddForce（力）を使った移動ができ、慣性のある自然な動きを表現しやすい</li>



<li>動く床・爆風による吹き飛ばしなど、他の物理システムと組み合わせやすい</li>
</ul>



<h3 class="wp-block-heading">Rigidbodyが向かないケース</h3>



<ul class="wp-block-list">
<li>ジャンプの高さや着地位置をフレーム単位で厳密に制御したいシビアなアクションゲーム</li>



<li>ネットワーク対戦などで移動の再現性（決定論的な挙動）が必須な場合</li>



<li>物理演算特有の揺れ・めり込みを避けたい、シンプルな一方向移動のみのケース</li>
</ul>



<p class="wp-block-paragraph">こうしたケースでは、<strong>無理にRigidbodyへ移行せずCharacterControllerを使</strong>う<strong>ほうが扱いやすい</strong>です。移行はあくまで手段であり、目的ではないことに注意してください。</p>



<h2 class="wp-block-heading">CharacterControllerとRigidbody＋CapsuleColliderの違い</h2>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1672" height="941" src="https://alicia-ing.com/wp-content/uploads/2026/07/CharacterController_compair.webp" alt="" class="wp-image-8898" srcset="https://alicia-ing.com/wp-content/uploads/2026/07/CharacterController_compair.webp 1672w, https://alicia-ing.com/wp-content/uploads/2026/07/CharacterController_compair-300x169.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/07/CharacterController_compair-1024x576.webp 1024w, https://alicia-ing.com/wp-content/uploads/2026/07/CharacterController_compair-768x432.webp 768w, https://alicia-ing.com/wp-content/uploads/2026/07/CharacterController_compair-1536x864.webp 1536w, https://alicia-ing.com/wp-content/uploads/2026/07/CharacterController_compair-240x135.webp 240w, https://alicia-ing.com/wp-content/uploads/2026/07/CharacterController_compair-320x180.webp 320w, https://alicia-ing.com/wp-content/uploads/2026/07/CharacterController_compair-640x360.webp 640w" sizes="(max-width: 1672px) 100vw, 1672px" /></figure>



<p class="wp-block-paragraph">CharacterController rigidbody 違いで検索している人向けに、両者の特徴を比較します。</p>



<figure class="wp-block-table"><div class="scrollable-table"><table class="has-fixed-layout"><thead><tr><th>項目</th><th>CharacterController</th><th>Rigidbody＋CapsuleCollider</th></tr></thead><tbody><tr><td>移動方法</td><td>Move()&nbsp;/&nbsp;SimpleMove()</td><td>velocity / MovePosition / AddForce</td></tr><tr><td>物理演算</td><td>受けない（独自の疑似物理）</td><td>Unityの物理エンジンに従う</td></tr><tr><td>他オブジェクトとの相互作用</td><td>基本的に一方的に押すのみ</td><td>相互に力を伝え合う（押される・乗る等）</td></tr><tr><td>段差・坂道</td><td>パラメータで個別調整が必要</td><td>物理演算が自然に処理する</td></tr><tr><td>移動の再現性</td><td>高い（決定論的）</td><td>物理演算の影響を受けやすい</td></tr><tr><td>実装の手軽さ</td><td>シンプルで扱いやすい</td><td>設定項目が多く、挙動の理解が必要</td></tr></tbody></table></div></figure>



<p class="wp-block-paragraph">要するに、CharacterControllerは「移動処理に特化した専用コンポーネント」、Rigidbodyは「物理演算そのものを使って移動も実現するコンポーネント」という違いです。</p>



<h3 class="wp-block-heading">なぜCharacterControllerではなくRigidbodyにする理由</h3>



<p class="wp-block-paragraph">CharacterControllerからRigidbodyへの移行を検討すべき代表的な判断基準は次の通りです。</p>



<ul class="wp-block-list">
<li>動く床・押せるオブジェクトなど、他の物理オブジェクトとキャラクターを相互作用させたい</li>



<li>坂道・段差の挙動を、個別のコードではなく物理演算にまかせたい</li>



<li>爆風で吹き飛ばす、掴まれて引っ張られるなど、外力による移動を扱いたい</li>



<li>ジャンプや落下の挙動を、他のコンポーネント（例：ジャンプ専用コンポーネント）とY軸だけ分担するような設計にしたい</li>
</ul>



<p class="wp-block-paragraph">逆に、<strong>移動の精密な制御を最優先するアクションゲームでは、CharacterControllerのままのほうが扱いやすい場合も</strong>あります。unity charactercontroller rigidbody 移行を検討するときは、プロジェクトで物理的な相互作用がどれだけ必要かを基準に判断してください。</p>



<h2 class="wp-block-heading">3Dキャラクターの移動処理</h2>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1672" height="941" src="https://alicia-ing.com/wp-content/uploads/2026/07/Reason_Rigidbody.webp" alt="" class="wp-image-8897" srcset="https://alicia-ing.com/wp-content/uploads/2026/07/Reason_Rigidbody.webp 1672w, https://alicia-ing.com/wp-content/uploads/2026/07/Reason_Rigidbody-300x169.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/07/Reason_Rigidbody-1024x576.webp 1024w, https://alicia-ing.com/wp-content/uploads/2026/07/Reason_Rigidbody-768x432.webp 768w, https://alicia-ing.com/wp-content/uploads/2026/07/Reason_Rigidbody-1536x864.webp 1536w, https://alicia-ing.com/wp-content/uploads/2026/07/Reason_Rigidbody-240x135.webp 240w, https://alicia-ing.com/wp-content/uploads/2026/07/Reason_Rigidbody-320x180.webp 320w, https://alicia-ing.com/wp-content/uploads/2026/07/Reason_Rigidbody-640x360.webp 640w" sizes="(max-width: 1672px) 100vw, 1672px" /></figure>



<p class="wp-block-paragraph">本記事では、ここまで説明したRigidbodyとCapsuleColliderを組み合わせて、CharacterControllerを使わない3Dキャラクターの移動処理を実装します。単に位置を動かすだけでなく、以下の3つの動きを備えた、実践で使えるレベルのプレイヤーコントローラーを目指します。</p>



<ul class="wp-block-list">
<li><strong>カメラ相対移動：</strong> カメラが向いている方向を基準に、入力方向を変換して移動する</li>



<li><strong>移動方向への回転：</strong> キャラクターが移動している方向へ滑らかに向きを変える</li>



<li><strong>落下時の自動リスポーン：</strong> マップの外や穴に落下した場合に、指定した位置へ自動的に戻す</li>
</ul>



<p class="wp-block-paragraph">これらはすべて、RigidbodyのFixedUpdate内での速度・回転操作として実装します。</p>



<h3 class="wp-block-heading">ソースコード</h3>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-file="PlayerMove.cs" data-lang="C#"><code>using UnityEngine;

[RequireComponent(typeof(Rigidbody), typeof(PlayerInputHandler))]
public class PlayerMove : MonoBehaviour
{
    [SerializeField] private Transform cameraTransform;
    [SerializeField] private float moveSpeed = 4f;
    [SerializeField] private float rotationSpeed = 10f;
    [SerializeField] private float fallResetY = -50f;
    [SerializeField] private Vector3 respawnPosition = Vector3.zero;

    private Rigidbody rb;
    private PlayerInputHandler input;
    private Animator animator;

    private Vector3 moveDirection;
    private bool isMoving;

    private void Awake()
    {
        rb = GetComponent&lt;Rigidbody&gt;();
        input = GetComponent&lt;PlayerInputHandler&gt;();
        animator = GetComponentInChildren&lt;Animator&gt;();

        rb.useGravity = true;
        rb.interpolation = RigidbodyInterpolation.Interpolate;
        rb.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic;
        rb.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationZ;

        if (cameraTransform == null && Camera.main != null)
        {
            cameraTransform = Camera.main.transform;
        }
    }

    private void Update()
    {
        if (rb.position.y &lt; fallResetY)
        {
            Respawn();
            return;
        }

        moveDirection = CameraRelativeDirection(input.MoveInput);
        isMoving = moveDirection.sqrMagnitude &gt; 0.0001f;

        animator.speed = isMoving ? 1f : 0f;
    }

    private void FixedUpdate()
    {
        if (isMoving)
        {
            Quaternion targetRotation = Quaternion.LookRotation(moveDirection);
            rb.MoveRotation(Quaternion.Slerp(rb.rotation, targetRotation, rotationSpeed * Time.fixedDeltaTime));
        }

        Vector3 horizontalVelocity = moveDirection.normalized * moveSpeed;
        Vector3 velocity = rb.linearVelocity;
        velocity.x = horizontalVelocity.x;
        velocity.z = horizontalVelocity.z;
        rb.linearVelocity = velocity;
    }

    private Vector3 CameraRelativeDirection(Vector2 moveInput)
    {
        if (cameraTransform == null || moveInput.sqrMagnitude &lt; 0.0001f)
        {
            return Vector3.zero;
        }

        Vector3 forward = cameraTransform.forward;
        forward.y = 0f;
        forward.Normalize();

        Vector3 right = cameraTransform.right;
        right.y = 0f;
        right.Normalize();

        return forward * moveInput.y + right * moveInput.x;
    }

    private void Respawn()
    {
        rb.linearVelocity = Vector3.zero;
        rb.angularVelocity = Vector3.zero;
        rb.position = respawnPosition;
        transform.position = respawnPosition;
    }
}</code></pre></div>



<h3 class="wp-block-heading">解説</h3>



<ul class="wp-block-list">
<li><strong>カメラ相対移動の仕組み</strong></li>
</ul>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>Vector3 forward = cameraTransform.forward;
forward.y = 0f;
forward.Normalize();

Vector3 right = cameraTransform.right;
right.y = 0f;
right.Normalize();

return forward * moveInput.y + right * moveInput.x;</code></pre></div>



<p class="wp-block-paragraph">カメラのforward（前方向）・right（右方向）ベクトルをそのまま使うと、カメラが下や上を向いているときにY成分が混ざってしまい、キャラクターが浮いたり沈んだりする移動方向になってしまいます。</p>



<p class="wp-block-paragraph">そこで、forward.y = 0f・right.y = 0fとしてY成分を打ち消し、XZ平面（水平面）に投影してからNormalize()で正規化しています。こうすることで、カメラがどの角度を向いていても、キャラクターは常に水平方向にのみ移動します。</p>



<p class="wp-block-paragraph">最後に、入力値moveInput.x（左右）・moveInput.y（前後）をそれぞれright・forwardに掛けて合成することで、「カメラの向きを基準にした移動方向」が完成します。この処理を扱った解説記事は少なく、三人称視点のゲームでスティック入力をそのままワールド座標として使ってしまい、カメラを回すと操作方向がズレるという不具合の原因にもなりやすいポイントです。</p>



<ul class="wp-block-list">
<li><strong>FixedUpdateでの速度制御とY軸の分担設計</strong></li>
</ul>



<p class="wp-block-paragraph">移動処理はFixedUpdate()の中で行っています。Unityの物理演算はFixedUpdateのタイミングで実行されるため、RigidbodyのvelocityやMovePositionを操作する処理は必ずFixedUpdateに書く必要があります。Updateで操作すると、フレームレートによって物理演算とのタイミングがズレて挙動が不安定になります。</p>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>Vector3 horizontalVelocity = moveDirection.normalized * moveSpeed;
Vector3 velocity = rb.linearVelocity;
velocity.x = horizontalVelocity.x;
velocity.z = horizontalVelocity.z;
rb.linearVelocity = velocity;</code></pre></div>



<p class="wp-block-paragraph">ここで注目したいのは、velocity.xとvelocity.zだけを書き換えて、velocity.yにはあえて触れていない点です。rb.linearVelocity（旧velocity）を丸ごと上書きしてしまうと、ジャンプや落下によるY方向の速度まで毎フレーム0にリセットされ、ジャンプ処理と競合してしまいます。</p>



<p class="wp-block-paragraph">コード内のコメントにもある通り、PlayerMoveはX/Z軸（水平方向の移動）だけを担当し、Y軸（ジャンプ・落下）は別のコンポーネントに委ねる設計にしています。この役割分担により、PlayerMoveと別のジャンプ用コンポーネントのどちらが先にFixedUpdateで実行されても、お互いの担当軸を上書きし合わない安全な作りになります。AddForceではなくvelocityを直接操作しているのも、この分担を明確に保つためです。</p>



<ul class="wp-block-list">
<li><strong>移動方向への回転処理</strong></li>
</ul>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>Quaternion targetRotation = Quaternion.LookRotation(moveDirection);
rb.MoveRotation(Quaternion.Slerp(rb.rotation, targetRotation, rotationSpeed * Time.fixedDeltaTime));</code></pre></div>



<p class="wp-block-paragraph">キャラクターを移動方向へ滑らかに回転させる処理です。Quaternion.LookRotation(moveDirection)で「移動方向を向くための目標の回転」を求め、Quaternion.Slerpで現在の回転から目標の回転へ少しずつ補間しています。</p>



<p class="wp-block-paragraph">ポイントは、transform.rotationを直接書き換えるのではなくrb.MoveRotation()を使っている点です。RigidbodyがアタッチされたオブジェクトをTransform経由で直接動かすと、物理演算のスレッドと描画のタイミングがズレて衝突判定が不安定になります。回転も移動と同様に、Rigidbody用のAPIを通して行うのが基本です。</p>



<ul class="wp-block-list">
<li><strong>落下時のリスポーン処理</strong></li>
</ul>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>private void Update()
{
    if (rb.position.y &lt; fallResetY)
    {
        Respawn();
        return;
    }
    ...
}

private void Respawn()
{
    rb.linearVelocity = Vector3.zero;
    rb.angularVelocity = Vector3.zero;
    rb.position = respawnPosition;
    transform.position = respawnPosition;
}</code></pre></div>



<p class="wp-block-paragraph">マップの外や穴に落下してしまった場合に備えて、Y座標がfallResetYを下回ったら自動的にリスポーンする処理です。ジャンプ台の位置調整ミスやコライダーの隙間から落下してしまうことは実際の開発でもよく起きるため、あらかじめ用意しておくと安心です。</p>



<p class="wp-block-paragraph">Respawn()では、位置をリセットするだけでなくlinearVelocity（速度）とangularVelocity（角速度）も必ずゼロに戻しています。速度をリセットせずに位置だけ戻すと、落下中に蓄積した速度がそのまま残り、リスポーン直後に想定外の方向へ吹き飛んでしまうため注意してください。</p>



<h2 class="wp-block-heading">実演</h2>



<p class="wp-block-paragraph">3DモデルにPlayerMove.csをアタッチします。</p>



<p class="wp-block-paragraph">この3DモデルはCapsuleColliderを追加してください。<br>アタッチした後に実行するとで冒頭で紹介した動作を実行できます。</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1285" height="703" src="https://alicia-ing.com/wp-content/uploads/2026/07/AttachPlayerMove.webp" alt="" class="wp-image-8902" srcset="https://alicia-ing.com/wp-content/uploads/2026/07/AttachPlayerMove.webp 1285w, https://alicia-ing.com/wp-content/uploads/2026/07/AttachPlayerMove-300x164.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/07/AttachPlayerMove-1024x560.webp 1024w, https://alicia-ing.com/wp-content/uploads/2026/07/AttachPlayerMove-768x420.webp 768w" sizes="(max-width: 1285px) 100vw, 1285px" /></figure>



<h2 class="wp-block-heading">よくあるハマりどころと対策</h2>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1672" height="941" src="https://alicia-ing.com/wp-content/uploads/2026/07/trouble3Dplayermove.webp" alt="" class="wp-image-8899" srcset="https://alicia-ing.com/wp-content/uploads/2026/07/trouble3Dplayermove.webp 1672w, https://alicia-ing.com/wp-content/uploads/2026/07/trouble3Dplayermove-300x169.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/07/trouble3Dplayermove-1024x576.webp 1024w, https://alicia-ing.com/wp-content/uploads/2026/07/trouble3Dplayermove-768x432.webp 768w, https://alicia-ing.com/wp-content/uploads/2026/07/trouble3Dplayermove-1536x864.webp 1536w, https://alicia-ing.com/wp-content/uploads/2026/07/trouble3Dplayermove-240x135.webp 240w, https://alicia-ing.com/wp-content/uploads/2026/07/trouble3Dplayermove-320x180.webp 320w, https://alicia-ing.com/wp-content/uploads/2026/07/trouble3Dplayermove-640x360.webp 640w" sizes="(max-width: 1672px) 100vw, 1672px" /></figure>



<ul class="wp-block-list">
<li><strong>Transform移動によるめり込み</strong></li>
</ul>



<p class="wp-block-paragraph">Rigidbodyが付いたオブジェクトをtransform.position += …のように直接移動させると、物理演算とタイミングがズレて壁や地面にめり込んでしまうことがあります。これはunity rigidbody transform 移動でよく報告される不具合です。</p>



<p class="wp-block-paragraph">本記事のコードのように、移動はFixedUpdate内でrb.linearVelocityまたはrb.MovePosition()を使って行います。Transformを直接書き換える処理を移動ロジックに混在させないことが重要です。</p>



<ul class="wp-block-list">
<li><strong>カメラのカクつき</strong></li>
</ul>



<p class="wp-block-paragraph">Rigidbodyの位置はFixedUpdate（物理演算のタイミング）で更新されますが、カメラの描画はUpdate（描画のタイミング）で行われます。この2つのタイミングにはズレがあるため、追従カメラがカクついて見えることがあります。</p>



<p class="wp-block-paragraph"> Awake()で設定しているrb.interpolation = RigidbodyInterpolation.Interpolate;が、このズレを補間して滑らかに見せる役割を持っています。加えて、追従カメラ側のスクリプトもUpdateではなくLateUpdateでプレイヤーを追従させることで、キャラクターの移動が反映された後にカメラが追従するようになり、カクつきをさらに抑えられます。</p>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">CharacterControllerからRigidbody＋CapsuleColliderへの移動処理の移行手順として、以下を解説しました。</p>



<ul class="wp-block-list">
<li>CapsuleColliderとRigidbodyの基本的な役割と設定値</li>



<li>CharacterControllerとの違いと、移行すべきかどうかの判断基準</li>



<li>カメラ相対移動・FixedUpdateでのX/Z軸のみの速度制御・回転処理・落下リスポーンの実装</li>



<li>Rigidbodyへの移行は、他の物理オブジェクトとの相互作用が必要になったときに大きな効果を発揮します。一方で、精密な移動制御が最優先の場合は無理に移行する必要はありません。プロジェクトの要件に合わせて、CharacterControllerとRigidbodyを使い分けてください。</li>
</ul>



<p class="wp-block-paragraph">次のステップとして、Y軸を分担しているジャンプ処理や、カメラ相対移動と組み合わせる三人称カメラの実装もあわせて検討してみると、より完成度の高いプレイヤー操作を作り込めます。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://alicia-ing.com/programming/unity/3dplayermove/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Unity】スライダーを特定の位置にスナップ（吸着）させる方法</title>
		<link>https://alicia-ing.com/programming/slidersnap/</link>
					<comments>https://alicia-ing.com/programming/slidersnap/#respond</comments>
		
		<dc:creator><![CDATA[アリッシア]]></dc:creator>
		<pubDate>Wed, 17 Jun 2026 16:44:26 +0000</pubDate>
				<category><![CDATA[Unity]]></category>
		<category><![CDATA[プログラミング]]></category>
		<guid isPermaLink="false">https://alicia-ing.com/?p=8839</guid>

					<description><![CDATA[音量調整や設定画面のスライダーで、「キリのいい値にぴったり合わせたい」と感じたことはありませんか？そのような場面で役立つのがスナップ（吸着）機能です。特定の値に近づくと自動で吸い付くため、ユーザーが意図した値に合わせやす [&#8230;]]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-cocoon-blocks-label-box-1 label-box block-box not-nested-style cocoon-block-label-box"><div class="label-box-label block-box-label box-label fab-flag"><span class="label-box-label-text block-box-label-text box-label-text">本記事を読むと以下の実行ができます</span></div><div class="label-box-content block-box-content box-content">
<p class="wp-block-paragraph">Unityのスライダーを、指定した任意の位置に自動で吸着（スナップ）させる</p>



<figure class="wp-block-image aligncenter size-full"><img loading="lazy" decoding="async" width="1280" height="720" src="https://alicia-ing.com/wp-content/uploads/2026/06/complete.gif" alt="" class="wp-image-8842"/></figure>
</div></div>



<p class="wp-block-paragraph">音量調整や設定画面のスライダーで、「キリのいい値にぴったり合わせたい」と感じたことはありませんか？そのような場面で役立つのが<strong>スナップ（吸着）機能</strong>です。特定の値に近づくと自動で吸い付くため、ユーザーが意図した値に合わせやすくなります。</p>



<p class="wp-block-paragraph">本記事では、スナップさせたい位置と吸着距離を自由に設定できる実装方法を解説します。</p>



<div class="wp-block-cocoon-blocks-label-box-1 label-box block-box cocoon-block-label-box"><div class="label-box-label block-box-label box-label fab-check"><span class="label-box-label-text block-box-label-text box-label-text">本記事は次の人におすすめ</span></div><div class="label-box-content block-box-content box-content">
<ul class="wp-block-list">
<li>&#8211; Unityのスライダーに吸着（スナップ）機能を付けたい人</li>



<li>&#8211; 等間隔ではなく、任意の位置にスナップさせたい人</li>



<li>IPointerUpHandler` の使い方を知りたい人</li>



<li>&#8211; 音量や設定値のUIをより使いやすくしたい人</li>
</ul>
</div></div>



<h2 class="wp-block-heading">Sliderのスナップとは？</h2>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1672" height="941" src="https://alicia-ing.com/wp-content/uploads/2026/06/snap_slider.webp" alt="" class="wp-image-8845" srcset="https://alicia-ing.com/wp-content/uploads/2026/06/snap_slider.webp 1672w, https://alicia-ing.com/wp-content/uploads/2026/06/snap_slider-300x169.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/06/snap_slider-1024x576.webp 1024w, https://alicia-ing.com/wp-content/uploads/2026/06/snap_slider-768x432.webp 768w, https://alicia-ing.com/wp-content/uploads/2026/06/snap_slider-1536x864.webp 1536w, https://alicia-ing.com/wp-content/uploads/2026/06/snap_slider-120x68.webp 120w, https://alicia-ing.com/wp-content/uploads/2026/06/snap_slider-160x90.webp 160w, https://alicia-ing.com/wp-content/uploads/2026/06/snap_slider-320x180.webp 320w" sizes="(max-width: 1672px) 100vw, 1672px" /></figure>



<p class="wp-block-paragraph">スナップとは、ある値に近づいたときに自動でその値に吸い付く動作のことです。</p>



<p class="wp-block-paragraph">Unityの標準Sliderコンポーネントにはスナップ機能が搭載されていません。スライダーをドラッグすると連続した値が取れるだけで、特定の値に吸着させるにはスクリプトで制御する必要があります。</p>



<h2 class="wp-block-heading">Sliderの準備</h2>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1672" height="941" src="https://alicia-ing.com/wp-content/uploads/2026/06/slider_preparation.webp" alt="" class="wp-image-8846" srcset="https://alicia-ing.com/wp-content/uploads/2026/06/slider_preparation.webp 1672w, https://alicia-ing.com/wp-content/uploads/2026/06/slider_preparation-300x169.webp 300w, https://alicia-ing.com/wp-content/uploads/2026/06/slider_preparation-1024x576.webp 1024w, https://alicia-ing.com/wp-content/uploads/2026/06/slider_preparation-768x432.webp 768w, https://alicia-ing.com/wp-content/uploads/2026/06/slider_preparation-1536x864.webp 1536w, https://alicia-ing.com/wp-content/uploads/2026/06/slider_preparation-120x68.webp 120w, https://alicia-ing.com/wp-content/uploads/2026/06/slider_preparation-160x90.webp 160w, https://alicia-ing.com/wp-content/uploads/2026/06/slider_preparation-320x180.webp 320w" sizes="(max-width: 1672px) 100vw, 1672px" /></figure>



<p class="wp-block-paragraph">UnityのHierarchyウィンドウから<strong>UI &gt; Slider</strong> を追加してください。</p>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-info-circle"></span>スライダーの設定はこちらで紹介しています。</span></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together">

<a target="_self" href="https://alicia-ing.com/programming/unity/slider-bar/" title="【Unity】スライダー使い方｜制限時間ゲージ、HPバー、音量調整" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://alicia-ing.com/wp-content/uploads/2024/01/slider-bar-160x90.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://alicia-ing.com/wp-content/uploads/2024/01/slider-bar-160x90.webp 160w, https://alicia-ing.com/wp-content/uploads/2024/01/slider-bar-120x68.webp 120w, https://alicia-ing.com/wp-content/uploads/2024/01/slider-bar-320x180.webp 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【Unity】スライダー使い方｜制限時間ゲージ、HPバー、音量調整</div><div class="blogcard-snippet internal-blogcard-snippet">Unityのスライダー（Slider）でHPバー・制限時間ゲージ・音量調整を作る方法を解説。Min Value・Max Valueの設定、HPバーをなめらかに減らすスクリプト、離したとき・押したときの処理まで紹介します。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://alicia-ing.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">alicia-ing.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2026.10.12</div></div></div></div></a>
</div>



<p class="wp-block-paragraph">また、スナップした値をテキストで表示するため、<strong>UI &gt; Text &#8211; TextMeshPro</strong> も追加します。</p>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-info-circle"></span>Unityで文字表示はこちらで紹介しています。</span></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together">

<a target="_self" href="https://alicia-ing.com/programming/unity/textmeshpro/" title="【Unity】TextMeshPro-日本語表示とスクリプト制御" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://alicia-ing.com/wp-content/uploads/2024/01/textmeshpro-160x90.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://alicia-ing.com/wp-content/uploads/2024/01/textmeshpro-160x90.webp 160w, https://alicia-ing.com/wp-content/uploads/2024/01/textmeshpro-120x68.webp 120w, https://alicia-ing.com/wp-content/uploads/2024/01/textmeshpro-320x180.webp 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【Unity】TextMeshPro-日本語表示とスクリプト制御</div><div class="blogcard-snippet internal-blogcard-snippet">UnityのTextMeshProは日本語のテキストを美しく表示し、スクリプトでテキストを動的に変更することも可能です。改行は&quot;\n&quot;でします。&quot;japanese_full.txt&quot;ファイルを読み込んでTextMeshProに適用します。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://alicia-ing.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">alicia-ing.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2025.08.11</div></div></div></div></a>
</div>



<h3 class="wp-block-heading">ソースコード</h3>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using TMPro;

public class SliderSnap : MonoBehaviour, IPointerUpHandler
{
    public Slider slider;
    public TextMeshProUGUI positionTMP;

    [Header(&quot;スナップ設定&quot;)]
    public float[] snapPoints = new float[] { 0.5f, 0.2f }; // 正規化値(0~1)
    public float snapThreshold = 0.02f;

    void Start()
    {
        slider.onValueChanged.AddListener(OnValueChanged);
        UpdatePositionDisplay();
    }

    void OnDestroy()
    {
        slider.onValueChanged.RemoveListener(OnValueChanged);
    }

    void OnValueChanged(float value)
    {
        float snapped;
        if (TryGetSnapPoint(value, out snapped))
        {
            slider.onValueChanged.RemoveListener(OnValueChanged);
            slider.value = snapped;
            slider.onValueChanged.AddListener(OnValueChanged);
        }

        UpdatePositionDisplay();
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        float snapped;
        if (!TryGetSnapPoint(slider.value, out snapped)) return;

        slider.onValueChanged.RemoveListener(OnValueChanged);
        slider.value = snapped;
        slider.onValueChanged.AddListener(OnValueChanged);

        UpdatePositionDisplay();
    }

    bool TryGetSnapPoint(float value, out float snapped)
    {
        snapped = value;
        if (snapPoints == null || snapPoints.Length == 0) return false;

        float minDist = float.MaxValue;
        float nearest = value;

        foreach (float point in snapPoints)
        {
            float dist = Mathf.Abs(value - point);
            if (dist &lt; minDist)
            {
                minDist = dist;
                nearest = point;
            }
        }

        if (minDist &lt; snapThreshold)
        {
            snapped = nearest;
            return true;
        }
        return false;
    }

    public string GetPositionText(float value)
    {
        float rounded = Mathf.Round(value * 100f) / 100f;
        return rounded.ToString(&quot;0.##&quot;);
    }

    void UpdatePositionDisplay()
    {
        if (positionTMP == null) return;
        positionTMP.text = GetPositionText(slider.value);
    }
}</code></pre></div>



<h3 class="wp-block-heading">解説</h3>



<ul class="wp-block-list">
<li><strong>snapPoints と snapThreshold</strong></li>
</ul>



<p class="wp-block-paragraph">snapPointsは、スナップさせたい位置を<strong>正規化値（0〜1）</strong>で指定する配列です。Sliderの最小値が0、最大値が1に対応します。例えば 0.5fはスライダーの中央、0.2fは左から20%の位置になります。</p>



<p class="wp-block-paragraph">snapThresholdは吸着距離です。スライダーの値がスナップポイントからこの値以内に入ると、自動でスナップします。0.02fは全体の2%の範囲です。値を大きくするほど遠くからでも吸着するようになります。</p>



<p class="wp-block-paragraph">どちらもInspectorから変更できるので、スクリプトを書き直さずに調整できます。</p>



<ul class="wp-block-list">
<li><strong>OnValueChanged でのスナップ処理</strong></li>
</ul>



<p class="wp-block-paragraph">ドラッグ中にスナップポイントへ近づいたとき、リアルタイムで吸着させる処理です。</p>



<div class="wp-block-cocoon-blocks-tab-caption-box-1 tab-caption-box block-box has-border-color has-luminous-vivid-amber-border-color not-nested-style cocoon-block-tab-caption-box" style="--cocoon-custom-border-color:#fcb900"><div class="tab-caption-box-label block-box-label box-label fab-exclamation-circle"><span class="tab-caption-box-label-text block-box-label-text box-label-text">注意</span></div><div class="tab-caption-box-content block-box-content box-content">
<p class="wp-block-paragraph">slider.value = snappedを実行するとonValueChangedが再び発火します。そのままではOnValueChangedが無限に呼ばれてしまうため、値を変更する前にRemoveListenerでイベントを一時解除し、変更後にAddListenerで再登録しています。</p>
</div></div>



<ul class="wp-block-list">
<li><strong>IPointerUpHandler でのスナップ処理</strong></li>
</ul>



<p class="wp-block-paragraph">IPointerUpHandlerのOnPointerUpは、<strong>マウスボタンやタッチを離した瞬間</strong>に呼ばれます。</p>



<p class="wp-block-paragraph">ドラッグを離した瞬間にもスナップ処理を走らせることで、「ドラッグ中はスナップしなかったが、離したときにスナップポイントの近くにいた」というケースも確実に吸着できます。OnValueChangedとの二重対応で、取りこぼしなくスナップが動作します。</p>



<p class="wp-block-paragraph">IPointerUpHandlerを使うためには、クラス宣言に IPointerUpHandlerを追加し、スクリプトをスライダーと<strong>同じGameObjectにアタッチ</strong>する必要があります。</p>



<ul class="wp-block-list">
<li><strong>TryGetSnapPoint メソッド</strong></li>
</ul>



<p class="wp-block-paragraph">スナップすべきかどうかを判定するメソッドです。out引数でスナップ先の値を返します。</p>



<p class="wp-block-paragraph">処理の流れは以下の通りです。</p>



<ol class="wp-block-list">
<li>すべてのsnapPointsとの距離を計算する</li>



<li>最も近いポイントを探す</li>



<li>その距離がsnapThreshold未満であればスナップ対象と判定しtrueを返す</li>



<li>閾値以上であれば何もせずfalseを返す</li>
</ol>



<p class="wp-block-paragraph">複数のスナップポイントがあっても、常に<strong>最も近い1点</strong>に吸着します。</p>



<ul class="wp-block-list">
<li><strong>TextMeshPro での値表示</strong></li>
</ul>



<p class="wp-block-paragraph">現在のスライダー値をTextMeshProのテキストに表示します。Mathf.Round で小数点2桁に丸めてから &#8220;0.##&#8221;フォーマットで表示しています。&#8221;0.##&#8221; は末尾の不要なゼロを省略してくれるので、0.50ではなく 0.5のようにすっきり表示されます。</p>



<p class="wp-block-paragraph">positionTMPがnullの場合は何もしないようにしているので、テキスト表示が不要な場合はアタッチしなくても動作します。</p>



<h2 class="wp-block-heading">実演</h2>



<p class="wp-block-paragraph">スクリプトができたら、Inspectorで以下の通り設定してください。</p>



<figure class="wp-block-image aligncenter size-full"><img loading="lazy" decoding="async" width="769" height="460" src="https://alicia-ing.com/wp-content/uploads/2026/06/attachment.webp" alt="" class="wp-image-8847" srcset="https://alicia-ing.com/wp-content/uploads/2026/06/attachment.webp 769w, https://alicia-ing.com/wp-content/uploads/2026/06/attachment-300x179.webp 300w" sizes="(max-width: 769px) 100vw, 769px" /></figure>



<figure class="wp-block-table"><div class="scrollable-table"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">Slider</td><td class="has-text-align-center" data-align="center">シーン上のSliderコンポーネントをアタッチ</td></tr><tr><td class="has-text-align-center" data-align="center">PositonTMP</td><td class="has-text-align-center" data-align="center">値表示に使うTextMeshProUGUIをアタッチ</td></tr><tr><td class="has-text-align-center" data-align="center">SnapPoints</td><td class="has-text-align-center" data-align="center">スナップさせたい位置を正規化値（0〜1）で入力</td></tr><tr><td class="has-text-align-center" data-align="center">SnapThreshold</td><td class="has-text-align-center" data-align="center">吸着距離。デフォルト `0.02f` から調整可能</td></tr></tbody></table></div></figure>



<div class="wp-block-cocoon-blocks-tab-caption-box-1 tab-caption-box block-box has-border-color has-luminous-vivid-amber-border-color not-nested-style cocoon-block-tab-caption-box" style="--cocoon-custom-border-color:#fcb900"><div class="tab-caption-box-label block-box-label box-label fab-exclamation-circle"><span class="tab-caption-box-label-text block-box-label-text box-label-text">注意</span></div><div class="tab-caption-box-content block-box-content box-content">
<p class="wp-block-paragraph">スクリプトは<strong>Sliderと同じGameObject</strong>にアタッチしてください。別のGameObjectにアタッチすると `IPointerUpHandler` が機能しません。</p>
</div></div>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">Unityのスライダーに任意の位置へのスナップ機能を実装しました。</p>



<ul class="wp-block-list">
<li>snapPoints（float配列）でスナップ位置を自由に指定できます</li>



<li>snapThresholdで吸着距離を調整できます</li>



<li>onValueChangedと IPointerUpHandlerを併用することで、ドラッグ中・離した瞬間どちらにも対応できます</li>



<li>&#8211; リスナーの二重発火を防ぐため、値変更前後で RemoveListener → AddListenerの順で処理します</li>
</ul>



<p class="wp-block-paragraph">音量調整や設定画面など、特定の値に合わせやすくしたいスライダーUIに活用してみてください。</p>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://alicia-ing.com/programming/slidersnap/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Unity】ゲームビルドやり方｜画面サイズ・WebGL設定</title>
		<link>https://alicia-ing.com/programming/build-setting/</link>
					<comments>https://alicia-ing.com/programming/build-setting/#respond</comments>
		
		<dc:creator><![CDATA[アリッシア]]></dc:creator>
		<pubDate>Sun, 16 Nov 2025 22:00:00 +0000</pubDate>
				<category><![CDATA[Unity]]></category>
		<category><![CDATA[プログラミング]]></category>
		<guid isPermaLink="false">https://alicia-ing.com/?p=8790</guid>

					<description><![CDATA[自作したゲームを販売する上で、作品のexe化（ビルド）しなければいけません。本記事では、ビルドする方法を分かりやすく解説します。 Unityのビルドとは？ Unityにおける「ビルド」とは、開発中のゲームプロジェクトを実 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">自作したゲームを販売する上で、作品のexe化（ビルド）しなければいけません。<br>本記事では、ビルドする方法を分かりやすく解説します。</p>



<div class="wp-block-cocoon-blocks-label-box-1 label-box block-box cocoon-block-label-box"><div class="label-box-label block-box-label box-label fab-check"><span class="label-box-label-text block-box-label-text box-label-text">本記事は次の人におすすめ</span></div><div class="label-box-content block-box-content box-content">
<ul class="wp-block-list">
<li>Unityで開発したゲームを出品したい人</li>



<li>ビルドのやり方を知りたい人</li>



<li>WebGLの形式でビルドしたい人</li>



<li>ビルドしたら画面サイズがおかしくなった人</li>
</ul>
</div></div>



<h2 class="wp-block-heading">Unityのビルドとは？</h2>



<p class="wp-block-paragraph">Unityにおける「ビルド」とは、開発中の<strong>ゲームプロジェクトを実行可能なアプリケーションやデータに変換する作業</strong>のことです。エディタ上で動かしていたゲームを、Windows/Mac用の実行ファイルやWebブラウザで動作するデータ（WebGL）などに出力し、<strong>他のユーザーがプレイできる</strong>形にします。</p>



<p class="wp-block-paragraph">Unityエディタでの再生は<strong>開発者ローカルのテスト</strong>に過ぎず、完成したゲームを配布・公開するにはビルドして所定のプラットフォーム用ファイルを用意する必要があります。ビルドを行うことで、初めてUnityをインストールしていないPCでもゲームを起動できたり、Web上に公開して遊んでもらうことが可能になります。</p>



<p class="wp-block-paragraph">ビルドの結果、例えばWindowsなら「.exe実行ファイルとデータフォルダ」、WebGLなら「index.htmlとUnityの生成したライブラリファイル群」など、プラットフォームごとに必要なファイル一式が出力されます。<strong>これらを配布・サーバーアップロードすることでユーザーがゲームをプレイできる</strong>ようになります。</p>



<h3 class="wp-block-heading">Unityでゲームをビルドする基本手順</h3>



<div class="wp-block-cocoon-blocks-tab-box-1 blank-box bb-tab bb-memo block-box has-border-color has-yellow-border-color">
<p class="wp-block-paragraph">本記事は、<strong>Unity6</strong>でのビルド方法を紹介しています。<br>バージョンが異なってもほとんど操作は同じです。</p>
</div>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1200" height="630" src="https://alicia-ing.com/wp-content/uploads/2025/11/Buildwindow.webp" alt="" class="wp-image-8800" srcset="https://alicia-ing.com/wp-content/uploads/2025/11/Buildwindow.webp 1200w, https://alicia-ing.com/wp-content/uploads/2025/11/Buildwindow-300x158.webp 300w, https://alicia-ing.com/wp-content/uploads/2025/11/Buildwindow-1024x538.webp 1024w, https://alicia-ing.com/wp-content/uploads/2025/11/Buildwindow-768x403.webp 768w" sizes="(max-width: 1200px) 100vw, 1200px" /></figure>



<p class="wp-block-paragraph">基本的なビルド手順は<strong>「シーンの設定 → プラットフォームの選択 → ビルドの実行」</strong>という流れになります。</p>



<div class="wp-block-cocoon-blocks-timeline timeline-box cf block-box has-point-color has-light-blue-point-color not-nested-style cocoon-block-timeline" style="--cocoon-custom-point-color:#2ca9e1"><div class="timeline-title">ビルド手順</div><ul class="timeline">
<li class="wp-block-cocoon-blocks-timeline-item timeline-item cf"><div class="timeline-item-label">Step1</div><div class="timeline-item-content cf"><div class="timeline-item-title">ゲームで使うシーンを追加</div><div class="timeline-item-snippet">
<p class="wp-block-paragraph"></p>
</div></div></li>



<li class="wp-block-cocoon-blocks-timeline-item timeline-item cf"><div class="timeline-item-label">Step2</div><div class="timeline-item-content cf"><div class="timeline-item-title">プラットフォーム（Windows,Mac,WebGLなど）を選ぶ</div><div class="timeline-item-snippet"></div></div></li>



<li class="wp-block-cocoon-blocks-timeline-item timeline-item cf"><div class="timeline-item-label">Step3</div><div class="timeline-item-content cf"><div class="timeline-item-title">ビルド</div><div class="timeline-item-snippet"></div></div></li>
</ul></div>



<p class="wp-block-paragraph"><a target="_self" href="https://docs.unity3d.com/ja/2018.4/Manual/PublishingBuilds.html">>>公式ページのビルド方法</a></p>



<h3 class="wp-block-heading">シーン登録</h3>



<p class="wp-block-paragraph">初めにビルドに含めるシーンを指定します。Unityメニューから <strong>File > Build Profiles </strong>を開き、Scenes Listに現在のシーンを追加します（「Open Scene List」>「Add Open Scenes」ボタン）。複数シーンがある場合、すべて追加しましょう。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1200" height="630" src="https://alicia-ing.com/wp-content/uploads/2025/11/BuildSetting.webp" alt="" class="wp-image-8799" srcset="https://alicia-ing.com/wp-content/uploads/2025/11/BuildSetting.webp 1200w, https://alicia-ing.com/wp-content/uploads/2025/11/BuildSetting-300x158.webp 300w, https://alicia-ing.com/wp-content/uploads/2025/11/BuildSetting-1024x538.webp 1024w, https://alicia-ing.com/wp-content/uploads/2025/11/BuildSetting-768x403.webp 768w" sizes="(max-width: 1200px) 100vw, 1200px" /></figure>



<p class="wp-block-paragraph">ボタンを押しても何も反応がない場合は、シーンが読み込めていません。<br>そこで、<strong>現在のシーンを変更してから「Add Open Scenes」ボタンを押す</strong>と認識できます。</p>



<p class="wp-block-paragraph"><strong>シーンリスト番号「0」が、ゲーム起動時に最初にロードされるシーン</strong>になります。一般的にタイトルやメインメニューのシーンを先頭に置きます。ドラッグ＆ドロップで順序を並び替え、一番最初に実行したいシーンがトップに来るよう設定します。</p>



<p class="wp-block-paragraph"><strong>チェックボックスでビルド対象に含めるか除外するかを制御</strong>できます。不要なシーンはチェックを外すことでビルドから除外可能ですが、基本的にはリストに追加したシーンはすべて有効にしておきます。Scene移動はスクリプトで制御しないと遷移できないですが、チェックボックスで除外しておく方が無難です。</p>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-info-circle"></span>実用的なシーン切り替えを紹介しています。</span></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together">

<a target="_self" href="https://alicia-ing.com/programming/unity/scene-change-fade/" title="【Unity】シーン切り替え演出｜フェイドイン・アウト" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://alicia-ing.com/wp-content/uploads/2024/10/scene-change-fade-160x90.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://alicia-ing.com/wp-content/uploads/2024/10/scene-change-fade-160x90.webp 160w, https://alicia-ing.com/wp-content/uploads/2024/10/scene-change-fade-120x68.webp 120w, https://alicia-ing.com/wp-content/uploads/2024/10/scene-change-fade-320x180.webp 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【Unity】シーン切り替え演出｜フェイドイン・アウト</div><div class="blogcard-snippet internal-blogcard-snippet">Unityのシーン切り替え演出の１つにフェイドイン・フェイドアウトがあります。シーン遷移は突然してしまうためフェイドを使い滑らかにすることでユーザビリティ―が向上します。本記事では、ボタンを押してフェイド演出を詳しく解説しています。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://alicia-ing.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">alicia-ing.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2025.04.29</div></div></div></div></a>
</div>



<h3 class="wp-block-heading">プラットフォームの選択</h3>



<p class="wp-block-paragraph"> ビルド設定ウィンドウを開きます（ショートカット: Ctrl+Shift+B）。ここでプロジェクトのビルド対象プラットフォームを設定できます。</p>



<p class="wp-block-paragraph"> 左側カラムのPlatformsからビルドしたいターゲットプラットフォームを選びます（ PC向けなら「Windows, MacOS, Linux」、Webブラウザ向けなら「WebGL」、スマホアプリなら「iOS、Android」など）。選択すると右下にビルド対象として表示され、現在のプラットフォームでない場合は「Switch Platform」ボタンが有効になります。</p>



<div class="wp-block-cocoon-blocks-tab-caption-box-1 tab-caption-box block-box has-border-color has-light-blue-border-color not-nested-style cocoon-block-tab-caption-box" style="--cocoon-custom-border-color:#2ca9e1"><div class="tab-caption-box-label block-box-label box-label fab-pencil"><span class="tab-caption-box-label-text block-box-label-text box-label-text">ビルドしたいプラットフォームを有効にする</span></div><div class="tab-caption-box-content block-box-content box-content">
<p class="wp-block-paragraph">希望するプラットフォームが一覧に表示されていない、<strong>「No module loaded」</strong>といった表示が出る場合は、そのプラットフォーム用モジュールが未インストールです。</p>



<p class="wp-block-paragraph"><strong>「Install with Unity Hub」</strong>で、Unity Hubを開き、該当Unityエディターのバージョンに対し「モジュールを追加」から必要なビルドサポート（例: WebGL、Android、iOS など）をインストールしてください。モジュール追加後、Unityエディタを再起動するとプラットフォームが選択可能になります。</p>
</div></div>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1200" height="630" src="https://alicia-ing.com/wp-content/uploads/2025/11/nomodule.webp" alt="" class="wp-image-8801" srcset="https://alicia-ing.com/wp-content/uploads/2025/11/nomodule.webp 1200w, https://alicia-ing.com/wp-content/uploads/2025/11/nomodule-300x158.webp 300w, https://alicia-ing.com/wp-content/uploads/2025/11/nomodule-1024x538.webp 1024w, https://alicia-ing.com/wp-content/uploads/2025/11/nomodule-768x403.webp 768w" sizes="(max-width: 1200px) 100vw, 1200px" /></figure>



<p class="wp-block-paragraph">ビルド対象を選んだら、<strong>Switch Platformボタンをクリックしてプラットフォームを切り替えます</strong>。プラットフォーム切り替え時には必要なライブラリのインポート処理が走るため、完了するまで待ちましょう。切り替え後、選択したプラットフォーム名の右に「(Active)」と表示されます。</p>



<h3 class="wp-block-heading">ビルドの実行</h3>



<p class="wp-block-paragraph">ビルド前に、必要に応じて右下のDevelopment Build（開発ビルド）やCompression Method（圧縮方式）などのオプションをチェックできます。開発ビルドにチェックを入れるとデバッグ情報付きでビルドされ、パフォーマンスは落ちますがデバッグに有用です。<strong>初学者の場合、基本はチェック不要で構いません。</strong></p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-1 sbs-stn sbp-l sbis-cb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://alicia-ing.com/wp-content/uploads/2023/05/alicia.webp" alt="著者の体験談" class="speech-icon-image"/></figure><div class="speech-name">著者の体験談</div></div><div class="speech-balloon">
<p class="wp-block-paragraph">項目が多すぎるので、基本そのままでOK</p>
</div></div>



<p class="wp-block-paragraph"> ビルドには、<strong>Build か Build and Run</strong>どちらかを押すと処理されます。「Build」ボタンを押すとビルド処理が始まります（完了後、出力先フォルダを開いて自分で実行ファイルを起動）。「Build and Run」を押すとビルド完了後に自動的にアプリケーション（またはエミュレータ）が起動し、実行結果をすぐ確認できます。<strong>開発中はBuild and Runが便利です。</strong></p>



<p class="wp-block-paragraph">ビルド中は<strong>Unityエディタ下部の進行バーに進捗メッセージが表示</strong>されます。スクリプトのコンパイルやシーンのデータ書き出しなど、多少時間がかかる場合がありますが完了まで待ちましょう。<strong>Consoleウィンドウにエラーが出た場合、ビルドは失敗</strong>しています。</p>



<p class="wp-block-paragraph"> ビルドが成功すると、指定したフォルダ内に出力物が生成されます。Windowsは実行ファイル（.exe 等）とDataフォルダ、WebGLの場合はBuildフォルダとindex.html、Androidの場合はAPKファイル等ができています。それらを実行・配置することで実際にゲームが動作するか確認できます。</p>



<h2 class="wp-block-heading">出品に向けた設定</h2>



<p class="wp-block-paragraph">いざ、ゲームをビルドしてもタイトルがそのままだったり、よくわからないファイルが同封されているなど問題だらけです。また、ゲーム作りはプロでも１年以上は費やして完成をさせます。しかし出品の際に、<strong>スクリプトなどを保護</strong>をしないと購入者に解析されてしまうことがあります。（逆コンパイル）</p>



<p class="wp-block-paragraph">このように、個人情報や作品の保護などより質の高いビルドについて解説をします。まずは、Edit >ProjectSettingを開きます（ビルド設定ウィンドウのPlayerSettingからでもOKです。）。</p>



<p class="wp-block-paragraph">Playerをいじれば基本的なゲーム設定は可能です。<strong>「Resolution and Presentation」</strong>は画面サイズや比率の設定は後述します。</p>



<h3 class="wp-block-heading">名前変更</h3>



<p class="wp-block-paragraph">ゲームの主要情報はここで変えることができます。ここは<strong>ユーザーが見えるところ</strong>なのでしっかりと変更することが重要です。</p>



<ul class="wp-block-list">
<li>Company Name：会社名（セーブデータ格納とかでフォルダー名になる）</li>



<li>Product Name：ゲーム名（ゲームファイルの名前になる）</li>



<li>Verson：バージョン（1.2.3という命名がおすすめ。【ゲーム性】.【機能追加】.【バグ修正】）</li>



<li>Default Icon：実行ファイルのアイコン。未設定ではUnityのロゴ</li>



<li>Default Cursor：マウスカーソルの見た目変更。</li>



<li>Default Hotspot：カーソルの位置、基本的にデフォルトでOK(x,y)=(0,0)</li>
</ul>



<p class="wp-block-paragraph"></p>



<h3 class="wp-block-heading">Splash Image（ゲーム開始時の企業ロゴ）</h3>



<p class="wp-block-paragraph">ゲームを開始するときに企業ロゴや注意事項などが出てくる作品がありますが、Unityでも再現ができます。基本初期のままで構いませんが、いくつか変更すると良いところがありますので私が良くする設定で紹介します。</p>



<ul class="wp-block-list">
<li>Splash Screen>Animation：Custom（ロゴのズームをしないように設定）</li>



<li>Logos>Show Unity Logo：なし（Unityのロゴを非表示。<strong>Unity6から無料版でもチェックを外せる</strong>ように！）</li>
</ul>



<p class="wp-block-paragraph">Splash StyleやBackground Colorなどはそれぞれのロゴに適したものを使うと良いでしょう。</p>



<h3 class="wp-block-heading">Other Settings</h3>



<p class="wp-block-paragraph">その他なのに最も項目が多くてめんどくさいので、変えないといけない箇所だけ紹介します。</p>



<ul class="wp-block-list">
<li>Configuration>Scripting Backend：<strong>IL2CPP</strong>（スクリプト等の保護。MONOだと逆コンパイルでデータが盗まれる）</li>
</ul>



<p class="wp-block-paragraph">その他にも、使っていないスクリプトを削除して軽くする機能もありますが、予期せぬバグになるので省略します。</p>



<h3 class="wp-block-heading">フォルダーの削除</h3>



<p class="wp-block-paragraph">ビルドを終えると、基本的に削除してはいけないファイルばかりですが、「BurstDebugInformation<strong>_DoNotShip</strong>」というフォルダーは削除しなければいけません。フォルダーの中身は、ビルド情報が載りますが、よく見ると自分のPC情報が記載されています。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Library: C:\Users<strong>\【username】</strong>\Desktop\UnityProject\Tile_RPG\Temp\BurstOutput\Data\Plugins\x86_64\lib_burst_generated<br>&#8211;platform=Windows<br>&#8211;backend=burst-llvm-18</p>
<cite>Tile_RPG_BurstDebugInformation_DoNotShip/lib_burst_generated.txt</cite></blockquote>



<h2 class="wp-block-heading">画面サイズと解像度の設定</h2>



<p class="wp-block-paragraph">PC向け（Standalone）ビルドでは、デフォルト設定のままだとゲーム起動時にディスプレイ全画面で表示されます。古いUnityでは起動時に解像度選択ダイアログが表示されることもありましたが、2020年以降のUnityでは初期挙動が自動でフルスクリーンとなる場合が多いです。</p>



<p class="wp-block-paragraph">必要に応じて、ビルドされたゲームの画面モードや解像度を指定しましょう。</p>



<p class="wp-block-paragraph">Unityエディタ上部メニューから Edit > Project Settingsを開き、左メニューから Player を選択します。その中の対象プラットフォームの<strong>Resolution and Presentation</strong> セクションを展開してください。ここで画面モードや初期解像度に関する設定を変更できます。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1200" height="630" src="https://alicia-ing.com/wp-content/uploads/2025/11/ScreenSize.webp" alt="" class="wp-image-8802" srcset="https://alicia-ing.com/wp-content/uploads/2025/11/ScreenSize.webp 1200w, https://alicia-ing.com/wp-content/uploads/2025/11/ScreenSize-300x158.webp 300w, https://alicia-ing.com/wp-content/uploads/2025/11/ScreenSize-1024x538.webp 1024w, https://alicia-ing.com/wp-content/uploads/2025/11/ScreenSize-768x403.webp 768w" sizes="(max-width: 1200px) 100vw, 1200px" /></figure>



<div class="wp-block-cocoon-blocks-tab-caption-box-1 tab-caption-box block-box has-border-color has-vivid-cyan-blue-border-color not-nested-style cocoon-block-tab-caption-box" style="--cocoon-custom-border-color:#0693e3"><div class="tab-caption-box-label block-box-label box-label fab-edit"><span class="tab-caption-box-label-text block-box-label-text box-label-text">不要なPlayer.txtが表示</span></div><div class="tab-caption-box-content block-box-content box-content">
<p class="wp-block-paragraph">AppDataフォルダーの中にPlayer.txtが生成されてしまいます。これはスクリプㇳのDebugなどを検知しますが、「Use Player Log」のチェックを外せば生成されることは無くなります。</p>
</div></div>



<p class="wp-block-paragraph"> Fullscreen Mode という設定項目があります。デフォルトでは「Fullscreen Window（全画面表示ウィンドウ）」もしくは「Exclusive Fullscreen（専用全画面）」になっています。これを <strong>「Windowed（ウィンドウ表示）」</strong> に変更すると、ビルド後のゲームがウィンドウモードで起動するようになります。フルスクリーンだと起動時にモニタ解像度で全面表示されますが、Windowedにすることでウィンドウ枠のある通常のウィンドウになります。</p>



<p class="wp-block-paragraph"> Default Screen Width（デフォルト幅）、Default Screen Height（デフォルト高さ）という項目で、ウィンドウモード時の初期画面サイズ（解像度）を指定できます。ただしこれらは Fullscreen Modeを「<strong>Windowed」にした場合のみ有効</strong>です。（フルスクリーン時はモニタ解像度に依存）。例えば幅1920×高さ1080にしたければ、それぞれ1920、1080と設定します。</p>



<p class="wp-block-paragraph">Resizable Window オプションを true にすると、ユーザーがウィンドウの端をドラッグして自由にリサイズできるようになります。固定サイズで遊ばせたい場合は false に設定し、ウィンドウサイズ変更を禁止します。<strong>リサイズを許可する場合、画面比率が変わってUI配置が崩れないようCanvasの設定</strong>（UIのScale ModeやReference Resolution）にも注意が必要なので、<strong>許可しないことをおすすめします。</strong></p>



<h3 class="wp-block-heading">著者が実際にしている画面サイズ設定</h3>



<p class="wp-block-paragraph">私の設定では、<strong>FullScreenとWindowedモードのハイブリット</strong>にしています。</p>



<ul class="wp-block-list">
<li>Fulscreen Mode：Windowed</li>



<li>Default Screen :幅1280×高さ720</li>
</ul>



<p class="wp-block-paragraph">このサイズにしておけば、<strong>ほとんどのユーザーのPCに納まる</strong>かと思います。</p>



<p class="wp-block-paragraph">また、以下のスクリプトをゲームのタイトル画面に設置してフルスクリーンとウィンドウどちらにも対応できるようにしています。</p>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>    // ウィンドウモードに戻すときのサイズ
    [SerializeField] private int windowWidth = 1280;
    [SerializeField] private int windowHeight = 720;

    // UIボタンから呼ぶ関数
    public void ToggleFullscreen()
    {
        if (Screen.fullScreen)
        {
            // フルスクリーン → ウィンドウモード
            Screen.SetResolution(windowWidth, windowHeight, FullScreenMode.Windowed);
            Debug.Log(&quot;Switched to Windowed Mode&quot;);
        }
        else
        {
            // ウィンドウモード → フルスクリーン
            Screen.SetResolution(Display.main.systemWidth, Display.main.systemHeight, FullScreenMode.FullScreenWindow);
            Debug.Log(&quot;Switched to Fullscreen Mode&quot;);
        }
    }</code></pre></div>



<h2 class="wp-block-heading">WebGLビルドの方法とポイント</h2>



<p class="wp-block-paragraph">WebGLプラットフォームを選択すると、UnityのゲームをWebブラウザ上で実行できる形でビルドできます。HTML5/WebGL対応ゲームのビルド手順と注意点を解説します。</p>



<p class="wp-block-paragraph">WebGLでビルドするには、まずUnityにWebGLビルドサポートモジュールがインストールされている必要があります。Unity Hubのインストール項目から現在使用中のUnityバージョンに対し<strong>「WebGL Build Support」を追加インストール</strong>してください（未導入の場合、Build SettingsでWebGLプラットフォームを選ぶ際に自動で「Install with Unity Hub」というボタンが表示されます）。</p>



<p class="wp-block-paragraph">Build Settings ウィンドウで Platform を「WebGL」に選択し、「Switch Platform」で切り替えます。切り替え後、「WebGL」がActiveプラットフォームになったことを確認してください。</p>



<p class="wp-block-paragraph"> WebGLビルド用のPlayer Settingsも確認しておきましょう。たとえば「Publishing Settings」内の Compression Format（圧縮形式）はデフォルトでは Brotli 圧縮が使われます。<strong>互換性のためGzip圧縮に変更するケース</strong>もあります（Unity公式のUnity Playや一部サーバーではBrotli未対応の場合があるため）。また Memory Size（デフォルト256MB）などWebGL固有の設定項目もありますが、必要に応じて調整します。初回は特に変更せずとも動作しますが、ビルドサイズや読み込み速度の最適化に関わる部分なので、公開時には検討するとよいでしょう。</p>



<p class="wp-block-paragraph"> Build and Run を使うと、ビルド完了後に<strong>自動でブラウザが起動しローカルホストでホスティングされたゲーム</strong>が開きます。Buildのみ実行した場合、出力されたフォルダ（デフォルトでは Build フォルダと Template データ）が生成され、その中のindex.htmlをブラウザで開いても直接は動作しません。WebGLビルドはセキュリティ上、ファイルシステムから直接読み込めないためです。必ずBuild and Runで確認するか、簡易なローカルHTTPサーバーを立ててホスティングしてください。</p>



<p class="wp-block-paragraph">WebGLのビルド結果として、index.html ファイルと Buildフォルダ（中に .jsonや.wasm、.dataファイルなどが入っています）が生成されます。これら一式をWebサーバー上に配置すれば、ユーザーはブラウザでindex.htmlにアクセスするだけでゲームをプレイできます。UnityRoom（日本国内向けのUnityゲーム投稿サイト）や itch.io, GitHub Pages などにアップロードするのも簡単です。Unity公式の Unity Play や Game Server Hosting なども選択肢になります。</p>



<div class="wp-block-cocoon-blocks-tab-box-1 blank-box bb-tab bb-check block-box has-border-color has-yellow-border-color">
<p class="wp-block-paragraph"><strong>WebGLビルドでは、使用できる機能にいくつか制限</strong>があります。例えばマルチスレッドやファイルシステムへのアクセス、一部プラグインは動作しません。またメモリ使用量にも注意が必要で、大きすぎるアセットはロードに時間がかかったりブラウザでメモリ不足になる場合があります。<strong>動作が重い場合はQuality設定を下げる、圧縮形式を見直す、不要なAssetを削減する</strong>等で最適化しましょう。基本的にはUnityエディタ上で問題なく動いていても、ブラウザの開発者コンソールでエラーが出ていないかを確認しつつテストを重ねることが大切です。</p>
</div>



<h2 class="wp-block-heading">ビルドできない時のトラブルシューティング</h2>



<p class="wp-block-paragraph">ビルド実行中にエラーが発生し「Build failed」となってしまうことがあります。ここでは、「Unityでビルドができない！」となった場合によくある原因と解決策を紹介します。最終的には<strong>エラー文をChatGPTや検索してみるとQiitaやNoteに公開しているユーザーが多いので、これらで解決</strong>しましょう。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1200" height="630" src="https://alicia-ing.com/wp-content/uploads/2025/11/errorcode.webp" alt="" class="wp-image-8803" srcset="https://alicia-ing.com/wp-content/uploads/2025/11/errorcode.webp 1200w, https://alicia-ing.com/wp-content/uploads/2025/11/errorcode-300x158.webp 300w, https://alicia-ing.com/wp-content/uploads/2025/11/errorcode-1024x538.webp 1024w, https://alicia-ing.com/wp-content/uploads/2025/11/errorcode-768x403.webp 768w" sizes="(max-width: 1200px) 100vw, 1200px" /></figure>



<p class="wp-block-paragraph"> 最初にチェックすべきは、<strong>スクリプトのコンパイルエラー</strong>です。Unityではスクリプトにエラーがある状態だとビルドは実行できません。<strong>エディタ下部のConsoleウィンドウに赤いエラーメッセージ</strong>が出ていないか確認し、出ている場合は内容に従ってコードを修正してください。典型的には文法ミス（セミコロンの付け忘れ等）や参照切れ、型の不一致などが原因です。コンパイルエラーはビルド以前にエディタ実行中から検知できますので、まずここをゼロにしましょう。</p>



<p class="wp-block-paragraph">または、<strong>ビルド対象プラットフォームのモジュールが入っていない場合、ビルド自体が開始できませ</strong>ん（ビルド設定でビルドボタンが押せない状態になる）。例えば「WebGL Module」や「Android Build Support」などがUnityに追加されているかを確認し、入っていなければUnity Hubからインストールします。モジュール不足が原因の場合、エラーメッセージで指摘されることもあります。「Module not loaded」「SDK not found」等のログが出たら該当モジュール/SDKの導入を行ってください。</p>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">Unityにおけるビルド手順と設定、そしてトラブル発生時の対処法について網羅的に解説しました。</p>



<p class="wp-block-paragraph">開発途中でもこまめにビルドを行う習慣を付けましょう。Unityエディタ上では正常に動いていても、ビルドすると初めて表面化する不具合は少なくありません。大きな機能追加や変更をした際はその都度ビルドして、予期せぬエラーが出ないか確認することで、後になってエラーの山に悩まされるリスクを減らせます。</p>



<p class="wp-block-paragraph"> バージョン管理とバックアップ: ビルド前後で問題が発生した際に備え、Git等のバージョン管理システムでプロジェクトの変更履歴を残しておくことをお勧めします。特にビルド直前に入れた変更が原因でエラーになった場合、直前のコミットに戻すことで原因の切り分けが容易になります。</p>



<p class="wp-block-paragraph">ビルドエラーに直面した場合、公式マニュアルのトラブルシューティングやUnityフォーラム、Qiita記事などコミュニティの情報も積極的に参考にしましょう。特にエラーメッセージで検索すると同様のケースに遭遇した開発者の知見が見つかることが多いです。英語で検索するとフォーラムの回答がヒットする場合もあります。</p>



<p class="wp-block-paragraph">ビルドが無事完了したら、実際に他のPCやデバイスで動作確認をします。画面サイズ設定や挙動が開発機と異ならないか、想定通りフルスクリーン/ウィンドウ表示になるか、WebGLなら複数のブラウザで正常動作するか、といった点をチェックしましょう。問題があれば再度Unity側の設定を調整しビルドし直します。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://alicia-ing.com/programming/build-setting/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Unity】時間計測の方法｜ミリ秒・分秒タイマーを実装</title>
		<link>https://alicia-ing.com/programming/unity/game-time-measurement/</link>
					<comments>https://alicia-ing.com/programming/unity/game-time-measurement/#respond</comments>
		
		<dc:creator><![CDATA[アリッシア]]></dc:creator>
		<pubDate>Sun, 04 May 2025 22:00:00 +0000</pubDate>
				<category><![CDATA[Unity]]></category>
		<guid isPermaLink="false">https://alicia-ing.com/?p=8521</guid>

					<description><![CDATA[Unityでゲームを作成する際、時間管理やタイマーの導入はゲームの面白さを左右する重要な要素です。特にアクションゲームやパズルゲームなどでは、時間制限を設けたり、経過時間を計測したりすることでゲームプレイに緊張感や達成感 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-cocoon-blocks-label-box-1 label-box block-box not-nested-style cocoon-block-label-box"><div class="label-box-label block-box-label box-label fab-flag"><span class="label-box-label-text block-box-label-text box-label-text">本記事を読むと以下の実行ができます</span></div><div class="label-box-content block-box-content box-content">
<p class="wp-block-paragraph">時間計測を行い、ゲーム終了後にタイマーを停止してシーン切り替えて結果を表示</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="960" height="540" src="https://alicia-ing.com/wp-content/uploads/2025/05/complete.webp" alt="" class="wp-image-9055" srcset="https://alicia-ing.com/wp-content/uploads/2025/05/complete.webp 960w, https://alicia-ing.com/wp-content/uploads/2025/05/complete-300x169.webp 300w, https://alicia-ing.com/wp-content/uploads/2025/05/complete-768x432.webp 768w, https://alicia-ing.com/wp-content/uploads/2025/05/complete-240x135.webp 240w, https://alicia-ing.com/wp-content/uploads/2025/05/complete-320x180.webp 320w, https://alicia-ing.com/wp-content/uploads/2025/05/complete-640x360.webp 640w" sizes="(max-width: 960px) 100vw, 960px" /></figure>
</div></div>



<p class="wp-block-paragraph">Unityでゲームを作成する際、時間管理やタイマーの導入はゲームの面白さを左右する重要な要素です。特にアクションゲームやパズルゲームなどでは、時間制限を設けたり、経過時間を計測したりすることでゲームプレイに緊張感や達成感を与えられます。</p>



<p class="wp-block-paragraph">本記事では、unityで時間管理するメソッドを紹介して、時間計測やタイマーをゲーム内に導入します。</p>



<div class="wp-block-cocoon-blocks-label-box-1 label-box block-box cocoon-block-label-box"><div class="label-box-label block-box-label box-label fab-check"><span class="label-box-label-text block-box-label-text box-label-text">本記事は次の人におすすめ</span></div><div class="label-box-content block-box-content box-content">
<ul class="wp-block-list">
<li>Unityで制限時間付きのゲームを作りたい方</li>



<li>ゲーム内で経過時間を表示したい方</li>



<li>ゲームオーバー処理を時間で制御したい方</li>



<li>ミリ秒単位の高精度タイマーが必要な方</li>



<li>時間経過で自動的にシーンを切り替えたい方</li>
</ul>
</div></div>



<h2 class="wp-block-heading">Unityで時間計測とタイマー</h2>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1376" height="768" src="https://alicia-ing.com/wp-content/uploads/2025/05/time-measurement.webp" alt="時計やストップウォッチなど時間を測る道具を並べた図
" class="wp-image-9056" srcset="https://alicia-ing.com/wp-content/uploads/2025/05/time-measurement.webp 1376w, https://alicia-ing.com/wp-content/uploads/2025/05/time-measurement-300x167.webp 300w, https://alicia-ing.com/wp-content/uploads/2025/05/time-measurement-767x428.webp 767w, https://alicia-ing.com/wp-content/uploads/2025/05/time-measurement-1024x572.webp 1024w, https://alicia-ing.com/wp-content/uploads/2025/05/time-measurement-240x135.webp 240w, https://alicia-ing.com/wp-content/uploads/2025/05/time-measurement-320x180.webp 320w" sizes="(max-width: 1376px) 100vw, 1376px" /></figure>



<p class="wp-block-paragraph">Unityでのゲーム開発において、時間計測やタイマー機能は非常に重要な位置を占めます。</p>



<p class="wp-block-paragraph"><strong>ゲーム内で時間制限を明確に設定</strong>することにより、プレイヤーに対して緊張感や達成感を生み出し、ゲームのテンポを一定に保つことができるためです。</p>



<p class="wp-block-paragraph">例えば、クイズゲームでは制限時間を設けることで迅速な判断を促し、制限時間内に答えられなければ不正解とする。カードゲームではプレイヤーが一定時間内に行動をしなければ自動的にターンが次のプレイヤーへと移る仕組みを作ることで、円滑な進行を促します。</p>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-info-circle"></span>Unityで４択クイズの作り方を紹介しています。</span></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together">

<a target="_self" href="https://alicia-ing.com/programming/unity/4choice-csharp/" title="【Unity】４択クイズゲームの作り方-アセットなしで作成する" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://alicia-ing.com/wp-content/uploads/2023/12/4-choice-160x90.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://alicia-ing.com/wp-content/uploads/2023/12/4-choice-160x90.webp 160w, https://alicia-ing.com/wp-content/uploads/2023/12/4-choice-120x68.webp 120w, https://alicia-ing.com/wp-content/uploads/2023/12/4-choice-320x180.webp 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【Unity】４択クイズゲームの作り方-アセットなしで作成する</div><div class="blogcard-snippet internal-blogcard-snippet">Unityで4択クイズを作成します。ゲーム内では、アニメーションやランダム、BGMを導入して質の高い作品を作ることができます。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://alicia-ing.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">alicia-ing.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2024.10.24</div></div></div></div></a>
</div>



<p class="wp-block-paragraph">さらに、RPGゲームではクリアタイムを競うタイムアタック要素を設けることで、プレイヤーのモチベーションを維持したり、競争心を高めたりできます。また、時間制限がプレイヤーに明確に示されることで、プレイヤーがより戦略的にゲームを進めたり、瞬時の判断力が求められたりするため、ゲームへの没入感や興奮度を高めることにも繋がります。</p>



<p class="wp-block-paragraph">こうした様々な側面から、<strong>時間管理はゲーム制作において不可欠な要素</strong>となっています。</p>



<p class="wp-block-paragraph">以下で、Unityの時間計測やタイマー機能を実装するために必要な具体的メソッドを詳しく見ていきます。</p>



<h3 class="wp-block-heading">Time.time</h3>



<p class="wp-block-paragraph"><a target="_self" href="https://docs.unity3d.com/ja/current/ScriptReference/Time-time.html">Time.time</a>は<strong>Unityにおける基本的な時間計測のプロパティ</strong>で、ゲームの開始時から現在までの経過時間を秒単位で取得できます。</p>



<p class="wp-block-paragraph">初心者でも簡単に利用でき、主にシンプルな経過時間表示や簡単なタイマー機能の実装に使えます。</p>



<p class="wp-block-paragraph">実際のコードでは次のように書きます。</p>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>void Update()
{
    float elapsedTime = Time.time;
    Debug.Log(&quot;経過時間: &quot; + elapsedTime + &quot;秒&quot;);
}</code></pre></div>



<p class="wp-block-paragraph">毎フレームごとに経過時間をログに表示しています。素早く実装可能です。</p>



<p class="wp-block-paragraph">ただし、この方法はあくまでも基本的な時間計測に向いており、細かい制御には不向きな場合があります。</p>



<h3 class="wp-block-heading">Time.deltaTime</h3>



<p class="wp-block-paragraph"><a target="_self" href="https://docs.unity3d.com/ja/current/ScriptReference/Time-deltaTime.html">Time.deltaTime</a>は前フレームからの経過時間を取得する方法であり、特に動きのあるゲームや毎フレーム更新されるタイマーの実装に適しています。</p>



<p class="wp-block-paragraph">実際のコードでは次のように書きます。</p>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>private float timer = 0f;
void Update()
{
    timer += Time.deltaTime;
    Debug.Log(&quot;累計時間: &quot; + timer + &quot;秒&quot;);
}</code></pre></div>



<p class="wp-block-paragraph">このコードはフレームレートに依存しないため、異なる端末や環境でも均一な動きを提供できます。移動速度の制御やアニメーションの時間管理にも非常に有効です。</p>



<h4 class="wp-block-heading">Time.timeとTime.deltaTimeの違いは？</h4>



<p class="wp-block-paragraph">コード例を見ると、両者に違いがなく<strong>Time.timeの方が短く記述でき</strong>るので、Time.deltaTimeの意味がなさそうに見えるでしょう。</p>



<p class="wp-block-paragraph">Time.timeは<strong>ゲーム開始からずっと加算される絶対時間ベースの処理</strong>です。タイマー、経過時間判定などに使えますが、リセットをすることができないので色々と不便です。</p>



<p class="wp-block-paragraph">一方Time.deltaTimeは、前のフレームから今まで何秒経ったか。<strong>移動・回転・アニメーションなどをフレーム依存なしで進める</strong>ことが可能です。</p>



<p class="wp-block-paragraph">なお、Time.timeScaleを0にしてゲームを一時停止すると、Time.timeもTime.deltaTimeも止まります。一時停止中も時間を進めたいときは、Time.unscaledTimeやTime.unscaledDeltaTimeを使います。</p>



<h3 class="wp-block-heading">Stopwatch</h3>



<p class="wp-block-paragraph"><a target="_self" href="https://learn.microsoft.com/ja-jp/dotnet/api/system.diagnostics.stopwatch">Stopwatch</a>はUnityで高精度の時間計測（ミリ秒単位）が可能なクラスです。これは主にベンチマークテストや処理の最適化を目的とした精密な処理時間の測定に使われます。</p>



<p class="wp-block-paragraph">実際のコードでは次のように書きます。</p>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>using UnityEngine;
using System.Diagnostics;
using Debug = UnityEngine.Debug;

Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
// 計測したい処理
stopwatch.Stop();
Debug.Log(&quot;処理時間: &quot; + stopwatch.ElapsedMilliseconds + &quot; ms&quot;);</code></pre></div>



<p class="wp-block-paragraph">特定処理にかかる正確な時間をミリ秒単位で取得でき、パフォーマンス改善に役立ちます。特徴として、名前空間で「System.Diagnostics」が必要です。ただしUnityEngineにもDebugがあるため、そのままだとどちらのDebugか決まらずエラーになります。「using Debug = UnityEngine.Debug;」を足して、Unity側のDebugを使うと指定します。</p>



<h4 class="wp-block-heading">ミリ秒のタイマー</h4>



<p class="wp-block-paragraph">Unityでミリ秒単位の高精度タイマーを導入する場合、Stopwatchが最も推奨されます。<br>特にリアルタイム性を求めるゲームや、処理精度を要求されるシミュレーションなどで有効です。</p>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>Stopwatch timer = new Stopwatch();
timer.Start();
// 時間を測る処理
timer.Stop();
long milliseconds = timer.ElapsedMilliseconds;
Debug.Log(&quot;経過時間: &quot; + milliseconds + &quot; ms&quot;);</code></pre></div>



<p class="wp-block-paragraph">Stopwatchは現実の時間で動くので、Time.timeScaleを0にして一時停止しても止まりません。ゲームの時間に合わせたいときは、Time.deltaTimeを加算するタイマーを使います。</p>



<h3 class="wp-block-heading">番外編：Coroutine + WaitForSeconds</h3>



<p class="wp-block-paragraph">一定時間後に処理を行う際に役立つのが、Coroutineと<a target="_self" href="https://docs.unity3d.com/ja/current/ScriptReference/WaitForSeconds.html">WaitForSeconds</a>です。これは遅延処理やクールタイムの実装で頻繁に利用されます。したがって、<strong>時間計測には向かない</strong>です。例えば、クイズゲームで解答表示3秒後に次の問題を出題するというときに使います。</p>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-info-circle"></span>コールチンについて解説しています。</span></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together">

<a target="_self" href="https://alicia-ing.com/programming/unity/coroutine/" title="【Unity】coroutine（コルーチン）で停止や再開を解説" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://alicia-ing.com/wp-content/uploads/2023/01/coroutine-160x90.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://alicia-ing.com/wp-content/uploads/2023/01/coroutine-160x90.webp 160w, https://alicia-ing.com/wp-content/uploads/2023/01/coroutine-120x68.webp 120w, https://alicia-ing.com/wp-content/uploads/2023/01/coroutine-320x180.webp 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【Unity】coroutine（コルーチン）で停止や再開を解説</div><div class="blogcard-snippet internal-blogcard-snippet">Unityのコルーチン（Coroutine）の使い方を解説。yield returnでの待機、WaitUntilでの条件待ち、StopCoroutineでの停止と再開に加え、Invokeやasync/awaitとの違いも紹介します。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://alicia-ing.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">alicia-ing.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2026.10.19</div></div></div></div></a>
</div>



<p class="wp-block-paragraph">例として、3秒後に特定の処理を行うコードは以下です。</p>



<p class="wp-block-paragraph">実際のコードでは次のように書きます。</p>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>IEnumerator DelayedAction()
{
    yield return new WaitForSeconds(3f);
    Debug.Log(&quot;3秒経過しました。&quot;);
}

void Start()
{
    StartCoroutine(DelayedAction());
}</code></pre></div>



<p class="wp-block-paragraph">このように、指定した時間経過後に処理を自動的に実行できるため、<strong>イベント制御やゲームロジックの調整</strong>に非常に便利です。</p>



<p class="wp-block-paragraph">1秒待つときは、WaitForSeconds(1f)にします。WaitForSecondsはTime.timeScaleの影響を受けるので、一時停止中も待ちたいときは<a target="_self" href="https://docs.unity3d.com/ja/current/ScriptReference/WaitForSecondsRealtime.html">WaitForSecondsRealtime</a>を使います。</p>



<p class="wp-block-paragraph">Unity 6では、Coroutineを使わずに「await Awaitable.WaitForSecondsAsync(1f);」と書いて待つこともできます（<a target="_self" href="https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Awaitable.WaitForSecondsAsync.html">公式ドキュメント</a>）。</p>



<h2 class="wp-block-heading">ゲームクリア後、シーン遷移して時間計測結果を表示する</h2>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1376" height="768" src="https://alicia-ing.com/wp-content/uploads/2025/05/clear-time-result.webp" alt="ゴールしてタイマーが止まり、結果の画面に切り替わる流れを表した図" class="wp-image-9058" srcset="https://alicia-ing.com/wp-content/uploads/2025/05/clear-time-result.webp 1376w, https://alicia-ing.com/wp-content/uploads/2025/05/clear-time-result-300x167.webp 300w, https://alicia-ing.com/wp-content/uploads/2025/05/clear-time-result-767x428.webp 767w, https://alicia-ing.com/wp-content/uploads/2025/05/clear-time-result-1024x572.webp 1024w, https://alicia-ing.com/wp-content/uploads/2025/05/clear-time-result-240x135.webp 240w, https://alicia-ing.com/wp-content/uploads/2025/05/clear-time-result-320x180.webp 320w" sizes="(max-width: 1376px) 100vw, 1376px" /></figure>



<p class="wp-block-paragraph">これまでの方法を踏まえて、<strong>実際のゲームでクリアタイムを分秒表示</strong>し、クリア後は<strong>タイマーを停止</strong>、<strong>シーンを移動して結果を表示する</strong>機能を作ります。</p>



<p class="wp-block-paragraph">シーン移動やドラッグ＆ドロップは別記事で紹介していますので、本記事ではタイマーのみ解説をします。</p>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-info-circle"></span>ドラッグ＆ドロップについて解説しています。</span></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together">

<a target="_self" href="https://alicia-ing.com/programming/unity/drag-and-drop-object/" title="【Unity】ドラックアンドドロップでゲームオブジェクトを動かす" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://alicia-ing.com/wp-content/uploads/2024/02/drag-and-drop-object-160x90.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://alicia-ing.com/wp-content/uploads/2024/02/drag-and-drop-object-160x90.webp 160w, https://alicia-ing.com/wp-content/uploads/2024/02/drag-and-drop-object-120x68.webp 120w, https://alicia-ing.com/wp-content/uploads/2024/02/drag-and-drop-object-320x180.webp 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【Unity】ドラックアンドドロップでゲームオブジェクトを動かす</div><div class="blogcard-snippet internal-blogcard-snippet">ゲームオブジェクトをドラッグアンドドロップするには、Camera.main.ScreenToWorldPoint()か、イベントシステムでIPointerDownHandler, IDragHandler, IPointerUpHandlerを使います。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://alicia-ing.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">alicia-ing.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2025.05.03</div></div></div></div></a>
</div>



<p class="wp-block-paragraph">実装には<strong>Time.deltaTimeを使った簡易タイマー</strong>を使います。それぞれのオブジェクトにドラッグ＆ドロップ機能をつけて、クリア時にタイマー停止後シーンを遷移し、結果表示します。</p>



<h3 class="wp-block-heading">ソースコード1</h3>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>using UnityEngine;
using TMPro;

public class Timer : MonoBehaviour
{
    [SerializeField] private TMP_Text timerText; // ゲーム中のタイマー表示用
    private float elapsedTime = 0f;
    private bool isRunning = true;

    // クリア時の最終時間を保持する static 変数
    public static float finalTime = 0f;

    void Update()
    {
        if (isRunning)
        {
            elapsedTime += Time.deltaTime;
            int minutes = Mathf.FloorToInt(elapsedTime / 60f);
            int seconds = Mathf.FloorToInt(elapsedTime % 60f);
            timerText.text = string.Format(&quot;{0:00}:{1:00}&quot;, minutes, seconds);
        }
    }

    // タイマー停止時に最終時間を保存する
    public void StopTimer()
    {
        isRunning = false;
        finalTime = elapsedTime;
    }
}
</code></pre></div>



<h3 class="wp-block-heading">解説</h3>



<ul class="wp-block-list">
<li><strong>名前空間</strong></li>
</ul>



<p class="wp-block-paragraph">「UnityEngine」：Unityの基本機能を利用するために必要。GameObjectやMonoBehaviourクラス、Timeクラスなどが含まれる。<br>「<a target="_self" href="https://docs.unity3d.com/Packages/com.unity.ugui@2.0/api/TMPro.html">TMPro</a>」：TextMeshProコンポーネントを使用し、高品質なテキスト表示を実現するために必要。</p>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-info-circle"></span>TextMeshProの導入と日本語取り扱いの解説をしています。</span></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together">

<a target="_self" href="https://alicia-ing.com/programming/unity/textmeshpro/" title="【Unity】TextMeshPro-日本語表示とスクリプト制御" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://alicia-ing.com/wp-content/uploads/2024/01/textmeshpro-160x90.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://alicia-ing.com/wp-content/uploads/2024/01/textmeshpro-160x90.webp 160w, https://alicia-ing.com/wp-content/uploads/2024/01/textmeshpro-120x68.webp 120w, https://alicia-ing.com/wp-content/uploads/2024/01/textmeshpro-320x180.webp 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【Unity】TextMeshPro-日本語表示とスクリプト制御</div><div class="blogcard-snippet internal-blogcard-snippet">UnityのTextMeshProは日本語のテキストを美しく表示し、スクリプトでテキストを動的に変更することも可能です。改行は&quot;\n&quot;でします。&quot;japanese_full.txt&quot;ファイルを読み込んでTextMeshProに適用します。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://alicia-ing.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">alicia-ing.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2025.08.11</div></div></div></div></a>
</div>



<ul class="wp-block-list">
<li><strong>フィールド（メンバ変数）</strong></li>
</ul>



<p class="wp-block-paragraph">「timerText」：ゲーム画面に経過時間を表示するTextMeshProコンポーネントへの参照。<br>「elapsedTime」：ゲーム開始から経過した時間（秒）を保持するための変数。<br>「isRunning」：タイマーが現在動作中かどうかを示すフラグ（trueで動作中、falseで停止）。<br>「finalTime」：ゲームクリア時に計測した最終時間を保持するstatic変数。他のクラスからも参照可能。</p>



<ul class="wp-block-list">
<li><strong>Updateメソッド</strong></li>
</ul>



<p class="wp-block-paragraph">タイマーが動作中（isRunningがtrue）の場合、経過時間（elapsedTime）に前フレームからの経過時間（Time.deltaTime）を加算する。経過時間を分と秒に分解し、テキスト形式（MM:SS）でtimerTextに表示する処理を行う。</p>



<ul class="wp-block-list">
<li><strong>StopTimerメソッド</strong></li>
</ul>



<p class="wp-block-paragraph">タイマーを停止する際に呼ばれ、isRunningフラグをfalseに設定して計測を停止させる。同時に、計測された経過時間をfinalTimeに格納し、クリア時の最終時間として保持する。</p>



<h2 class="wp-block-heading">実演</h2>



<p class="wp-block-paragraph">タイマースクリプトはゲームマネージャーなど共通管理用オブジェクトにアタッチします。</p>



<p class="wp-block-paragraph">ゲームを再生すると、冒頭で紹介したような挙動が可能になります。</p>



<p class="wp-block-paragraph">経過時間を画面上に表示（TMP_Textコンポーネント）ゴールした時点でTimerクラスのStopTimerメソッドを呼び、タイマーを止めます。</p>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">本記事ではUnityの時間管理やタイマー機能を詳しく解説しました。</p>



<p class="wp-block-paragraph">Time.time、Time.deltaTimeの基本的な使い方から、Stopwatchを利用した高精度タイマー、Coroutineを利用した時間制御の方法まで、幅広くカバーしました。</p>



<p class="wp-block-paragraph">これらの技術を活用し、より質の高い、魅力的なゲームを作りましょう。</p>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://alicia-ing.com/programming/unity/game-time-measurement/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Unity】TextMeshProでテキストを1文字ずつ表示する</title>
		<link>https://alicia-ing.com/programming/unity/display-one-character-at-a-time/</link>
					<comments>https://alicia-ing.com/programming/unity/display-one-character-at-a-time/#respond</comments>
		
		<dc:creator><![CDATA[アリッシア]]></dc:creator>
		<pubDate>Sun, 09 Mar 2025 22:00:00 +0000</pubDate>
				<category><![CDATA[Unity]]></category>
		<guid isPermaLink="false">https://alicia-ing.com/?p=8458</guid>

					<description><![CDATA[Unityでノベルゲームのような会話シーンを制作するとき、「文字を1文字ずつ表示したい！」ことがあると思います。 突然テキストが表示されるのではなく、まるでキャラクターが実際に話しているかのような演出があれば、プレイヤー [&#8230;]]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-cocoon-blocks-label-box-1 label-box block-box not-nested-style cocoon-block-label-box"><div class="label-box-label block-box-label box-label fab-flag"><span class="label-box-label-text block-box-label-text box-label-text">本記事を読むと以下の実行ができます</span></div><div class="label-box-content block-box-content box-content">
<p class="wp-block-paragraph">TextMeshProでテキストを一文字ずつ、文字送りする。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1920" height="940" src="https://alicia-ing.com/wp-content/uploads/2025/03/complete.gif" alt="" class="wp-image-8465"/></figure>
</div></div>



<p class="wp-block-paragraph">Unityで<strong>ノベルゲームのような会話シーンを制作</strong>するとき、「文字を1文字ずつ表示したい！」ことがあると思います。<br><br>突然テキストが表示されるのではなく、<strong>まるでキャラクターが実際に話しているかのような演出</strong>があれば、プレイヤーの没入感も大きくアップさせることができます。</p>



<p class="wp-block-paragraph">しかし、「実際にどうやって実装するの？」や「初心者でも簡単にできる方法はないの？」と悩んでいる方も多いでしょう。</p>



<p class="wp-block-paragraph">本記事では、UnityのTextMeshPro（TMP）を使って<strong>1文字ずつ表示する方法</strong>を分かりやすく解説します。</p>



<p class="wp-block-paragraph">具体的な実装例や注意点も挙げながら、初心者の方でも迷わず実践できる内容にしています。</p>



<div class="wp-block-cocoon-blocks-label-box-1 label-box block-box cocoon-block-label-box"><div class="label-box-label block-box-label box-label fab-check"><span class="label-box-label-text block-box-label-text box-label-text">本記事は次の人におすすめ</span></div><div class="label-box-content block-box-content box-content">
<ul class="wp-block-list">
<li>文字を1文字ずつ流れるように表示する基本的な方法</li>



<li>コルーチンを使った効率的で簡単な実装方法</li>



<li>応用として、途中で一気に全文を表示する方法</li>



<li>注意すべきポイントやトラブルシューティング</li>
</ul>
</div></div>



<h2 class="wp-block-heading">文字送り表示</h2>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1200" height="630" src="https://alicia-ing.com/wp-content/uploads/2025/03/character-spacing.webp" alt="" class="wp-image-8466" srcset="https://alicia-ing.com/wp-content/uploads/2025/03/character-spacing.webp 1200w, https://alicia-ing.com/wp-content/uploads/2025/03/character-spacing-300x158.webp 300w, https://alicia-ing.com/wp-content/uploads/2025/03/character-spacing-1024x538.webp 1024w, https://alicia-ing.com/wp-content/uploads/2025/03/character-spacing-768x403.webp 768w" sizes="(max-width: 1200px) 100vw, 1200px" /></figure>



<p class="wp-block-paragraph">文字送りとは、テキストが一瞬で表示されるのではなく、1文字ずつ流れるように表示されるアニメーションのことを指します。</p>



<p class="wp-block-paragraph">これはノベルゲームやアドベンチャーゲームなど、<strong>キャラクター同士が会話をするシーン</strong>でよく用いられています。</p>



<p class="wp-block-paragraph">1文字ずつ表示されることによって、キャラクターが実際に言葉を話しているかのような臨場感を出すことができます。</p>



<p class="wp-block-paragraph">プレイヤーの没入感を高める重要な要素なので、ゲームのクオリティを上げたいならぜひマスターしましょう。</p>



<p class="wp-block-paragraph">また、RPGやチュートリアル表示など、幅広いジャンルのゲームにも応用可能です。</p>



<h3 class="wp-block-heading">コルーチンで実装</h3>



<p class="wp-block-paragraph">Unityで1文字ずつの表示を効率的かつ簡単に実現するためには、<br>「<strong>コルーチン（Coroutine）</strong>」を使用します。</p>



<p class="wp-block-paragraph">コルーチンとは、特定の処理を途中で待機（一定時間停止）させたり、<br>少しずつ処理を実行したりできるUnity特有の便利な機能です。</p>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-info-circle"></span>コールチンで停止・再開を解説しています。</span></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together">

<a target="_self" href="https://alicia-ing.com/programming/unity/coroutine/" title="【Unity】coroutine（コルーチン）で停止や再開を解説" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://alicia-ing.com/wp-content/uploads/2023/01/coroutine-160x90.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://alicia-ing.com/wp-content/uploads/2023/01/coroutine-160x90.webp 160w, https://alicia-ing.com/wp-content/uploads/2023/01/coroutine-120x68.webp 120w, https://alicia-ing.com/wp-content/uploads/2023/01/coroutine-320x180.webp 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【Unity】coroutine（コルーチン）で停止や再開を解説</div><div class="blogcard-snippet internal-blogcard-snippet">Unityのコルーチン（Coroutine）の使い方を解説。yield returnでの待機、WaitUntilでの条件待ち、StopCoroutineでの停止と再開に加え、Invokeやasync/awaitとの違いも紹介します。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://alicia-ing.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">alicia-ing.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2026.10.19</div></div></div></div></a>
</div>



<p class="wp-block-paragraph">似た機能にInvokeというものがありますが、Invokeは指定した関数を一度または定期的に呼び出すシンプルな仕組みであるのに対し、コルーチンは細かな処理の制御に適しています。</p>



<p class="wp-block-paragraph">本記事のような単純に文字送りをするだけならInvokeでも良いですが、<br>文字送りの速度を微調整したり、特定の文字だけ遅らせたりする場合は、コルーチンをおすすめします。</p>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-info-circle"></span>Invokeの使い方を紹介しています。</span></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together">

<a target="_self" href="https://alicia-ing.com/programming/unity/invoke/" title="【Unity】Invokeで引数を渡す、途中で停止・中断。" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://alicia-ing.com/wp-content/uploads/2023/02/invoke-160x90.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://alicia-ing.com/wp-content/uploads/2023/02/invoke-160x90.webp 160w, https://alicia-ing.com/wp-content/uploads/2023/02/invoke-120x68.webp 120w, https://alicia-ing.com/wp-content/uploads/2023/02/invoke-320x180.webp 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【Unity】Invokeで引数を渡す、途中で停止・中断。</div><div class="blogcard-snippet internal-blogcard-snippet">UnityのInvokeを使って引数を渡す方法や、処理を途中で停止するテクニックを解説。また、コールチンとの違いを紹介。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://alicia-ing.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">alicia-ing.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2025.05.18</div></div></div></div></a>
</div>



<h2 class="wp-block-heading">コルーチンを使った1文字ずつ表示する</h2>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1200" height="630" src="https://alicia-ing.com/wp-content/uploads/2025/03/character-a-time.webp" alt="" class="wp-image-8467" srcset="https://alicia-ing.com/wp-content/uploads/2025/03/character-a-time.webp 1200w, https://alicia-ing.com/wp-content/uploads/2025/03/character-a-time-300x158.webp 300w, https://alicia-ing.com/wp-content/uploads/2025/03/character-a-time-1024x538.webp 1024w, https://alicia-ing.com/wp-content/uploads/2025/03/character-a-time-768x403.webp 768w" sizes="(max-width: 1200px) 100vw, 1200px" /></figure>



<p class="wp-block-paragraph">今回紹介する方法は、TextMeshPro（テキストメッシュプロ）を使って、<br>簡単に実装できるシンプルな方法です。</p>



<p class="wp-block-paragraph">ソースコードの大まかな流れは以下の通りです。</p>



<div class="wp-block-cocoon-blocks-tab-caption-box-1 tab-caption-box block-box has-border-color has-blue-border-color not-nested-style cocoon-block-tab-caption-box" style="--cocoon-custom-border-color:#0095d9"><div class="tab-caption-box-label block-box-label box-label fab-bolt"><span class="tab-caption-box-label-text block-box-label-text box-label-text">機能の内容</span></div><div class="tab-caption-box-content block-box-content box-content">
<ul class="wp-block-list">
<li>Resourcesフォルダに格納したテキストファイル（csv）を読み込み、表示するテキストを準備</li>



<li>コルーチンを利用して1文字ずつ表示し、表示間隔を調整</li>



<li>テキスト中のタグ（やなど）が途切れないように注意して処理</li>
</ul>
</div></div>



<p class="wp-block-paragraph">Unityでテキストを表示するのは多種ありますが、TextMeshProが主流です。<br>制御もしやすく、フォントを自由に使うことができます。</p>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-info-circle"></span>TMPをインストールする方法を紹介しています。</span></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together">

<a target="_self" href="https://alicia-ing.com/programming/unity/textmeshpro/" title="【Unity】TextMeshPro-日本語表示とスクリプト制御" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://alicia-ing.com/wp-content/uploads/2024/01/textmeshpro-160x90.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://alicia-ing.com/wp-content/uploads/2024/01/textmeshpro-160x90.webp 160w, https://alicia-ing.com/wp-content/uploads/2024/01/textmeshpro-120x68.webp 120w, https://alicia-ing.com/wp-content/uploads/2024/01/textmeshpro-320x180.webp 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【Unity】TextMeshPro-日本語表示とスクリプト制御</div><div class="blogcard-snippet internal-blogcard-snippet">UnityのTextMeshProは日本語のテキストを美しく表示し、スクリプトでテキストを動的に変更することも可能です。改行は&quot;\n&quot;でします。&quot;japanese_full.txt&quot;ファイルを読み込んでTextMeshProに適用します。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://alicia-ing.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">alicia-ing.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2025.08.11</div></div></div></div></a>
</div>



<p class="wp-block-paragraph">stringを使用してスクリプト内のテキストで表示させる方法もありますが、<br>本記事では扱いやすくてより実践的なCSVファイルを読み込んで表示します。</p>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-info-circle"></span>Unityでcsvファイルを読み込む方法を紹介しています。</span></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together">

<a target="_self" href="https://alicia-ing.com/programming/unity/csv-load/" title="【Unity】CSVファイルを読み込み、テキストを画面に表示する" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://alicia-ing.com/wp-content/uploads/2022/12/csv-load-1-160x90.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://alicia-ing.com/wp-content/uploads/2022/12/csv-load-1-160x90.webp 160w, https://alicia-ing.com/wp-content/uploads/2022/12/csv-load-1-120x68.webp 120w, https://alicia-ing.com/wp-content/uploads/2022/12/csv-load-1-320x180.webp 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【Unity】CSVファイルを読み込み、テキストを画面に表示する</div><div class="blogcard-snippet internal-blogcard-snippet">UnityでのCSVファイルの読み込み方法を解説します。エクセルやGoogleスプレッドシートでcsvを作成し、データのインポート・読み書き・外部ファイル読み込みを簡単に実装する方法を紹介。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://alicia-ing.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">alicia-ing.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2025.08.12</div></div></div></div></a>
</div>



<h3 class="wp-block-heading">ソースコード</h3>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>using System.Collections;
using UnityEngine;
using TMPro;
using System.IO;

public class typing : MonoBehaviour
{
    public TextMeshProUGUI LogText;
    public float typingInterval = 0.05f; // 文字表示の速度

    private string fullText;
    private bool isTyping = false;//タイピング開始

    void Start()
    {
        LoadCSV(&quot;Sample&quot;);
    }

    void LoadCSV(string fileName)
    {
        TextAsset csvFile = Resources.Load&lt;TextAsset&gt;(fileName);
        if (csvFile != null)
        {
            using (StringReader reader = new StringReader(csvFile.text))
            {
                fullText = reader.ReadLine();
            }
            StartCoroutine(TypeText());
        }
        else
        {
            Debug.LogError($&quot;CSVファイル({fileName})が見つかりません。&quot;);
        }
    }

    IEnumerator TypeText()
    {
        isTyping = true;
        LogText.text = &quot;&quot;;
        int i = 0;

        while (i &lt; fullText.Length)
        {
            if (fullText[i] == &#39;&lt;&#39;) // タグ開始の処理
            {
                int tagEnd = fullText.IndexOf(&#39;&gt;&#39;, i);
                if (tagEnd != -1)
                {
                    LogText.text += fullText.Substring(i, tagEnd - i + 1);
                    i = tagEnd + 1;
                }
            }
            else
            {
                LogText.text += fullText[i];
                i++;
                yield return new WaitForSeconds(typingInterval);
            }
        }

        isTyping = false;
    }
}</code></pre></div>



<h3 class="wp-block-heading">解説</h3>



<ul class="wp-block-list">
<li><strong>名前空間</strong></li>
</ul>



<p class="wp-block-paragraph">「System.Collections」：IEnumeratorとコルーチンを利用するために必要。<br>「UnityEngine」：MonoBehaviourを継承し、Unityの基本機能を使用するために必要。<br>「TMPro」：TextMeshProUGUIを使用し、UIにテキスト表示を行うために必要。<br>「System.IO」：文字列の読み込みや操作にStringReaderを使用するために必要。</p>



<ul class="wp-block-list">
<li><strong>フィールド（メンバ変数）</strong></li>
</ul>



<p class="wp-block-paragraph">「LogText」：画面に表示するテキスト（TMP）を格納し、逐次テキストを追加表示するためのUI要素。<br>「typingInterval」：1文字表示ごとの待機時間（秒数）を指定することで、テキスト表示の速度を調整する。<br>「fullText」：CSVファイルから読み込んだ表示対象の文字列を格納する。<br>「isTyping」：現在タイピング表示処理が進行中か否かを判定するフラグ（真偽値）。</p>



<ul class="wp-block-list">
<li><strong>LoadCSVメソッド</strong></li>
</ul>



<p class="wp-block-paragraph">引数として渡されたファイル名（Resources内にあるCSV形式のテキストファイル）を読み込む。</p>



<p class="wp-block-paragraph">読み込みが成功すると、ファイルから取得した最初の行のテキストをfullTextに格納し、<br>TypeTextコルーチンを呼び出して文字列の逐次表示を開始する。</p>



<p class="wp-block-paragraph">指定のファイルが存在しない場合は、エラーをログに表示する。</p>



<ul class="wp-block-list">
<li><strong>TypeTextメソッド</strong></li>
</ul>



<p class="wp-block-paragraph">コルーチンを用いて、fullTextに格納されているテキストを1文字ずつ表示する。</p>



<p class="wp-block-paragraph">文字列内にHTMLタグなどの特殊タグ（&lt;…&gt;）があった場合はタグ全体をまとめて表示し、<br>タグが途切れないよう処理する。</p>



<p class="wp-block-paragraph">タグではない通常の文字は、指定したインターバル（typingInterval）ごとに1文字ずつ追加表示される。<br></p>



<p class="wp-block-paragraph">全ての文字を表示し終えると、isTypingフラグをfalseに戻し、処理を完了する。</p>



<h2 class="wp-block-heading">実演</h2>



<p class="wp-block-paragraph">作成したスクリプトをInspectorウィンドウにアタッチして実行すると、<br>以下のような挙動を確認できます。</p>



<div class="wp-block-cocoon-blocks-tab-caption-box-1 tab-caption-box block-box has-border-color has-yellow-border-color not-nested-style cocoon-block-tab-caption-box" style="--cocoon-custom-border-color:#ffd900"><div class="tab-caption-box-label block-box-label box-label fab-bolt"><span class="tab-caption-box-label-text block-box-label-text box-label-text">冒頭の挙動</span></div><div class="tab-caption-box-content block-box-content box-content">
<ul class="wp-block-list">
<li>Resourcesフォルダに配置されたCSVファイルの最初の行が1文字ずつゆっくりと表示される</li>



<li>&lt;color&gt;や&lt;size&gt;などのTextMeshProタグは、文字送りの途中で途切れることなく正しく表示される</li>



<li>テキスト表示中は他の入力を受け付けない（ただし、後述の応用機能で回避可能）</li>
</ul>
</div></div>



<p class="wp-block-paragraph">CSVはResourcesフォルダーに入れて管理しますが、現在は非推奨です。</p>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-info-circle"></span>Resourcesファイルの使い方とやめた方が良い理由を解説しています。</span></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together">

<a target="_self" href="https://alicia-ing.com/programming/unity/resources/" title="【Unity】Resourcesフォルダの使い方と非推奨な理由" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://alicia-ing.com/wp-content/uploads/2024/09/Resources-160x90.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://alicia-ing.com/wp-content/uploads/2024/09/Resources-160x90.webp 160w, https://alicia-ing.com/wp-content/uploads/2024/09/Resources-120x68.webp 120w, https://alicia-ing.com/wp-content/uploads/2024/09/Resources-320x180.webp 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【Unity】Resourcesフォルダの使い方と非推奨な理由</div><div class="blogcard-snippet internal-blogcard-snippet">UnityのResourcesフォルダは、アセットを動的に管理できる機能ですが、非推奨とされる。ビルドサイズの増加やメモリ管理の難しさ、アセット参照の追跡が困難になることなどで、「アドレッサブルシステム」を利用することが推奨とされる。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://alicia-ing.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">alicia-ing.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2025.04.29</div></div></div></div></a>
</div>



<h3 class="wp-block-heading">文字送り中に、右クリックで全表示する</h3>



<p class="wp-block-paragraph">さらに快適なユーザー体験を提供するために、応用機能として「右クリックすると瞬時に全テキストが表示される機能」も追加してみましょう。</p>



<p class="wp-block-paragraph">これによりプレイヤーが待ち時間を自由にコントロールでき、ストレスを軽減できます。</p>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>void Update()
{
    if (Input.GetMouseButtonDown(1) && isTyping)
    {
        StopAllCoroutines();
        LogText.text = fullText;
        isTyping = false;
    }
}</code></pre></div>



<p class="wp-block-paragraph">右クリックでコルーチンを途中停止することで、処理の完了を即時化します。</p>



<h3 class="wp-block-heading">左クリックで全文を表示し、もう一度で次の行へ進む</h3>



<p class="wp-block-paragraph">会話を読み進めるゲームでは、文字の表示中に左クリックすると全文が出て、もう一度左クリックすると次の行へ進む、という動きがよく使われます。</p>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>private Coroutine typingCoroutine;   // 動いているコルーチンを覚えておく

void ShowLine(string text)
{
    fullText = text;
    if (typingCoroutine != null) StopCoroutine(typingCoroutine);
    typingCoroutine = StartCoroutine(TypeText());
}

void Update()
{
    if (!Input.GetMouseButtonDown(0)) return;

    if (isTyping)
    {
        // 1回目のクリック：全文を表示するだけ
        StopCoroutine(typingCoroutine);
        LogText.text = fullText;
        isTyping = false;
    }
    else
    {
        // 2回目のクリック：次の行へ
        NextLine();   // 次の行の文字をShowLineに渡す処理
    }
}</code></pre></div>



<p class="wp-block-paragraph">StopAllCoroutines()は、そのスクリプトで動いている<strong>すべての</strong>コルーチンを止めます。自動送りなど別のコルーチンも同じスクリプトで動かしている場合は、上のようにStartCoroutineの戻り値を覚えておき、StopCoroutineでそれだけを止めます。</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-1 sbs-stn sbp-l sbis-cb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://alicia-ing.com/wp-content/uploads/2023/05/alicia.webp" alt="著者の体験談" class="speech-icon-image"/></figure><div class="speech-name">著者の体験談</div></div><div class="speech-balloon">
<p class="wp-block-paragraph">左クリックで「全文表示→次の行」、右クリックでバックログを開く、という分け方にしています。オート再生も別のコルーチンで動かしているので、StopAllCoroutines()だとオートまで止まってしまいました。</p>
</div></div>



<h3 class="wp-block-heading">閉じていない「&lt;」でゲームが固まるのを防ぐ</h3>



<p class="wp-block-paragraph">本記事のTypeTextは、閉じていない「&lt;」（「&gt;」が無いもの）がセリフにあると、読む位置が進まずにゲームが固まります。タグの終わりが見つからないときは、「&lt;」を普通の文字として1文字進める処理を足しておくと安全です。</p>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>if (tagEnd != -1)
{
    LogText.text += fullText.Substring(i, tagEnd - i + 1);   // タグはまとめて追加
    i = tagEnd + 1;
}
else
{
    LogText.text += fullText[i];   // 閉じていない &lt; はそのまま表示
    i++;
}</code></pre></div>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">この記事では、UnityのTextMeshProを使った1文字ずつ表示する方法を解説しました。</p>



<p class="wp-block-paragraph">キャラクターが実際に会話しているような演出を実現することで、<br>ゲームのクオリティやプレイヤーの没入感が大幅に向上します。</p>



<p class="wp-block-paragraph">また、「右クリック即時表示」機能を導入すれば、<br>ユーザーがさらに快適にゲームを楽しめます。</p>



<p class="wp-block-paragraph">次のステップとして以下の記事もチェックして、さらなるスキルアップを目指しましょう！</p>
]]></content:encoded>
					
					<wfw:commentRss>https://alicia-ing.com/programming/unity/display-one-character-at-a-time/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【Unity】ピッチで速度変更をしても高さを変えない方法</title>
		<link>https://alicia-ing.com/programming/unity/pitchshifter/</link>
					<comments>https://alicia-ing.com/programming/unity/pitchshifter/#respond</comments>
		
		<dc:creator><![CDATA[アリッシア]]></dc:creator>
		<pubDate>Sun, 23 Feb 2025 22:00:00 +0000</pubDate>
				<category><![CDATA[Unity]]></category>
		<guid isPermaLink="false">https://alicia-ing.com/?p=8410</guid>

					<description><![CDATA[Unityでゲームやアプリケーションを制作する際、音声の再生速度を変更することは演出や操作感の向上に非常に有効です。 しかし、再生速度を単純に上げると、音の高さも一緒に上がってしまい、思い通りのサウンドにならないケースが [&#8230;]]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-cocoon-blocks-label-box-1 label-box block-box not-nested-style cocoon-block-label-box"><div class="label-box-label block-box-label box-label fab-flag"><span class="label-box-label-text block-box-label-text box-label-text">本記事を読むと以下の実行ができます</span></div><div class="label-box-content block-box-content box-content">
<p class="wp-block-paragraph">音程を高くすることなく、再生速度だけ変える。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1920" height="940" src="https://alicia-ing.com/wp-content/uploads/2025/02/complete-1.gif" alt="" class="wp-image-8436"/></figure>
</div></div>



<p class="wp-block-paragraph">Unityでゲームやアプリケーションを制作する際、<br><strong>音声の再生速度を変更する</strong>ことは演出や操作感の向上に非常に有効です。</p>



<p class="wp-block-paragraph">しかし、<strong>再生速度を単純に上げると、音の高さも一緒に上がってしまい</strong>、<br>思い通りのサウンドにならないケースが多々あります。</p>



<p class="wp-block-paragraph">本記事では、AudioSourceのピッチ設定を利用しつつ、<br>AudioMixerのPitch Shifterを併用することで、再生速度だけを変更し、<br>音程はそのまま維持する方法について詳しく説明します。</p>



<div class="wp-block-cocoon-blocks-label-box-1 label-box block-box cocoon-block-label-box"><div class="label-box-label block-box-label box-label fab-check"><span class="label-box-label-text block-box-label-text box-label-text">本記事は次の人におすすめ</span></div><div class="label-box-content block-box-content box-content">
<ul class="wp-block-list">
<li>Unityでオーディオ再生の速度調整に挑戦したい開発者</li>



<li>高品質なサウンドを保ちつつ再生速度を操作したいゲームクリエイター</li>



<li>AudioMixerを活用して音程補正を実現したいエンジニア</li>



<li>UIコンポーネントと連動した実装方法を学びたい初心者プログラマー</li>



<li>実践的なスクリプト例から学び、応用力を高めたい技術者</li>
</ul>
</div></div>



<div class="wp-block-cocoon-blocks-micro-balloon-2 aligncenter micro-balloon micro-top mc-circle micro-copy"><span class="micro-balloon-content micro-content"><strong>Udemyで学習する</strong></span></div>



<div class="wp-block-cocoon-blocks-button-1 aligncenter button-block"><a target="_self" href="https://click.linksynergy.com/deeplink?id=IyOtUnEMtpw&amp;mid=47984&amp;murl=https%3A%2F%2Fwww.udemy.com%2Fcourses%2Fdevelopment%2F" class="btn btn-m btn-shine has-background has-light-green-background-color">Udemy 公式サイト</a></div>



<h2 class="wp-block-heading">Pitch（AudioSource）</h2>



<p class="wp-block-paragraph">AudioSourceの<strong>ピッチ（Pitch）</strong>は、音声の再生速度と周波数を決定する重要なパラメータです。</p>



<p class="wp-block-paragraph">ピッチの値を上げると<strong>再生速度が速くなり、同時に音の高さ（周波数）も上昇</strong>します。<br>ピッチを上げるとこのサンプルレートが相対的に高くなり、<br>波形の周期が短縮されることで音程が上昇します。</p>



<p class="wp-block-paragraph">たとえば、以下のようにピッチを1.5に設定すると、<br><strong>元の再生速度よりも50％速く再生</strong>され、音程も高く聞こえるようになります。</p>



<p class="wp-block-paragraph">ピッチの変更は、<strong>Inspectorウィンドウ</strong>のAudioSourceで操作できますが、<br><strong>スクリプトを使う</strong>ことでも制御可能です。</p>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>// AudioSourceのピッチを1.5に変更する例
audioSource.pitch = 1.5f;</code></pre></div>



<h2 class="wp-block-heading">PitchShifter</h2>



<p class="wp-block-paragraph">PitchShifterは、AudioMixer上で動作する<strong>オーディオエフェクト</strong>の一種です。<br>このエフェクトは、再生速度を変更した際に生じる<strong>音程の変化を補正</strong>するために利用されます。</p>



<p class="wp-block-paragraph">音の高さを変えないためには、AudioSourceのピッチ操作によって速くなった再生速度に合わせ、<br><strong>逆数の値を用いてPitch Shifterを調整する</strong>ことで、音程を元の状態に近づけることが可能となります。</p>



<p class="wp-block-paragraph">AudioSourceのピッチ操作と同様にInspectorウィンドウからだけではなく、<br><strong>スクリプト制御</strong>が可能です。</p>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>// AudioMixerのPitch Shifterパラメータを設定する例（パラメータ名：&quot;PitchShifter&quot;）
audioMixer.SetFloat(&quot;PitchShifter&quot;, 0.75f);</code></pre></div>



<h3 class="wp-block-heading">PitchShifterの作成方法</h3>



<p class="wp-block-paragraph">PitchShifterを利用するためには、<strong>Unityエディタ内でAudioMixer</strong>を正しく設定し、<br>Pitch Shifterエフェクトを適用する必要があります。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1920" height="940" src="https://alicia-ing.com/wp-content/uploads/2025/02/audio_mixer.webp" alt="" class="wp-image-8417" srcset="https://alicia-ing.com/wp-content/uploads/2025/02/audio_mixer.webp 1920w, https://alicia-ing.com/wp-content/uploads/2025/02/audio_mixer-300x147.webp 300w, https://alicia-ing.com/wp-content/uploads/2025/02/audio_mixer-1024x501.webp 1024w, https://alicia-ing.com/wp-content/uploads/2025/02/audio_mixer-768x376.webp 768w, https://alicia-ing.com/wp-content/uploads/2025/02/audio_mixer-1536x752.webp 1536w" sizes="(max-width: 1920px) 100vw, 1920px" /></figure>



<p class="wp-block-paragraph">作成したAudioMixerをダブルクリック、あるいはUnityエディタ上部のメニューから「Window」＞「AudioMixer」を選択し、新規または既存のAudioMixerを開きます。</p>



<p class="wp-block-paragraph">AudioMixerは複数のオーディオグループをまとめて管理できるため、<br>エフェクトの適用や音量調整が容易になります。</p>



<p class="wp-block-paragraph">作成したAudioMixer内の適用対象となるミキサーグループを選択します。<br>本記事では、「Master」を使用します。<br><strong>「Add…」ボタン</strong>をクリックし、リストから「Pitch Shifter」エフェクトを追加します。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1915" height="944" src="https://alicia-ing.com/wp-content/uploads/2025/02/add_pitch_shifter.webp" alt="" class="wp-image-8418" srcset="https://alicia-ing.com/wp-content/uploads/2025/02/add_pitch_shifter.webp 1915w, https://alicia-ing.com/wp-content/uploads/2025/02/add_pitch_shifter-300x148.webp 300w, https://alicia-ing.com/wp-content/uploads/2025/02/add_pitch_shifter-1024x505.webp 1024w, https://alicia-ing.com/wp-content/uploads/2025/02/add_pitch_shifter-768x379.webp 768w, https://alicia-ing.com/wp-content/uploads/2025/02/add_pitch_shifter-1536x757.webp 1536w" sizes="(max-width: 1915px) 100vw, 1915px" /></figure>



<p class="wp-block-paragraph">Pitch Shifterエフェクトは、<strong>AudioSourceのピッチ変更に伴う音程のズレを補正</strong>する機能です。</p>



<h3 class="wp-block-heading">エフェクトパラメータのExpose</h3>



<p class="wp-block-paragraph">Pitch Shifterエフェクトを導入して、ゲームを再生すると<strong>警告文</strong>が出てきます。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1917" height="943" src="https://alicia-ing.com/wp-content/uploads/2025/02/alert_exposed.webp" alt="" class="wp-image-8422" srcset="https://alicia-ing.com/wp-content/uploads/2025/02/alert_exposed.webp 1917w, https://alicia-ing.com/wp-content/uploads/2025/02/alert_exposed-300x148.webp 300w, https://alicia-ing.com/wp-content/uploads/2025/02/alert_exposed-1024x504.webp 1024w, https://alicia-ing.com/wp-content/uploads/2025/02/alert_exposed-768x378.webp 768w, https://alicia-ing.com/wp-content/uploads/2025/02/alert_exposed-1536x756.webp 1536w" sizes="(max-width: 1917px) 100vw, 1917px" /></figure>



<p class="wp-block-paragraph">警告文の内容は、<strong>PitchShifterがない</strong>というもの。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Exposed name does not exist: PitchShifter<br>UnityEngine.StackTraceUtility:ExtractStackTrace ()</p>
</blockquote>



<p class="wp-block-paragraph">エフェクト追加後、Pitch Shifterのパラメータをスクリプトから操作できるようにExposeします。</p>



<p class="wp-block-paragraph">InspectorウインドウのPitch Shifterエフェクトで<strong>パラメータ名を右クリック</strong>します。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1920" height="940" src="https://alicia-ing.com/wp-content/uploads/2025/02/expose_pitch.webp" alt="" class="wp-image-8419" srcset="https://alicia-ing.com/wp-content/uploads/2025/02/expose_pitch.webp 1920w, https://alicia-ing.com/wp-content/uploads/2025/02/expose_pitch-300x147.webp 300w, https://alicia-ing.com/wp-content/uploads/2025/02/expose_pitch-1024x501.webp 1024w, https://alicia-ing.com/wp-content/uploads/2025/02/expose_pitch-768x376.webp 768w, https://alicia-ing.com/wp-content/uploads/2025/02/expose_pitch-1536x752.webp 1536w" sizes="(max-width: 1920px) 100vw, 1920px" /></figure>



<p class="wp-block-paragraph">「Expose pitch to script」でスクリプト制御を可能にします。<br>さらに、「Exposed Parameters」で<strong>名前を「PitchShifter」に変更</strong>します。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1920" height="940" src="https://alicia-ing.com/wp-content/uploads/2025/02/expose_rename.webp" alt="" class="wp-image-8420" srcset="https://alicia-ing.com/wp-content/uploads/2025/02/expose_rename.webp 1920w, https://alicia-ing.com/wp-content/uploads/2025/02/expose_rename-300x147.webp 300w, https://alicia-ing.com/wp-content/uploads/2025/02/expose_rename-1024x501.webp 1024w, https://alicia-ing.com/wp-content/uploads/2025/02/expose_rename-768x376.webp 768w, https://alicia-ing.com/wp-content/uploads/2025/02/expose_rename-1536x752.webp 1536w" sizes="(max-width: 1920px) 100vw, 1920px" /></figure>



<p class="wp-block-paragraph">この設定でスクリプト側から<strong>AudioMixer.SetFloat(&#8220;PitchShifter&#8221;, 補正値)</strong>を利用して、<br>エフェクトのパラメータにアクセス可能となります。</p>



<h2 class="wp-block-heading">再生速度だけ上げて高さはそのまま</h2>



<p class="wp-block-paragraph">再生速度だけを上げて音程（高さ）は変えないように、<br>AudioSourceとAudioMixerの両方を連動させる設定を行ってきました。</p>



<p class="wp-block-paragraph">そこで、<strong>スライダーを操作して再生速度だけ上げる機能</strong>を作成します。</p>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-info-circle"></span>スライダーの使い方を紹介しています。</span></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together">

<a target="_self" href="https://alicia-ing.com/programming/unity/slider-bar/" title="【Unity】スライダー使い方｜制限時間ゲージ、HPバー、音量調整" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://alicia-ing.com/wp-content/uploads/2024/01/slider-bar-160x90.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://alicia-ing.com/wp-content/uploads/2024/01/slider-bar-160x90.webp 160w, https://alicia-ing.com/wp-content/uploads/2024/01/slider-bar-120x68.webp 120w, https://alicia-ing.com/wp-content/uploads/2024/01/slider-bar-320x180.webp 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【Unity】スライダー使い方｜制限時間ゲージ、HPバー、音量調整</div><div class="blogcard-snippet internal-blogcard-snippet">Unityのスライダー（Slider）でHPバー・制限時間ゲージ・音量調整を作る方法を解説。Min Value・Max Valueの設定、HPバーをなめらかに減らすスクリプト、離したとき・押したときの処理まで紹介します。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://alicia-ing.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">alicia-ing.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2026.10.12</div></div></div></div></a>
</div>



<p class="wp-block-paragraph">方法はAudioSourceの<strong>pitch</strong>プロパティを変更して、再生速度を調整する。<br>同時に、AudioMixer上のPitchShifterパラメータに、AudioSourceのpitch値の逆数を設定する。</p>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-info-circle"></span>csvでaudio再生する方法を紹介しています。</span></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together">

<a target="_self" href="https://alicia-ing.com/programming/unity/csv-image-voice/" title="【Unity】csvファイルから画像と音声をパスで読み込み" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://alicia-ing.com/wp-content/uploads/2023/01/csv-image-voice-160x90.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://alicia-ing.com/wp-content/uploads/2023/01/csv-image-voice-160x90.webp 160w, https://alicia-ing.com/wp-content/uploads/2023/01/csv-image-voice-120x68.webp 120w, https://alicia-ing.com/wp-content/uploads/2023/01/csv-image-voice-320x180.webp 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【Unity】csvファイルから画像と音声をパスで読み込み</div><div class="blogcard-snippet internal-blogcard-snippet">Unityでcsvに書いたパスから画像と音声を読み込む方法を解説。Resourcesフォルダの使い方と非推奨な理由、立ち絵・ボイスの表示に加えて、背景・BGMをcsvで切り替える方法も紹介します。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://alicia-ing.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">alicia-ing.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2026.10.19</div></div></div></div></a>
</div>



<h3 class="wp-block-heading">ソースコード</h3>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>using UnityEngine;
using UnityEngine.UI;
using TMPro;
using UnityEngine.Audio;

public class AudioPitchController : MonoBehaviour
{
    public AudioSource audioSource;  // 操作対象の AudioSource
    public Slider pitchSlider;       // スライダー
    public TMP_Text pitchText;       // 再生速度表示用の TMP
    public AudioMixer audioMixer;    // AudioMixer（Pitch Shifterを制御するため）

    private const string PitchShifterParam = &quot;PitchShifter&quot;; // Audio Mixer の Pitch パラメータ

    void Start()
    {
        if (pitchSlider != null)
        {
            pitchSlider.minValue = 0.5f; // スライダーの最小値を0.5
            pitchSlider.maxValue = 2.0f; // スライダーの最大値を2.0
            pitchSlider.value = 1.0f;    // 初期値を1.0
            pitchSlider.onValueChanged.AddListener(UpdatePitch);
        }

        UpdatePitch(pitchSlider.value); // 初期値の設定
    }

    void UpdatePitch(float value)
    {
        // AudioSource の pitch を変更
        if (audioSource != null)
        {
            audioSource.pitch = value; // 再生速度変更
            Debug.Log($&quot;AudioSource.pitch = {audioSource.pitch}&quot;);
        }
        else
        {
            Debug.LogWarning(&quot;AudioSource が設定されていません！&quot;);
        }

        // AudioMixer の Pitch Shifter を調整
        if (audioMixer != null)
        {
            float pitchShifterValue = 1.0f / value; // 逆数にすることで音程を一定に保つ
            audioMixer.SetFloat(PitchShifterParam, pitchShifterValue);
            Debug.Log($&quot;AudioMixer Pitch Shifter = {pitchShifterValue}&quot;);
        }
        else
        {
            Debug.LogWarning(&quot;AudioMixer が設定されていません！&quot;);
        }

        // Text 表示を更新
        if (pitchText != null)
        {
            pitchText.text = $&quot;×{value:F2}&quot;; // 小数2桁で表示
        }
    }
}</code></pre></div>



<h4 class="wp-block-heading">UdemyでUnityを学習</h4>



<p class="wp-block-paragraph"><a target="_self" href="https://click.linksynergy.com/deeplink?id=IyOtUnEMtpw&amp;mid=47984&amp;murl=https%3A%2F%2Fwww.udemy.com%2F">Udemy</a>は、オンデマンド式の学習講座です。<br>趣味から実務まで使えるおすすめの講座を紹介します。</p>



<div class="wp-block-cocoon-blocks-micro-text aligncenter micro-text micro-copy micro-top"><span class="micro-text-content micro-content">＼Unityの学習から収益化の方法はこちらから！／</span></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together">

<a target="_self" href="https://alicia-ing.com/programming/unity/roadmap-cs/" title="【Unity】学習ロードマップ｜自作ゲームを作りたい人必見！" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://alicia-ing.com/wp-content/uploads/2024/10/roadmap-cs-160x90.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://alicia-ing.com/wp-content/uploads/2024/10/roadmap-cs-160x90.webp 160w, https://alicia-ing.com/wp-content/uploads/2024/10/roadmap-cs-120x68.webp 120w, https://alicia-ing.com/wp-content/uploads/2024/10/roadmap-cs-320x180.webp 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【Unity】学習ロードマップ｜自作ゲームを作りたい人必見！</div><div class="blogcard-snippet internal-blogcard-snippet">Unityを使って自作ゲームを作りたい方必見。ゲームエンジン選択から学習方法、収益化の手段まで初心者向けにわかりやすく解説します。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://alicia-ing.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">alicia-ing.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2026.10.06</div></div></div></div></a>
</div>



<div class="wp-block-cocoon-blocks-tab-box-1 blank-box bb-tab bb-pickup block-box has-border-color has-yellow-border-color">
<ul class="wp-block-list">
<li><a target="_self" href="https://click.linksynergy.com/deeplink?id=IyOtUnEMtpw&amp;mid=47984&amp;murl=https%3A%2F%2Fwww.udemy.com%2Fcourse%2Fild-unity-777game%2F">【Unity C# ゲーム開発超入門】7つのミニゲームを作っておぼえる！UnityとC#講座</a><br>Unityで頻出の機能を実際のゲーム作りで学習。<br><strong>何か作りたい、今後の開発で役立てたい初心者</strong>におすすめ</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<ul class="wp-block-list">
<li><a target="_self" href="https://click.linksynergy.com/deeplink?id=IyOtUnEMtpw&amp;mid=47984&amp;murl=https%3A%2F%2Fwww.udemy.com%2Fcourse%2Fild-unity-playing_cards%2F">【Unity C# ゲーム開発初心者レベルアップ】7つのトランプゲームを作っておぼえる！UnityとC#講座</a><br>トランプやボードゲーム作りに特化している講座。<br><strong>テーブルゲームを作りたい人</strong>におすすめ。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<ul class="wp-block-list">
<li><a target="_self" href="https://click.linksynergy.com/deeplink?id=IyOtUnEMtpw&amp;mid=47984&amp;murl=https%3A%2F%2Fwww.udemy.com%2Fcourse%2Funityworld%2F" data-type="link" data-id="https://click.linksynergy.com/deeplink?id=IyOtUnEMtpw&amp;mid=47984&amp;murl=https%3A%2F%2Fwww.udemy.com%2Fcourse%2Funityworld%2F">【全行程を網羅！最初に学びたい総合学習】Unityワールド制作講座<br></a>Unityワールド制作の全工程を学習できる講座。<br><strong>RPGを作りたい人</strong>におすすめ。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<ul class="wp-block-list">
<li><a target="_self" href="https://click.linksynergy.com/deeplink?id=IyOtUnEMtpw&amp;mid=47984&amp;murl=https%3A%2F%2Fwww.udemy.com%2Fcourse%2Fstudio_shimazu_nfrpg%2F">Unity ゲーム開発：インディーゲームクリエイターが教える C#の基礎からゲームリリースまで【スタジオしまづ】</a><br>C#の文法やApp StoreとGoogle Playへゲームをリリース方法を解説。<br><strong>ゲームを出品したい人</strong>におすすめ。</li>
</ul>
</div>



<h3 class="wp-block-heading">解説</h3>



<ul class="wp-block-list">
<li><strong>名前空間</strong></li>
</ul>



<p class="wp-block-paragraph">UnityEngine：ゲーム開発の基本機能（GameObject、Transform、MonoBehaviourなど）を利用するために必要です。<br>UnityEngine.UI：UIコンポーネント（スライダーなど）を利用するために必要です。<br>TMPro：TextMeshProのテキスト表示機能を利用するために必要です。<br>UnityEngine.Audio：オーディオの再生やミキシング、AudioMixerを操作するために必要です。</p>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-info-circle"></span>Unityで文字を表示する方法を紹介してます。</span></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together">

<a target="_self" href="https://alicia-ing.com/programming/unity/textmeshpro/" title="【Unity】TextMeshPro-日本語表示とスクリプト制御" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://alicia-ing.com/wp-content/uploads/2024/01/textmeshpro-160x90.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://alicia-ing.com/wp-content/uploads/2024/01/textmeshpro-160x90.webp 160w, https://alicia-ing.com/wp-content/uploads/2024/01/textmeshpro-120x68.webp 120w, https://alicia-ing.com/wp-content/uploads/2024/01/textmeshpro-320x180.webp 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【Unity】TextMeshPro-日本語表示とスクリプト制御</div><div class="blogcard-snippet internal-blogcard-snippet">UnityのTextMeshProは日本語のテキストを美しく表示し、スクリプトでテキストを動的に変更することも可能です。改行は&quot;\n&quot;でします。&quot;japanese_full.txt&quot;ファイルを読み込んでTextMeshProに適用します。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://alicia-ing.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">alicia-ing.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2025.08.11</div></div></div></div></a>
</div>



<ul class="wp-block-list">
<li><strong>フィールド（メンバ変数）</strong></li>
</ul>



<p class="wp-block-paragraph">audioSource：音声再生の制御を担うAudioSourceコンポーネントを参照します。<br>pitchSlider：再生速度（ピッチ）の調整に使用するスライダーコンポーネントを参照します。<br>pitchText：現在の再生速度をテキスト表示するためのTextMeshProコンポーネントを参照します。<br>audioMixer：ピッチシフターのパラメータを調整するためのAudioMixerコンポーネントを参照します。<br>PitchShifterParam：AudioMixer内のピッチシフターを制御するためのパラメータ名「PitchShifter」を保持する定数です。</p>



<ul class="wp-block-list">
<li><strong><strong>Startメソッド</strong></strong></li>
</ul>



<p class="wp-block-paragraph">スライダーが存在する場合、最小値（0.5）、最大値（2.0）、初期値（1.0）を設定し、<br>スライダー値の変化でUpdatePitchメソッドが呼ばれるようリスナーを登録します。</p>



<p class="wp-block-paragraph">その後、初期値をもとに一度UpdatePitchメソッドを実行し、<br>AudioSourceやAudioMixer、テキスト表示などの初期状態を反映させます。</p>



<ul class="wp-block-list">
<li><strong>UpdatePitchメソッド</strong></li>
</ul>



<p class="wp-block-paragraph">AudioSourceが設定されていれば、その<strong>pitchプロパティを更新</strong>し、再生速度を変更します。<br>設定されていない場合は警告ログを出力します。</p>



<p class="wp-block-paragraph">AudioMixerが設定されていれば、<strong>引数の逆数を計算</strong>してピッチシフターのパラメータを調整し、音程を一定に保つよう補正します。</p>



<p class="wp-block-paragraph">設定されていない場合は警告ログを出力します。<br>TMPテキストが設定されていれば、計算された再生速度を<strong>小数点以下2桁でフォーマット</strong>し、<br>テキストに反映させます。</p>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-info-circle"></span>数値を文字として表示する方法を紹介します。</span></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together">

<a target="_self" href="https://alicia-ing.com/programming/unity/object-tostring/" title="【Unity】カウントアップでリザルト画面にスコアを表示" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://alicia-ing.com/wp-content/uploads/2022/12/object-tostring-1-160x90.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://alicia-ing.com/wp-content/uploads/2022/12/object-tostring-1-160x90.webp 160w, https://alicia-ing.com/wp-content/uploads/2022/12/object-tostring-1-120x68.webp 120w, https://alicia-ing.com/wp-content/uploads/2022/12/object-tostring-1-320x180.webp 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【Unity】カウントアップでリザルト画面にスコアを表示</div><div class="blogcard-snippet internal-blogcard-snippet">Unityでスコアを表示します。カウントアップ機能や別シーンに移動してリザルト画面を表示など紹介しています。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://alicia-ing.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">alicia-ing.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2025.04.16</div></div></div></div></a>
</div>



<h2 class="wp-block-heading">実演</h2>



<p class="wp-block-paragraph">初めに、シーン内に必要なUIコンポーネントを正しくアタッチしてください。</p>



<p class="wp-block-paragraph">シーンが開始されると、スクリプトのStartメソッドが実行され、<br>まずUI（特にSlider）の初期設定が行われます。</p>



<p class="wp-block-paragraph">スライダーの最小値（0.5）、最大値（2.0）、初期値（1.0）が設定され、<br>値が変更されるたびに<strong>UpdatePitchメソッドが呼ばれるようリスナーが登録</strong>されます。</p>



<p class="wp-block-paragraph">スライダーの値が直接AudioSourceの<strong>pitch</strong>プロパティに反映され、再生速度が変わります。</p>



<p class="wp-block-paragraph">音の高さが変わらないようにするため、AudioMixerのPitch Shifterパラメータには、<br><strong>スライダーの値の逆数</strong>が適用されます。</p>



<h2 class="wp-block-heading">再生速度をゲームの進行速度と連動させる</h2>



<p class="wp-block-paragraph">本記事の仕組みは、ゲームの「進行速度」の設定にも使えます。たとえば会話を読み進めるゲームで進行速度を2倍にしたら、BGMやボイスだけでなく、文字が出る間隔や、自動で次へ進むまでの待ち時間も半分にしたくなります。</p>



<p class="wp-block-paragraph">そこで、元の時間を速度の値で<strong>割り算</strong>して使います。</p>



<div class="hcb_wrap"><pre class="prism undefined-numbers lang-csharp" data-lang="C#"><code>float speed = pitchSlider.value;                   // 進行速度（0.5〜2倍）

audioSource.pitch = speed;                         // BGM・ボイスの再生速度
audioMixer.SetFloat(&quot;PitchShifter&quot;, 1f / speed);   // 音の高さは元に戻す

float typingInterval = baseTypingInterval / speed; // 1文字ごとの間隔
float autoWait = baseAutoWait / speed;             // 自動で次へ進むまでの待ち時間</code></pre></div>



<p class="wp-block-paragraph">割り算するのは「使うとき」だけにして、元の値（baseTypingIntervalとbaseAutoWait）は書き換えないようにします。割った結果で元の値を上書きして保存すると、次に起動したときにもう一度割られて、どんどん速くなってしまいます。</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-3 sbs-line sbp-l sbis-cb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://alicia-ing.com/wp-content/themes/cocoon-master/images/b-man.png" alt="筆者" class="speech-icon-image"/></figure><div class="speech-name">筆者</div></div><div class="speech-balloon">
<p class="wp-block-paragraph">自作のノベルゲームでは、進行速度のスライダー1本で、BGM・ボイスの再生速度と、文字送り・オートの待ち時間をまとめて変えています。最初は文字送りの値そのものを書き換えていたため、起動するたびに速くなる不具合が出ました。</p>
</div></div>



<div class="wp-block-cocoon-blocks-icon-box common-icon-box block-box memo-box">
<p class="wp-block-paragraph">本記事ではPitch Shifterを「Master」グループに付けています。この場合、効果音（SE）の音の高さも補正の対象になります。BGMとボイスだけ速度を変えたいときは、BGM用・ボイス用のグループを作ってPitch Shifterを付け、それぞれのAudioSourceの「Output」をそのグループにします。</p>
</div>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">本記事では、UnityにおけるAudioSourceのピッチ操作とAudioMixerのPitch Shifterエフェクトを組み合わせ、<strong>再生速度のみを変更しながらも音程を維持する</strong>方法について解説しました。</p>



<p class="wp-block-paragraph">この技法は、ゲーム内のBGM、効果音、ナレーションなど、さまざまなシーンで応用可能です。<br>例えば、スローや早送りの演出、ユーザーの操作に応じたリアルタイムな音声変化など、音響面での表現の幅を大きく広げることができます。</p>



<div class="wp-block-cocoon-blocks-micro-balloon-2 aligncenter micro-balloon micro-top mc-circle micro-copy"><span class="micro-balloon-content micro-content"><strong>Udemyで学習する</strong></span></div>



<div class="wp-block-cocoon-blocks-button-1 aligncenter button-block"><a target="_self" href="https://click.linksynergy.com/deeplink?id=IyOtUnEMtpw&amp;mid=47984&amp;murl=https%3A%2F%2Fwww.udemy.com%2Fcourses%2Fdevelopment%2F" class="btn btn-m btn-shine has-background has-light-green-background-color">Udemy 公式サイト</a></div>
]]></content:encoded>
					
					<wfw:commentRss>https://alicia-ing.com/programming/unity/pitchshifter/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
