【Unity覚書】FPS視点の探索ゲームで、アイテムを拾う機能の実装
スポンサードリンク
こんにちは。ふぁんたです。
Unityでゲームを作ろうとしたときに、タイトルのような、アイテムを拾う機能を実装したいなと思いまして。
でも、標準アセットに入ってるFPSControllerにはアイテムに近づいて拾うなんてボタンの実装はないのです。
そこで、実装することを考えました。
以下、やってみた部分の覚書になります。
やったことの目次を貼ります。
いらんかったので消しました。
やり方は、FPSControllerのPrefabをScene上に配置して、そのObjectのInspector欄(物理とか衝突判定とか入れるとこ)のRun Speedの値をWalk Speedと同じ5に、Jump Speedを0に、うるさいと困るのでJump SoundとLand Soundを消しました。
これで、飛びも走れもしない主人公が完成します。
FPSControllerの下に、FirstPersonCharacterっていうオブジェクトがひっついていると思います、ひっついていなかったらひっつけてください。
それがカメラの機能を果たすので、そこからRayを発射させます。
Rayっていうのは、プレイヤーには見えないレーザービームみたいなもので、好きな長さの光線を出して衝突判定を起こすことができます。
アイテムを作って、インスペクタからタグをつけます。タグの名前はItemにしました。
具体的には、どこからでも取り出せるbool値をグローバル変数的に宣言しておいて、updateで毎フレームRayを作り、マウスの位置から80cmの長さ発射して、当たった物体のタグにItemがついていたら、そのbool値をtrueに、そうでない場合は全部falseにするといったような内容です。
光線を受け取る側を考えます。
先程、取り出せるようにとpublicで宣言しておいたboolを取り出し、trueならログを出力するといったような実装をしました。
毎フレーム、bool値を持ってきてその結果によってログを吐いています。
書いている途中に思ったんですけど、カメラから出ているRayで衝突判定の計算とかbool値をtrueにするとかやめて、その判定計算を全部アイテム側にやらせるようにすれば、このスクリプトを「使いたい全てのアイテム」に流用することができるんですね。
ちょっと頭の良くない実装でしたが、書いて晒すことで自戒にも覚書にもなるので残しておきます。
次の実装は、「どのアイテムを取ったかという変数をPlayer側にもたせる」とか、「拾ったアイテムは消す」とか、「この機能をVRでも使えるようにする」とかそういう事を考えています。
VRでRAYやってうまいこと衝突判定できるのか心配ですが…
Unityでゲームを作ろうとしたときに、タイトルのような、アイテムを拾う機能を実装したいなと思いまして。
でも、標準アセットに入ってるFPSControllerにはアイテムに近づいて拾うなんてボタンの実装はないのです。
そこで、実装することを考えました。
以下、やってみた部分の覚書になります。
やったことの目次を貼ります。
ジャンプ機能、走る機能の削除
いらんかったので消しました。
やり方は、FPSControllerのPrefabをScene上に配置して、そのObjectのInspector欄(物理とか衝突判定とか入れるとこ)のRun Speedの値をWalk Speedと同じ5に、Jump Speedを0に、うるさいと困るのでJump SoundとLand Soundを消しました。
これで、飛びも走れもしない主人公が完成します。
カメラにRayを飛ばす機能を実装
FPSControllerの下に、FirstPersonCharacterっていうオブジェクトがひっついていると思います、ひっついていなかったらひっつけてください。
それがカメラの機能を果たすので、そこからRayを発射させます。
Rayっていうのは、プレイヤーには見えないレーザービームみたいなもので、好きな長さの光線を出して衝突判定を起こすことができます。
アイテムを作って、インスペクタからタグをつけます。タグの名前はItemにしました。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class rayfromcamera : MonoBehaviour {
public bool itemray;
\t// Use this for initialization
\tvoid Start () {
itemray = false;
\t}
\t
\t// Update is called once per frame
\tvoid Update () {
Ray mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
Debug.DrawRay(mouseRay.origin,mouseRay.direction,Color.red,0.8f);
RaycastHit hit;
if (Physics.Raycast(mouseRay, out hit, 0.8f))
{
if (hit.collider.gameObject.tag == "Item")
{
itemray = true;
}
else
{
itemray = false;
}
}
else
{
itemray = false;
}
}
}
具体的には、どこからでも取り出せるbool値をグローバル変数的に宣言しておいて、updateで毎フレームRayを作り、マウスの位置から80cmの長さ発射して、当たった物体のタグにItemがついていたら、そのbool値をtrueに、そうでない場合は全部falseにするといったような内容です。
Rayと衝突したら何かを行うアイテム側の機能の実装
光線を受け取る側を考えます。
先程、取り出せるようにとpublicで宣言しておいたboolを取り出し、trueならログを出力するといったような実装をしました。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RayHilight : MonoBehaviour {
public bool onhighlight = true;
public GameObject r2;
\t// Use this for initialization
\tvoid Start () {
\t\t
\t}
\t
\t// Update is called once per frame
\tvoid Update () {
rayfromcamera r = r2.GetComponent<rayfromcamera>();
onhighlight = r.itemray;
if (onhighlight)
{
Debug.Log("on it !");
}
\t}
}
毎フレーム、bool値を持ってきてその結果によってログを吐いています。
これから
書いている途中に思ったんですけど、カメラから出ているRayで衝突判定の計算とかbool値をtrueにするとかやめて、その判定計算を全部アイテム側にやらせるようにすれば、このスクリプトを「使いたい全てのアイテム」に流用することができるんですね。
ちょっと頭の良くない実装でしたが、書いて晒すことで自戒にも覚書にもなるので残しておきます。
次の実装は、「どのアイテムを取ったかという変数をPlayer側にもたせる」とか、「拾ったアイテムは消す」とか、「この機能をVRでも使えるようにする」とかそういう事を考えています。
VRでRAYやってうまいこと衝突判定できるのか心配ですが…
スポンサードリンク