Unityでカーリングゲームを作る #2 ストーンを複数発射する

投稿者: | 2019-12-23


ストーンを複数発射できるようにします。

まずストーンをプレハブ化して、どれかのキーを押すとストーンのインスタンスを作ります。

ストーンのプレハブにスクリプトを付けました。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class StoneScript : MonoBehaviour
{
    public int stoneState = 0;
    public bool player = true;
    Rigidbody rb;

    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update()
    {

        if (stoneState == 1 && rb.velocity != Vector3.zero)
        {
            stoneState = 2;

        }

        if (stoneState == 2 && rb.velocity == Vector3.zero)
        {
            stoneState = 3;
        }

    }
}

とりあえずストーンのインスタンスごとに状態と手番を設定できるようにしました。インスタンスが作られたときは状態0で、発射されると状態が1になります。
状態が1でストーンの速度が0のときに、ストーンが止まったと判断して状態を2にしたのですが、これだと状態が1になったときにすぐに状態が2になってしまうので、一旦、状態が1でストーンに速度があるときに状態2にして、その後速度が0になったら状態を3にするようにしてみました。

ストーンをはじくスクリプトで、ストーンのインスタンスを作ったり状態を変えたりということをしています。


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class CurlingScript : MonoBehaviour
{
    Plane groundPlane;
    Vector3 downPosition3D;
    Vector3 upPosition3D;

    //public GameObject sphere;
    public float thrust = 3f;

    float rayDistance;
    Ray ray;

    public GameObject stone;
    //GameObject currentStone;

    List<GameObject> stones;

    // Start is called before the first frame update
    void Start()
    {
        groundPlane = new Plane(Vector3.up,0f);

        stones = new List<GameObject>();
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0)) // 左クリックを押した時
        {
            downPosition3D = GetCursorPosition3D();
        }
        else if (Input.GetMouseButtonUp(0)) // 左クリックを離した時
        {
            upPosition3D = GetCursorPosition3D();

            
            if (stones.Count != 0 && downPosition3D != ray.origin && upPosition3D != ray.origin && stones[stones.Count - 1].GetComponent<StoneScript>().stoneState == 0)
            {
                stones[stones.Count - 1].GetComponent<Rigidbody>().AddForce((downPosition3D - upPosition3D) * thrust, ForceMode.Impulse); // ストーンをはじく
                stones[stones.Count - 1].GetComponent<StoneScript>().stoneState = 1;
            }
        }

        // ストーンを出現させる
        if(Input.GetKeyDown(KeyCode.R) && (stones.Count == 0 || stones[stones.Count - 1].GetComponent<StoneScript>().stoneState != 0))
        {
            stones.Add(Instantiate(stone, new Vector3(42f, 3f, 0f), Quaternion.Euler(0f, 0f, 0f)));

        }

    }

    Vector3 GetCursorPosition3D()
    {
        ray = Camera.main.ScreenPointToRay(Input.mousePosition); // マウスカーソルから、カメラが向く方へのレイ
        groundPlane.Raycast(ray, out rayDistance); // レイを飛ばす

        return ray.GetPoint(rayDistance); // Planeとレイがぶつかった点の座標を返す
            
    }

}

出現させたストーンはリストに追加してきます。

stones = new List<GameObject>();

Rキーを押したときにストーンを出現させます。

// ストーンを出現させる
if(Input.GetKeyDown(KeyCode.R) && (stones.Count == 0 || stones[stones.Count - 1].GetComponent<StoneScript>().stoneState != 0))
{
    stones.Add(Instantiate(stone, new Vector3(42f, 3f, 0f), Quaternion.Euler(0f, 0f, 0f)));
}

ストーンがまだ一つも作られていないか、最新のストーンが発射された後(状態が0でないとき)にストーンのインスタンスを作ります。
最新のストーンはリストの末尾にあります。

ストーンが一度も作られていない時や、最新のストーンが発射された後、次のストーンが作られるまではストーンを発射できないようにしています。

if (stones.Count != 0 && downPosition3D != ray.origin && upPosition3D != ray.origin && stones[stones.Count - 1].GetComponent<StoneScript>().stoneState == 0)
{
    stones[stones.Count - 1].GetComponent<Rigidbody>().AddForce((downPosition3D - upPosition3D) * thrust, ForceMode.Impulse); // ストーンをはじく
    stones[stones.Count - 1].GetComponent<StoneScript>().stoneState = 1; // 状態を1にする
}

コメントを残す

メールアドレスが公開されることはありません。