見出し画像

character controllerを使ってプレイヤーを動かしている場合は、transformの値を直接変更してワープ処理などを行う時は注意が必要!

自分が作っているTPSゲームで、ワープさせる処理をした時にある注意点があったのでメモとして残しておきます。プレイヤーにキャラクターコントローラー(以下キャラコン)のコンポーネントがついているのですが、キャラコンはどーやらtransformの値を使っているらしく、キャラコンがついたオブジェクトに、他のスクリプトでtransformの値を直接変更してもすぐに上書きされてしまうようです。

だめなコード

private IEnumerator WarpAndFreeze()
    {
        isWarp = true;

        // プレイヤーを動けなくする処理
        Debug.Log("Player frozen for 1 second");
        yield return new WaitForSeconds(_freezeTime);

        // プレイヤーをWarpPoint2に瞬間移動させる
        GameObject warpPoint2 = GameObject.FindGameObjectWithTag("WarpPoint2");
        if (warpPoint2 != null)
        {
            //ワープ先のオブジェクトの少し上にワープ
            Vector3 newPosition = warpPoint2.transform.position;
            newPosition.y += 0.1f; // y軸方向に0.1上に移動

            transform.position = newPosition;
            //移動先のオブジェクトの回転にプレイヤーも合わせる
            transform.rotation = warpPoint2.transform.rotation;

            // 移動後も1秒間動けない
            yield return new WaitForSeconds(_freezeTime);
        }

        isWarp = false;
        //ワープインターバル
        isWarpinterval = true;
        yield return new WaitForSeconds(_Warpinterval);
        isWarpinterval = false;
    }

こちらのコードでは、WarpPoint2というタグがついたオブジェクトに瞬間移動する処理がされていますが、プレイヤーにキャラコンがついているので、このままだと、ワープはしますが、一瞬で元いた場所に戻されてしまいます。
ではどーするかというと、答えは簡単で、ワープする時だけキャラクターコントローラーを無効化すればいいのです。

良いコード

private IEnumerator WarpAndFreeze()
    {
        isWarp = true;

        // プレイヤーを動けなくする処理
        Debug.Log("Player frozen for 1 second");
        yield return new WaitForSeconds(_freezeTime);

        // プレイヤーをWarpPoint2に瞬間移動させる
        GameObject warpPoint2 = GameObject.FindGameObjectWithTag("WarpPoint2");
        if (warpPoint2 != null)
        {
            //一旦キャラクターコントロールを無効化する
            _characterController.enabled = false;
            //ワープ先のオブジェクトの少し上にワープ
            Vector3 newPosition = warpPoint2.transform.position;
            newPosition.y += 0.1f; // y軸方向に0.1上に移動

            transform.position = newPosition;
            //移動先のオブジェクトの回転にプレイヤーも合わせる
            transform.rotation = warpPoint2.transform.rotation;

      
            // 移動後も1秒間動けない
            yield return new WaitForSeconds(_freezeTime);
        }

        // CharacterControllerコンポーネントを有効化する
        _characterController.enabled = true;
        isWarp = false;
        //ワープインターバル
        isWarpinterval = true;
        yield return new WaitForSeconds(_Warpinterval);
        isWarpinterval = false;
    }

_characterController.enabled = false;で、キャラコンを一時的にとめ、ワープが終わったら再びtrueにしています。これでしっかりワープ処理がされます。


この記事が参加している募集

ゲームの作り方

この記事が気に入ったらサポートをしてみませんか?