🎮

Unity〜Scene共通のScriptをちょっとだけ分岐する

に公開

一人称視点のオブジェクトを動かすKeyの割り当て

『四次元年表』のために、二つのSceneを作っている。
一つはxz平面上を世界地図に見立てて、y軸を時間軸とする3D空間 Map。
もう一つは三次元空間に地球儀を置いて、地球儀中心から放射状に時間軸を立てる4D空間 Globe。
この中を一人称視点で動く。
Mapでは、時間軸は垂直に立っているので、Keyはこんなふうに割り当てた。

一方、Globeでは、時間軸が放射状なので、斜めってる姿勢がほしい。
で、こうやってみた。

どこが違うか。時計回り、反時計回りが増えている。

もちろん、共通にしたっていい。
だが、この斜めってる姿勢をMapで取ると、けっこうめまいがする。
かといって、斜めってる姿勢なしでは、Globeでうまく動けない。

実際VRでゴーグルかけたらどうなるんだ、という先の話は置いておいて、
ともかく、この二つのKey配分を分岐するには、Scriptはどう書けばいいのか。
もちろん、別々のScriptにしたっていい。
だが、ほとんど一緒なんだから、もったいないでしょう。

ifはどこに書くのか

そもそも
void Startとvoid Updateはどう違うか
も、わかってない状態で開発しているせいなのだが
爺様がいてよかった、と、毎日思っている。
結果として、以下のように書いた。

PlayerManager
using UnityEngine;
using UnityEngine.SceneManagement;

public class PlayerManager : MonoBehaviour
{
    private Rigidbody rb;

    [Header("移動・回転設定")]
    public float moveSpeed = 10f;     
    public float rotationSpeed = 1f;   
    private string currentScene;


    void Start()
    {
        rb = GetComponent<Rigidbody>();

        // シーン名を取得
        string sceneName = SceneManager.GetActiveScene().name;
        
        // 現在のシーン名を取得
        currentScene = SceneManager.GetActiveScene().name;

    }

    void FixedUpdate()
    {
        // --- WASDで水平移動 ---
        if (Input.GetKey(KeyCode.W))
        {
            rb.AddForce(transform.forward * moveSpeed);
        }
        if (Input.GetKey(KeyCode.S))
        {
            rb.AddForce(-transform.forward * moveSpeed);
        }
        if (Input.GetKey(KeyCode.D))
        {
            rb.AddForce(transform.right * moveSpeed);
        }
        if (Input.GetKey(KeyCode.A))
        {
            rb.AddForce(-transform.right * moveSpeed);
        }

        //頭上に進む
        if (Input.GetKey(KeyCode.R))
        {
            rb.AddForce(transform.up * moveSpeed);
        }
        //足下に進む
        if (Input.GetKey(KeyCode.F))
        {
            rb.AddForce(-transform.up * moveSpeed);
        }

        //上を向く
        if (Input.GetKey(KeyCode.U))
        {
            transform.Rotate(-rotationSpeed, 0, 0);
        }
        //下を向く
        if (Input.GetKey(KeyCode.J))
        {
            transform.Rotate(rotationSpeed, 0, 0);
        }
        //右を向く
        if (Input.GetKey(KeyCode.K))
        {
            transform.Rotate(0, rotationSpeed, 0);
        }
        //左を向く
        if (Input.GetKey(KeyCode.H))
        {
            transform.Rotate(0, -rotationSpeed, 0);
        }

        // 右に傾く   <= ここと
        if (currentScene != "WithMap")  Mapの時は無効
        {
            if (Input.GetKey(KeyCode.I))
            {
                transform.Rotate(0, 0, rotationSpeed);
            }
        }

        // 左に傾く  <= ここ
        if (currentScene != "WithMap")  Mapの時は無効
        {
            if (Input.GetKey(KeyCode.Y))
            {
                transform.Rotate(0, 0, -rotationSpeed);
            }
        }

    }

    void Update()
    {

        // WASDのキーを離した際に慣性をリセットする例
        if (Input.GetKeyUp(KeyCode.W) ||
            Input.GetKeyUp(KeyCode.S) ||
            Input.GetKeyUp(KeyCode.A) ||
            Input.GetKeyUp(KeyCode.D) ||
            Input.GetKeyUp(KeyCode.R) ||
            Input.GetKeyUp(KeyCode.F) ||
            Input.GetKeyUp(KeyCode.Y) ||
            Input.GetKeyUp(KeyCode.U) ||
            Input.GetKeyUp(KeyCode.I) ||
            Input.GetKeyUp(KeyCode.H) ||
            Input.GetKeyUp(KeyCode.J) ||
            Input.GetKeyUp(KeyCode.K))
        {
            rb.linearVelocity = Vector3.zero;
        }
    }
}

Key操作が煩雑だからMouseも使えば?

と、爺様はいうのだが、
マウス操作でデータの詳細表示をするので、
競合するというか、動きがギクシャクする。
今回は取りあえず、全部Keyでいく。
右手がKeyとMouseを行ったり来たりすることになるけれども、
基本Rotationは、そんなに頻繁にする操作じゃないと思っているので、大丈夫でしょう。

たぶん。

シューティングゲームみたいなスピード勝負でもないし。
図書館の中は、のんびり静かに移動してほしい。

斜め上に上昇する

Mapの時は傾かないのでR/FKeyは単純に上昇・下降なのだが、
Globeでは、斜めってる時間軸に沿って移動したい。
と思ったら、R/Fに設定した tranceform.up と .downは
上、じゃなく 頭上
下、じゃなく 足下
を最初から設定しているらしい。
ということで、ここは分岐しなくてもいけるらしい。

ビュンッと飛んでくテーツジン♪

誰も知らないだろうな〜。

Discussion