弓をマウスで引っ張って矢を飛ばす。Part1.弓の弦を引っ張る|Unityゲーム制作

今回はUnityで「弓で矢を飛ばす」のを実装してみます。マウスで弓を引き、離した時に矢を撃つ感じです。Part1では弓の弦を引っ張るのを実装していきます。

はじめに

Unityのヴァージョンは2022.3.14f1です。下記、2つの画像を利用していきます。私がInkscapeで簡単に作成したものです。

実装開始

ここから実際に作成していきます。

弓の弦を作成

まずは、弓の弦を作成していきます。弓の画像を画面にセットします。

弓の配下に「空オブジェクト」を追加して名前をstring1とし、LineRendrerを追加します。

LineRendererは下記のようにサイズ、Width、色、マテリアルを変更します。

下記のようにLineRendererで弓の弦を作成することが出来ます。

弦をスクリプトで実装

弓の配下に「空オブジェクト」を2つ追加して、位置を弓の上下に配置します。

string1の座標をリセットしておきます。

下記スクリプトを作成します。

using UnityEngine;

public class Bow : MonoBehaviour
{
    [SerializeField] private GameObject Top;
    [SerializeField] private GameObject Bottom;
    [SerializeField] private LineRenderer String1;

    void Start()
    {
        Vector2 TopPos = Top.transform.position;
        Vector2 BottomPos = Bottom.transform.position;

        String1.SetPosition(0, TopPos);
        String1.SetPosition(1, BottomPos);
    }
}

弓にスクリプトを追加して、パラメータをセットします。

実行して、弦が作成されたらOKです。

マウスで弓を引く

次にマウスで弓を引けるようにします。

まずは、string1をコピーしてstring2を作成、弦の真ん中の位置に空オブジェクトを追加します。

スクリプトを下記に変更します。

using UnityEngine;

public class Bow : MonoBehaviour
{
    [SerializeField] private GameObject Top;
    [SerializeField] private GameObject Bottom;
    [SerializeField] private LineRenderer String1;
    [SerializeField] private LineRenderer String2;
    [SerializeField] private GameObject Anchor;

    private Vector2 startPos;
    private bool isPull;

    void Start()
    {
        isPull = false;
        StringRender(Vector2.zero);
    }

    private void StringRender(Vector2 pos)
    {
        Vector2 TopPos = Top.transform.position;
        Vector2 BottomPos = Bottom.transform.position;

        if (isPull)
        {
            String2.gameObject.SetActive(true);
            String1.SetPosition(0, TopPos);
            String1.SetPosition(1, pos);
            String2.SetPosition(0, pos);
            String2.SetPosition(1, BottomPos);

        }
        else
        {
            String2.gameObject.SetActive(false);
            String1.SetPosition(0, TopPos);
            String1.SetPosition(1, BottomPos);
        }
    }

    void Update()
    {
        Vector2 mousePos = (Vector2)Camera.main.ScreenToWorldPoint(Input.mousePosition);

        if (Input.GetMouseButtonDown(0))
        {
            startPos = mousePos;
            isPull = true;
        }
        else if (Input.GetMouseButton(0))
        {
            Vector2 distance = mousePos - startPos;
            StringRender((Vector2)Anchor.transform.position + distance);
        }
        if (Input.GetMouseButtonUp(0))
        {
            isPull = false;
            StringRender(Vector2.zero);
        }
    }
}

スクリプトの簡単な説明

StringRenderで弦を表示しています。弓を引いてないときはstring1だけでまっすぐな状態、弓を引いてるときはstring1とstring2で「>」の形にしています。

Update内では、マウスを左クリック時に基準となるマウス位置を取得、マウスクリックしたまま動かすと弦の位置を変更、マウスクリックを離した時に初期状態に戻す処理を行っています。

それぞれのパラメータをセットします。

実行して、下記のようにマウスで弓を引けたらOKです。

弦がどこまでも引けてしまうので制限をかけるのを、弓の角度を変えていきます。スクリプトを下記に変更します。startとStringRendererは変更がないので省略してあります。

using UnityEngine;

public class Bow : MonoBehaviour
{
    [SerializeField] private GameObject Top;
    [SerializeField] private GameObject Bottom;
    [SerializeField] private LineRenderer String1;
    [SerializeField] private LineRenderer String2;
    [SerializeField] private GameObject Anchor;

    private Vector2 startPos;
    private bool isPull;
    private float maxString = 1.2f;

    void Update()
    {
        Vector2 mousePos = (Vector2)Camera.main.ScreenToWorldPoint(Input.mousePosition);

        if (Input.GetMouseButtonDown(0))
        {
            startPos = mousePos;
            isPull = true;
        }
        else if (Input.GetMouseButton(0))
        {
            Vector2 distance = Vector2.ClampMagnitude((mousePos - startPos), maxString);
            StringRender((Vector2)Anchor.transform.position + distance);

            float angle = Mathf.Atan2(mousePos.y - startPos.y, mousePos.x - startPos.x);
            transform.rotation = Quaternion.AngleAxis(angle * Mathf.Rad2Deg, Vector3.forward);

        }
        if (Input.GetMouseButtonUp(0))
        {
            isPull = false;
            StringRender(Vector2.zero);
        }
    }
}

実行してみて、下記のように引っ張る限界が出来て、弓の角度が変わればOKです。

Part1では弓の弦を引っ張るここまでとします。Part2では実際に矢を飛ばしていきます。

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