スワイプ・フリックした向きへLookAtさせる(カメラと相対的に)

Pirate Ships Pack MTSの帆船でLookAt1

上下左右にスワイプ・フリックした時に、カメラと相対的な「奥前左右」にキャラクターの向きを変える。
カメラのRotation(Y軸のみ抽出)を入力座標に掛けて、相対的にするのがコツ。

解説

  1. スワイプ・フリックのデルタ値を、真上から見た形のワールド座標に変換。
  2. カメラのRotationからY軸のみ抽出。
  3. 入力した方向と、カメラのRotation(Y軸のみ)とを合わせた向きに、LookAtさせる。
  • 短いコードで、PCとスマホ両方に対応する為、Input.GetTouchでなく、Input.GetMouseを使用。

コード

GameManager的な物

GameManager的な物に、これを記述。



//向きを変えたいキャラクターにアタッチしたメインスクリプトを紐付け。
//ここでは仮にPlayerとしておく。
	[SerializeField]
	Player player;

	Vector2 beganTouchPosition;
	Vector2 endedTouchPosition;
	Vector2 direction;


	void Update () {
		CheckTouch();
	}

	void CheckTouch () {
 		if (Input.GetMouseButtonDown(0)) {
			beganTouchPosition = Input.mousePosition;
		}

 		if (Input.GetMouseButtonUp(0)) {
  			endedTouchPosition = Input.mousePosition;
    		
//スワイプ・フリックした向きを計算。
			direction = endedTouchPosition - beganTouchPosition;
//スクリーン座標の上下左右を、ワールド座標の奥前左右に修正。
  			player.StartLookAt(new Vector3(direction.x, 0, direction.y);
		}
	}

Player

Playerのメインスクリプトに、これを記述。



//向きの変更は、短時間で連発する事が予想されるので、StopCoroutine出来るように、きちんと管理する。
    Coroutine lookAt;

//カメラのRotationを直接使うと、X、Z軸の回転が余計になる為(Z軸は余り使わないと思うが)、除外する。
    Quaternion mainCameraRotationIgnoreXZ;

//LookAtのスピード。大きい程早くなる。
    float lookAtRate = 0.1f;

//経過時間。
    float elapsedTime = 0;

//LookAtが継続する任意の長さ。LookAtのスピードはlookAtRateで管理しているので、「向き終わった瞬間」と一致しないので注意。
    float duration = 0.5f;

//毎回Camera.main.transformから読み取ると負荷になるので、初期化時に保持しておく。
    Transform mainCameraTransform;



    void Awake () {
        mainCameraTransform = Camera.main.transform;
    }

    public void StartLookAt (Vector3 direction) {

//連続して使う場合は、前のコルーチンを止める。
//このコードではnullを代入しなくても大丈夫だが一応完全に止めている。
        if (lookAt != null) {
            StopCoroutine(lookAt);
            lookAt = null;
        }


        lookAt = StartCoroutine("LookAt", direction);
    }

    IEnumerator LookAt (Vector3 direction) {

        elapsedTime = 0;
        mainCameraRotationIgnoreXZ = new Quaternion(0, mainCameraTransform.rotation.y, 0, 0);


        while (true) {
            elapsedTime += Time.fixedDeltaTime;

//入力された方向に、一定の速度で向き続ける。
//Rigidbodyがアタッチされているなら、transform.rotationでなく、rigidbody.rotationの操作に変更した方が良い。
            transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(mainCameraRotationIgnoreXZ * direction, Vector3.up), lookAtRate);

            if (duration < elapsedTime) {

                yield break;
            }

            yield return new WaitForFixedUpdate();
        }
    }

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