Unityでカーリングゲームを作る #5 手番によってマテリアルの色を変える

投稿者: | 2019-12-26


手番によってストーンのマテリアルの色を変えます。

ストーンのプレハブに付けたスクリプトでストーンのRendererコンポーネントを得ます。

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

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

    public Color color2;

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

        stoneNumber = num;
        if (num % 2 == 1)
        {
            player = false;
            GetComponent<Renderer>().material.color = color2;
        }

        num++;
    }

    // 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;
        }

    }
}

手番はストーンのplayerプロパティで表現されます。デフォルトはtrueで、奇数の手番ではfalseになります。

if (num % 2 == 1)
{
    player = false; // 手番をfalseにする
    GetComponent<Renderer>().material.color = color2; // マテリアルの色を変える
}

%演算子で余りを計算します。2で割って余りが1のときに手番とマテリアルの色を変えます。

publicを付けてColor型の変数を宣言しています。

public Color color2;

すると、インスペクタにカラーピッカーが表示されて好きな色を選択できます。

投げられたストーンの手番をインスペクタで確認してみます。


ピンクのストーンではplayerのチェックが外れていて、グリーンのストーンではチェックが入っています。

スコアを計算する

カーリングでは、ハウスの中にあって中心に一番違いストーンを持つチームだけに、相手のストーンの内側にあるストーンの数の得点が入ります。
前の記事で中心から近い順にストーンを整列させているので、最初のストーンの手番を調べてスコア足し、同じ手番が連続する限りスコアを増加していって、相手の手番のストーンが出たらスコアの計算をやめます。

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


public class HouseScript : MonoBehaviour
{
    bool secondLap = false;
    List<int> stoneNumbers;
    Dictionary<GameObject, float> stonesInHouse;
    public Transform center;
    bool winner;
    int score = 0;

    // Start is called before the first frame update
    void Start()
    {
        stoneNumbers = new List<int>();
        stonesInHouse = new Dictionary<GameObject, float>();
    }

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

    }

    private void OnTriggerStay(Collider other)
    {
        // ストーンの番号が一巡していないとき
        if (!secondLap && other.CompareTag("Stone"))
        {

            // ストーンの番号がリストにあるとき
            if (stoneNumbers.Count != 0 && stoneNumbers.Contains(other.gameObject.GetComponent<StoneScript>().stoneNumber))
            {
                secondLap = true;
                Score();
            }
            else {// ストーンの番号がリストに無いとき
                Debug.Log(other.gameObject.GetComponent<StoneScript>().stoneNumber);
                stoneNumbers.Add(other.gameObject.GetComponent<StoneScript>().stoneNumber); // 番号をリストに追加する
                stonesInHouse.Add(other.gameObject, Vector3.Distance(other.gameObject.transform.position, center.position)); // オブジェクトと中心までの距離をディクショナリーに追加する
            }
        }

    }

    void Score()
    {
        
        var stoneDic = stonesInHouse.OrderBy((x) => x.Value); // ディクショナリーの値をソートする
        int n = 0;
        foreach (KeyValuePair<GameObject, float> stone in stoneDic)
        {
            StoneScript sc_stone = stone.Key.GetComponent<StoneScript>();

            //Debug.Log(stone.Key.transform.position.ToString() + " " + stone.Value.ToString() + " " + stone.Key.GetComponent<StoneScript>().stoneNumber);


            if (n == 0)
            {
                winner = sc_stone.player; // 中心に一番近いストーンの手番を勝者にする
                score++; // スコアに1を足す
            }
            else if (sc_stone.player == winner)
            {

                score++; // 続くストーンの手番が勝者と同じであればスコアに1追加
            }
            else if (sc_stone.player != winner)
            {
                break; // 勝者と同じでなければスコアの計算を終える
            }

            n++;

        }

        Debug.Log("winner:" + winner + " score:" + score);
        
    }

}


中心に一番違いストーンはピンク(false)なので、勝者はfalseです。一番内側のグリーンのストーンよりも内側にあるピンクのストーンは2個なので、スコアは2になっています。

コメントを残す

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