🌊

【Unity Tips】Raycastで高速移動でも壁貫通ゼロ!初心者向けUnity移動ガイド

2024/12/06に公開

Unityでプレイヤーを移動させるとき、キーボードやコントローラーで入力を受け取り、キャラクターを動かします。ただし、移動スピードが速かったり、処理速度が遅い場合、キャラクターが壁をすり抜けてしまうことがあります。

この記事では、Unityの「Ray」という便利な機能を使って、この問題を防ぐ方法を解説します。プログラミング初心者でもわかりやすい内容になっているので、ぜひ試してみてください!

Unityの基本操作からC#スクリプトの基礎まで、やさしく学べる入門チュートリアルはこちら
https://zenn.dev/ryuryu_game/books/fd28de9d8e963a

Raycastとは?

Ray(レイ)とは、Unityで使える「仮想的な線」のことです。この線は始点から特定の方向へ伸びており、何かにぶつかる(衝突する)かどうかを検出するために使います。

https://tech.pjin.jp/blog/2021/10/28/unity-raycast/

Raycastの特徴

項目 説明
始点と方向 Rayは「始点」と「方向」を指定して使います。この2つを設定することで、レイがどこに伸びていくかが決まります。
衝突検出 Rayが障害物やオブジェクトにぶつかったかを調べることができます。
効率的な処理 Rayは軽量で動作が速いため、ゲームのパフォーマンスに悪影響を与えません。

https://nekojara.city/unity-ray-struct

Raycastの使いどころ

  • 地面の検出
    キャラクターが地面にいるか、空中にいるかを確認できます。

  • 敵の視野のシミュレーション
    敵キャラクターがプレイヤーを見つけたかどうかを判断できます。

  • クリック位置の検出
    マウスでクリックした場所にあるオブジェクトを見つけられます。

  • FPS・TPSの射撃システムの構築
    マウスでクリックした時に、カメラの中心にあるオブジェクトにダメージを与えることができます。

Rayの基本的な文法

Physics.Raycastは、bool型のため、光線がヒットしたかどうかをtrueorfalseで値を返します。

bool hitDetected = Physics.Raycast(始点, 方向, out RaycastHit hit情報, 最大距離, レイヤーマスク);

Rayを使ったプレイヤー移動のプログラム

以下のプログラムをコピーしてUnityに導入しましょう。キャラクターのオブジェクトにこのスクリプトをアタッチします。

using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerMove : MonoBehaviour
{
    [SerializeField]
    private float speed = 5f; // プレイヤーの移動速度をインスペクターから設定

    [SerializeField]
    private InputActionMap playerControls; // プレイヤー移動のアクションマップをインスペクターから設定

    private void Update()
    {
        HandleMovement();
    }

    private void HandleMovement()
    {
        // 入力から移動方向を計算
        Vector2 input = playerControls["Move"].ReadValue<Vector2>();
        Vector3 direction = (transform.forward * input.y + transform.right * input.x).normalized;

        // Rayの設定
        Vector3 rayStart = transform.position;
        Vector3 rayDirection = direction;
        float rayDistance = speed + 0.1f; // Rayの最大距離に余裕を持たせる

        // Raycastによる衝突判定
        if (!Physics.Raycast(rayStart, rayDirection, out RaycastHit hit, rayDistance))
        {
            // 衝突がない場合は移動
            transform.position += direction * speed * Time.deltaTime;
        }
        else
        {
            Debug.Log($"衝突: {hit.collider.name}");
        }

        // SceneビューでRayを可視化
        Debug.DrawRay(rayStart, rayDirection * rayDistance, Color.red);
    }
}

https://nekojara.city/unity-input-system-intro

https://nekojara.city/unity-input-system-actions

  • 変数設定
    speed:プレイヤーの移動速度
    playerControls:プレイヤーの操作アクションマップ(Input Systemを使用)

Unityで動作を確認してみよう

  1. Unityのシーンに障害物として「Cube」を配置します。障害物はキャラクターの移動経路に置いてみましょう。
  2. Unityエディタの上部にある「再生ボタン(▶)」をクリックして、ゲームを開始します。
  3. キャラクターを移動させてみて、障害物を通り抜けず正しく衝突判定が機能しているか確認してください。

最後に障害物に貫通せずに移動ができたら、成功!!!

もし問題が発生した場合は、スクリプトや設定をもう一度見直してみましょう!

この記事を読んでもっと実践したいと感じたあなたへ

Unity開発を効率よく進めるためには、実践的なスキルと仲間との交流が欠かせません。
そんな方におすすめのステップが、下記の3つです。

1. 有料教材「どこでもUnity教室」でゲーム制作を短期マスター

  • 5日でシンプルなFPS完成:初心者向けに要点を押さえたカリキュラム
  • C#や最新のInputSystem、FPS実装まで網羅:つまずきやすいポイントを先回りで解説
  • 購入特典:Discord招待+サンプルプロジェクトDLで、疑問や実装例を即確認

Unity初心者でも最短5日で3D FPSが完成!今すぐ始める入門チュートリアルはこちら

https://zenn.dev/ryuryu_game/books/fd28de9d8e963a

2. 無料コミュニティで、疑問をすぐに解消&モチベーションUP

  • 初心者~中級者までOK:学習進度に合わせて質問や情報共有
  • 質問サポートが充実:わからないことを仲間や講師に即相談
  • 学習仲間と切磋琢磨:一緒に学ぶから続けやすい

Discordサーバー参加はこちら

https://discord.gg/5FwuKCacNy

3. 実績豊富な“ゲーム開発所RYURYU”があなたをトータルサポート

  • コナラ総販売200件超:さまざまなUnity開発の依頼を対応
  • VR/AR/AIなど最新技術にも精通:幅広いノウハウを活かして開発支援
  • ゲームクリエイター甲子園や東京ゲームショウなど出展実績多数

ご相談・お問い合わせはこちら

https://coconala.com/users/1772507

Discussion