【山崎研Tips】Unityの当たり判定:サンプル①接触したブロックが消えて新しいブロックが1つ出現
https://scrapbox.io/files/672da435ed849ce4831f60fd.mp4
1. はじめに
研究室では現在(2024年度)「格闘技を理解するAI」の開発に取り組んでいます。その一環で、柔道の形(かた)のVRトレーニングシステムを開発しています。そのために必要になるUnityでの当たり判定に関して、下記の2つのサンプルを用意しました。
サンプル1:プレーヤーがブロックと接触するとそのブロックが消え、新しいブロックが1つ出現する。(上の動画。このページの内容です。)
※サンプルプロジェクトはドライブの 開発資料\Unity\衝突判定サンプルに置いてあります。
2. 参考
3. Unityの衝突判定
プレーヤーとブロックとの当たり判定には、Unityでは下記の2種類が考えられます。
プレーヤーがブロックと衝突する(跳ね返る、または止まる) → OnCollision を用いる
プレーヤーがブロックをすり抜ける(接触する、領域内に入る) → OnTrigger を用いる
今回はすり抜けを検知したいので、OnTriggerEnter関数を用いています。
以下に具体的な手順を示します。
4. Unityの当たり判定:サンプル①プレーヤーがブロックと接触するとそのブロックが消え、新しいブロックが1つ出現する
4.1 やること
ボール(Player)とブロックの接触を判定する
接触したらブロックが消え、次のブロックが現れる
4.2 手順
https://gyazo.com/997b4dc75bdb657cc3a9673d528eeada
Step1 判定ブロックとしてCube_0、Cube_1、Cube_2を作成し「Block」タグをつけてPrefab化(Prefabフォルダに入れました)
a. Cube_0、Cube_1、Cube_2は「Transform」からそれぞれX=2, 4, 6の位置に指定してます
Hierarchy ウィンドウで右クリック →「3D Object」 →「Cube」でCubeを作成
名前を変更(Cube_0、Cube_1、Cube_2)
https://gyazo.com/9339f902e1f8bf704250c020c4896017
Inspectorウィンドウの「Transform」の「Position」で位置を指定
Cube_0 → X=2
Cube_1 → X=4
Cube_2 → X=6
https://gyazo.com/3d8bb121d58eeec4e7439280c4a3f7de
Inspectorウィンドウの「Tag」の▼をクリック→「Add Tag…」から「Block」タグを追加
https://gyazo.com/29c2a072a40d6f32126ed600d7eda120
「+」をクリックして「New Tag Name」に「Block」と記入しSave
https://gyazo.com/0fd5f8b15b8cbb55ed2dec857846a73a
Blockタグが選択できるように
https://gyazo.com/4d874487006350c7b090aad2c068583d
b.(サンプルではMaterialを用意してCubeの色を変えてます。やらなくてもよいです)
c. Prefabsフォルダ内にCube_0、Cube_1、Cube_2をPrefab化
https://gyazo.com/8abd35e5a5677c825da77512fa7f9b60
Step2 BlockSpawn.csを作成し、GameObject(空のオブジェクト)に追加
空のオブジェクトを作成
Hierarchyウィンドウで右クリック→「Create Emputy」で空のオブジェクトを作成→名前を 「BlockManager」に
BlockManagerにBlockSpawner.csをアタッチ
BlockManagerをクリックし(下図①)、Inspector のPrefab Array のサイズを「3」に指定(下図②)
「▼Prefab Array」の「▼」を開き(下図③)、各ElemetにCubeのPrefabを指定(下図④)
https://gyazo.com/af4c26abbb3c632a65a92f613e60681f
BlockSpawner.cs
code:BlockSpawn.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BlockSpawn : MonoBehaviour
{
public static BlockSpawn instance;
public GameObject[] prefabArray;
public void Awake()
{
if(instance == null)
{
instance = this;
}
}
void Start()
{
}
public void Generate()
{
if(PlayerScript.instance.count < 3)
{
}
}
}
Step3 Sphere(プレーヤー)を作成
a. リジッドボディを追加する(重力は使用しない。「Use Gravity」のチェックを外す)
b. 当たり判定としてTriggerを使用するため、「Is Trigger(トリガーにする)」にチェックを入れる
https://gyazo.com/6fdd6b7f7c56af21497174a1062fed7f
Step4 PlayerScript.csを作成し、Sphereに追加
code:PlayerScript.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerScript : MonoBehaviour
{
public static PlayerPlayerScript instance;
public int count;
public void Awake()
{
if(instance == null)
{
instance = this;
}
}
// Update is called once per frame
void Update()
{
float x = Input.GetAxisRaw("Horizontal") * Time.deltaTime * 2;
transform.position += new Vector3(x, 0, 0);
if (Input.GetKey(KeyCode.LeftShift))
{
transform.Translate(-0.1f, 0f, 0f);
}
if (Input.GetKey(KeyCode.RightShift))
{
transform.Translate(0.1f, 0f, 0f);
}
}
void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag("Block"))
{
Destroy(other.gameObject);
count++;
BlockSpawn.instance.Generate();
}
}
}
以上です。細かいところは参考サイトを見ればできるかと。ボールは十字キーで動くようにしています。これを元にしてボールをプレヤーに変えれば形判定システムができるはずです。 https://gyazo.com/71c7de59f100448c29cdb7f29fbd171b