三角関数で画面端の座標を求める

はじめに

画面端の座標を決めておいてプレイヤーの狙った先の画面端の座標を求める。

方法

yoshipenguins.hatenablog.com

前回の記事の方法で取得した角度をもとにプレイヤーから狙った画面端の座標を三角関数を使って計算する。

スクリプト

public void TakeAim()
{
    // 的の親オブジェクトを回転させる
    var angle = GameManager.Instance.GetHandleAngle();
    _targetRoot.eulerAngles = new Vector3(0, 0, angle);

    // 的とのベクトル差
    var vecDiff = _target.position - transform.position;

    _aimPos = Vector2.one;
    var rad = GameManager.Instance.GetHandleRadian();

    // x座標が画面端だと仮定してy座標を求める
    var limitX = vecDiff.x >= 0 ? _edgeHi.x : _edgeLo.x;
    limitX -= transform.position.x;
    _aimPos.y = limitX * Mathf.Tan(rad);
    if (_aimPos.y <= _edgeHi.y - transform.position.y &&
        _aimPos.y >= _edgeLo.y - transform.position.y)
    {
        _aimPos.x = limitX;
    }
    else
    {
        var limitY = vecDiff.y >= 0 ? _edgeHi.y : _edgeLo.y;
        limitY -= transform.position.y;
        _aimPos.x = limitY / Mathf.Tan(rad);
        _aimPos.y = limitY;
    }

    // プレイヤーの位置を基準にする
    _aimPos += (Vector2)transform.position;
    // 予測した座標を代入
    var pos = new Vector3[] { transform.position, _aimPos };
    _renderer.SetPositions(pos);
}

説明

14行目からの処理が重要。
三角関数から y=xtanθ と式を入れ替えて x=y/tanθ を使い座標を求める。
処理では先にy座標を求める。x座標は画面端だと仮定しlimitXに代入する。この時プレイヤーの座標を引いているのはプレイヤーからみた画面端までのベクトルにするため。


式によって求めたy座標が画面範囲外ならy座標を画面端と決めてx座標を計算する。
そして範囲内の座標を計算できたらプレイヤーの座標を加えて位置を調整する。

おわりに

sinとcosを使う場合は斜辺の長さが必要なのだが長さを計算は処理が重い。斜辺を使わないことで少し行が長くなってしまったが、この処理は毎フレーム行うので効果はあると思う。ただどこかでsin、cos、tanの関数も重いらしいと聞いた。

参考にしたもの

【数学】ゲーム開発で覚えておくべき三角関数の性質 - LIGHT11