Unity でアーチェリーのメカニクスを実装する

Unity のアーチェリーの仕組みを使用すると、プレイヤーが弓から矢を射ることができる、楽しく魅力的なゲームプレイ体験を作成できます。このチュートリアルでは、弓を引く、照準を合わせる、矢を射るといった基本的なアーチェリーの仕組みの実装について説明します。

1. 弓と矢の準備

まず、簡単な弓と矢のセットアップが必要です。自分でモデル化することも、Unity Asset Store からアセットをダウンロードすることもできます。このチュートリアルでは、弓と矢の 3D モデルが準備されているものと想定します。

2. 弓矢のスクリプトを作成する

弓の引き、照準、射撃の機能を処理する BowAndArrow スクリプトを作成します。

using UnityEngine;

public class BowAndArrow : MonoBehaviour
{
    public GameObject arrowPrefab; // Reference to the arrow prefab
    public Transform bowString; // Reference to the bowstring for drawing
    public Transform spawnPoint; // Point where the arrow will be spawned
    public float drawSpeed = 2f; // Speed at which the bowstring is drawn
    public float maxDrawDistance = 3f; // Maximum draw distance for the bowstring
    public float arrowForce = 50f; // Force applied to the arrow when shot

    private float drawDistance = 0f; // Current draw distance of the bowstring

    void Update()
    {
        // Draw the bowstring when holding the fire button
        if (Input.GetButton("Fire1"))
        {
            DrawBow();
        }

        // Shoot the arrow when the fire button is released
        if (Input.GetButtonUp("Fire1") && drawDistance > 0f)
        {
            ShootArrow();
        }
    }

    void DrawBow()
    {
        // Increase the draw distance while holding the fire button
        drawDistance = Mathf.Clamp(drawDistance + drawSpeed * Time.deltaTime, 0, maxDrawDistance);
        bowString.localPosition = new Vector3(0, drawDistance, 0);
    }

    void ShootArrow()
    {
        // Instantiate and shoot the arrow
        GameObject arrow = Instantiate(arrowPrefab, spawnPoint.position, spawnPoint.rotation);
        Rigidbody arrowRb = arrow.GetComponent();
        arrowRb.AddForce(spawnPoint.forward * arrowForce * drawDistance, ForceMode.VelocityChange);

        // Reset the bowstring
        drawDistance = 0f;
        bowString.localPosition = Vector3.zero;
    }
}

このスクリプトにより、プレイヤーは発射ボタンを押し続けることで弓弦を引くことができ、発射ボタンを放すと矢がインスタンス化され、弓弦を引いた距離に比例した力で発射されます。矢には、弓が向いている方向の速度が与えられます。

3. 矢印プレハブを作成する

次に、プレイヤーが射撃したときにインスタンス化される矢印プレハブを作成します。矢印には、物理​​ベースの動きのための Rigidbody コンポーネントと、オプションで他のオブジェクトと相互作用するための Collider が必要です。

  1. シーンに新しい GameObject を作成し、矢印の 3D モデル (独自のモデルまたは Unity Asset Store のアセット) を追加します。
  2. 物理ベースの動きを実現するために、矢印に Rigidbody コンポーネントを追加します。
  3. 他のオブジェクトとの衝突を処理するために、Collider コンポーネント (BoxCollider や CapsuleCollider など) を追加します。
  4. このゲームオブジェクトをプロジェクト ウィンドウにドラッグしてプレハブにします。

4. 弓を狙う

弓の狙いを定めるには、マウスまたは右サムスティック (ゲームパッドの場合) を使用して簡単なメカニズムを実装できます。この例では、プレイヤーがマウスを使用して弓を回転させて狙いを定めることができるようにします。

using UnityEngine;

public class BowAiming : MonoBehaviour
{
    public float rotationSpeed = 5f; // Speed at which the bow rotates

    void Update()
    {
        // Rotate the bow based on mouse movement
        float horizontal = Input.GetAxis("Mouse X");
        float vertical = Input.GetAxis("Mouse Y");

        transform.Rotate(Vector3.up * horizontal * rotationSpeed);
        transform.Rotate(Vector3.left * vertical * rotationSpeed);
    }
}

BowAiming スクリプトは、マウスの X および Y の動きに基づいて弓を回転させます。これにより、プレイヤーは弓を任意の方向に向けることができます。rotationSpeed を調整して、マウス入力に対する弓の動きの感度を高めることができます。

5. 矢の飛行と衝突の追加

矢の飛行は、矢が発射されたときに力を加える Rigidbody コンポーネントによって処理されます。矢をよりリアルにするには、Arrow スクリプトを追加して衝突を検出し、敵にダメージを与えたり表面にくっついたりといったイベントをトリガーします。

using UnityEngine;

public class Arrow : MonoBehaviour
{
    private void OnCollisionEnter(Collision collision)
    {
        // Check for collision with an enemy or other object
        if (collision.gameObject.CompareTag("Enemy"))
        {
            // Handle damage or effects here
            Debug.Log("Arrow hit the enemy!");
            Destroy(gameObject); // Destroy the arrow on impact
        }
        else
        {
            // Destroy arrow if it hits something else
            Destroy(gameObject, 2f); // Arrow disappears after 2 seconds
        }
    }
}

Arrow スクリプトは、他のオブジェクトとの衝突を検出します。矢が敵に当たると、ダメージやその他の効果をトリガーできます。現時点では、単にメッセージをログに記録して矢を破壊します。このスクリプトを拡張して、ダメージを与えたり、特殊効果を作成したり、矢をオブジェクトに貼り付けたりすることができます。

6. 描画強度のUIの実装

弓がどれだけ引かれたかについてプレイヤーにフィードバックを与えるために、現在の引く強さを示す UI 要素を表示できます。シンプルなスライダーで、弓弦の引く距離を表すことができます。

  1. シーン内に UI スライダーを作成します。
  2. スライダーの値を BowAndArrow スクリプトの drawDistance にリンクします。
using UnityEngine;
using UnityEngine.UI;

public class BowAndArrow : MonoBehaviour
{
    public Slider drawStrengthSlider; // Reference to the UI slider

    void Update()
    {
        if (Input.GetButton("Fire1"))
        {
            DrawBow();
            drawStrengthSlider.value = drawDistance / maxDrawDistance; // Update the slider
        }

        if (Input.GetButtonUp("Fire1") && drawDistance > 0f)
        {
            ShootArrow();
            drawStrengthSlider.value = 0f; // Reset the slider after shooting
        }
    }
}

これは、drawDistance に基づいてスライダーの値を更新することで、プレイヤーが弓をどれだけ引いたかを視覚的に表示します。

7. テストと微調整

次に、ゲームをプレイして弓と矢の仕組みをテストします。次の点を確認してください。

  • 弓弦はスムーズに引かれ、射撃後にリセットされます。
  • 矢印は正しい方向に移動し、衝突に反応します。
  • 照準システムは期待通りに動作し、応答性も良好です。

希望するゲームプレイ感覚に合わせて、drawSpeedarrowForcerotationSpeed などの値を微調整できます。

結論

Unity では、弓、矢の仕組み、照準、射撃を特徴とする、シンプルだが効果的なアーチェリー システムを実装しました。また、引きの強さを示す UI 要素も組み込んでいます。このシステムは、矢の種類、敵の反応、特殊効果などの追加機能で拡張でき、より複雑なアーチェリー体験を実現します。