Unity初心者必見! ~壁抜けしない。Rayを使用した新しい移動方法!プログラムを徹底解説。~
更新日 2024 / 04 / 06
自己紹介
\ ココナラ実績140件達成 /
こんにちは!ゲーム開発所RYURYUのりゅうやと申します。
📢 Unityに興味がある方にお得なお知らせ
ゲーム開発所RYURYUの公式LINEを友だち追加して、5つの特別な特典🎁を受け取ろう‼️
はじめに
Unity3Dを使用してプレイヤーの移動を実装するとき、多くの開発者はキーボードやゲームコントローラーの入力を基に、`Transform`や`Rigidbody`を活用します。
しかしながら、この方法には欠点が存在します。特に、高速な動きやデバイスの処理速度が遅い場合、キャラクターが壁をすり抜けてしまう問題が生じることがあります。
この記事では、Unityの「Ray」という強力な機能を使用して、この問題を回避する方法を紹介します。初心者の方も、簡単なコードのコピー&ペーストで実装を始めることができます。
1.「Ray」とは。
Unity3Dにおける「Ray」とは、直線の一部として考えることができる仮想的な線のことを指します。この仮想的な線は、ある点から特定の方向に無限に伸びると考えることができます。
Rayは主に、ゲームオブジェクトやシーン内の地形など、他のオブジェクトとの間での交差点(衝突)を検出するために使用されます。
特徴
始点と方向:Rayは始点(origin)と方向(direction)の二つの主要な要素から成り立っています。始点はRayがスタートする3D空間内の座標を示し、方向はそのRayが進むベクトルを示します。
衝突検出:Rayを利用することで、特定の方向に存在するオブジェクトや障害物を検出することが可能です。これは、シューティングゲームでの弾の軌道や、キャラクターの視野をシミュレートする際に特に役立ちます。
高効率:Rayは非常に軽量で効率的な方法で衝突検出を行うため、パフォーマンスに与える影響はほとんどありません。
応用例
Rayは多岐にわたるシチュエーションでの利用が考えられます。
キャラクターの足元の地形の検出:キャラクターが地面に接しているか、空中に浮いているかを判断するためにRayを下方向に放射します。
敵の視野のシミュレーション:敵キャラクターがプレイヤーを視認できるかどうかを判断するためにRayを使用します。
マウスのクリック位置の検出:3D空間内でマウスクリックの位置にあるオブジェクトを検出する際にもRayが用いられます。
総じて、RayはUnity3D開発における強力なツールの一つとして、多くのゲームメカニクスの実現に貢献しています。
2.「Ray」を利用した移動プログラム
下記のプログラムをコピーして作成します。
キャラクターのオブジェクトにアタッチしてください。
インスペクターで、以下の変数を設定します。
speed: プレイヤーの移動速度を数値で設定してください。
playerControls: プレイヤーが使用する移動アクションマップを選択してください。
注意 : アクションマップの設定には、Unityの「Input System」機能の使用が必要です。
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.InputSystem;
[SerializeField] private float speed; // プレイヤーの速度をインスペクターから設定
[SerializeField ]private InputActionMap playerControls; //プレイヤー移動のアクションマップをインスペクターから設定
public class PlayerMove : MonoBehaviour
{
private void Update()
{
Move()
}
public void Move()
{
// 移動方向を計算
Vector3 direction = (transform.forward * playerControls["Move"].ReadValue<Vector2>().y + transform.right * playerControls["Move"].ReadValue<Vector2>().x).normalized;
// Rayの開始位置と方向を設定
Vector3 rayStart = transform.position;
Vector3 rayDirection = direction;
// 移動方向にRayを放射
RaycastHit hit;
float rayDistance = speed + 0.1f; // 少し余裕を持たせるために0.1fを追加
if (!Physics.Raycast(rayStart, rayDirection, out hit, 0.5f))
{
// Rayが何もヒットしない場合、プレイヤーを移動
transform.position += direction * speed;
}
else
{
Debug.Log("当たり判定");
}
// RayをSceneビューで可視化
Debug.DrawRay(rayStart, rayDirection * rayDistance, Color.red);
}
}
3.Unity上で再生してみよう
1.Unity上に障害物となる「Cube」を配置する。
2.unity上で画面中央上部の再生ボタンを押す。
3.キャラを移動させて、障害物に貫通しないか確かめよう。
障害物に貫通せずに移動ができたら、成功!!!