【unity】3D脱出ゲーム作成_その2

3D脱出ゲーム

前回ステージを作成しましたが、ゲームを開始しても当然何もおきません。まずはプレーヤー配置を行います。ただ今回のゲームは主観操作にしたいので、プレーヤー=MainCameraとなります。

その1で作成したステージを配置します。配置位置は自由ですが全てのオブジェクトはステージ内に収める予定なので、Inspector<Transform.Position,Rotation<x,y,zは全て0にします。MainCameraもx,zは同じく0で、yのみ目線の高さに設定します。他にDirectionalLight(太陽の光みたいなもの)もあると思いますが、後々電灯オブジェクトを部屋内に作成するので、部屋の外に移動させるか削除します。因みに位置に関して、2つの定義があるので簡単に記します。

・ワールド基準:シーン全体からみた絶対位置

・ローカル基準:親オブジェクトから見た子オブジェクトの相対位置

主観カメラを回転させる

キーボードの矢印を押すとカメラが回転するようにします。MainCameraに以下のスクリプトをアタッチしました。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerCamera : MonoBehaviour
{
    float _inputX, _inputY;

    void Start()
    {  
    }
    void Update()
    {
        _inputX = Input.GetAxis("Horizontal");
        _inputY = Input.GetAxis("Vertical");
        transform.Rotate(_inputY, _inputX, 0);
    }

これで実行するとキーボードの上下左右の矢印入力でカメラも回転します。Horizontalは上下、Verticalは左右に対応します。なぜ対応するのかはEdit>ProjectSetting>InputManager>Horizontal,Verticalにて設定されているからです(この設定は可変です_*初期設定でVerticalの上はプラスで下はマイナスでしたがこれが世界基準なのかな)。

一応回転はするのですが、プレーヤー=MainCameraという前提からすると、上下の制限がない(プレーヤーの首が上下360度回転)、x,y軸の操作がそれぞれ連動してしまう(プレイヤー目線と体の向きが連動してしまう)といった問題が生じます。

カメラの回転軸を分離して上下制限をつける

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerCamera : MonoBehaviour
{
    [SerializeField]float viewAngle;
    float _inputX, _inputY;

    void Start()
    {  
    }
    void Update()
    {
        _inputX = Input.GetAxis("Horizontal");
        _inputY = Input.GetAxis("Vertical");
        //transform.Rotate(_inputY, _inputX, 0);
        Rotate(_inputX, _inputY, viewAngle);
    }
    void Rotate(float _inputX, float _inputY, float limit)
    {
        float maxLimit = limit, minLimit = 360 - maxLimit;
        //X軸回転_縦回転
        var localAngle = transform.localEulerAngles;
        localAngle.x += _inputY;
        //縦回転制限
        if (localAngle.x > maxLimit && localAngle.x < 180)
            localAngle.x = maxLimit;
        if (localAngle.x < minLimit && localAngle.x > 180)
            localAngle.x = minLimit;
     //制限を加味し反映
        transform.localEulerAngles = localAngle;
        //Y軸回転_横回転
        var angle = transform.eulerAngles;
        angle.y += _inputX;
        transform.eulerAngles = angle;
    }

赤マーカーは削除、青マーカーは追加(//以右はコメント)。[SerializeField]というprivateでありながらInspectorで編集できる変数を追加してます(_inputX, _inputYは通常のprivate)。

既存のtransform.Rotateでは上手くいかなかったので、引数あり(変数を渡す用)のRotateメソッドを追加しました(メソッド名はローマ字であれば何でも構いません)。Rotateメソッドには縦回転、横回転、縦回転制限を定義しました。

縦回転、横回転はEulerAngles(オイラー角)とセットで使う事で分離して処理します。因みにX軸回転でlocalをつけてますが今回のゲームでカメラに角度のある親オブジェクトを設定する予定はないので、外しても問題ないと思います。

縦回転制限は変数viewAngleの値を用いて、上限下限を設定。仮にviewAngle=45とした場合→ 上限45_下限315となります。ゲームを実行しながらこの下限値とInspector<Transform.Rotationの値を見比べて整合しないので混乱しましたが(下限-45じゃないの?といった感じ)、以下の様なルールの違いがあるのだなと無理やり納得しました。

・Transform.Rotation:0〜180(加算)=0〜ー180(減算)

・EulerAngles:0〜360

ゲーム画面になります。既に色々な仕掛けを設置済みですが、次回以降で扱います。

コメント

タイトルとURLをコピーしました