敵のストーンが自動で発射されるようにします。
まず石のプレハブに付けたスクリプトで、最新の石が動きを止めるとゲームの状態が3になるようにしました。
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;
public static int gameState = 0;
// 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++;
gameState = 1;
}
// Update is called once per frame
void Update()
{
if (stoneState == 1 && rb.velocity != Vector3.zero)
{
stoneState = 2;
gameState = 2;
}
if (stoneState == 2 && rb.velocity == Vector3.zero)
{
stoneState = 3;
gameState = 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<Rigidbody> stones;
bool stoneEnter = false;
//bool stoneExit = false;
public GameObject mainCamera;
public GameObject lookDownCam;
public GameObject house;
StoneScript sc_stone;
bool mouseButtonDown;
//public static bool moving = false;
// Start is called before the first frame update
void Start()
{
groundPlane = new Plane(Vector3.up,0f);
stones = new List<Rigidbody>();
stones.Add(Instantiate(stone, new Vector3(42f, 3f, 0f), Quaternion.Euler(0f, 0f, 0f)).GetComponent<Rigidbody>());
mouseButtonDown = false;
StoneScript.num = 0;
StoneScript.gameState = 0;
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0) && StoneScript.gameState == 1 && stones[stones.Count - 1].GetComponent<StoneScript>().player) // 左クリックを押した時
{
downPosition3D = GetCursorPosition3D();
mouseButtonDown = true;
}
else if (Input.GetMouseButtonUp(0) && mouseButtonDown && StoneScript.gameState == 1) // 左クリックを離した時
{
mouseButtonDown = false;
upPosition3D = GetCursorPosition3D();
if (stones.Count != 0 && downPosition3D != ray.origin && upPosition3D != ray.origin && stones[stones.Count - 1].GetComponent<StoneScript>().stoneState == 0 && downPosition3D != upPosition3D)
{
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))
{
//currentStone = Instantiate(stone, new Vector3(42f, 3f, 0f), Quaternion.Euler(0f, 0f, 0f));
//SceneManager.LoadScene("curling");
//stones.Add(currentStone);
stones.Add(Instantiate(stone, new Vector3(42f, 3f, 0f), Quaternion.Euler(0f, 0f, 0f)).GetComponent<Rigidbody>());
}*/
if (stoneEnter)
{
stoneEnter = false;
foreach (Rigidbody stone in stones)
{
if (stone.velocity != Vector3.zero && stone.transform.position.x > -13f)
{
stoneEnter = true;
}
}
if (!stoneEnter) // 全てのストーンが止まっているとき
{
mainCamera.SetActive(true);
lookDownCam.SetActive(false);
}
}
if (StoneScript.num == 8 && StoneScript.gameState == 3)//Input.GetKeyDown(KeyCode.Space)
{
StoneScript.gameState = 4;
house.SetActive(!house.activeSelf);
}
if (StoneScript.gameState == 3)
{
StoneScript.gameState = 0;
SpawnStone(); // ストーンを出現させる
}
if (StoneScript.gameState == 4 && Input.GetKeyDown(KeyCode.R))
{
SceneManager.LoadScene("curling");
}
}
Vector3 GetCursorPosition3D()
{
ray = Camera.main.ScreenPointToRay(Input.mousePosition); // マウスカーソルから、カメラが向く方へのレイ
groundPlane.Raycast(ray, out rayDistance); // レイを飛ばす
return ray.GetPoint(rayDistance); // Planeとレイがぶつかった点の座標を返す
}
private void OnTriggerEnter(Collider other)
{
stoneEnter = true;
mainCamera.SetActive(false);
lookDownCam.SetActive(true);
//Debug.Log("enter");
}
public void SpawnStone()
{
if (StoneScript.num % 2 == 1)
{ // 相手の手番
stones.Add(Instantiate(stone, new Vector3(42f, 3f, 0f), Quaternion.Euler(0f, 0f, 0f)).GetComponent<Rigidbody>());
StartCoroutine("autoThrow");
}
else { // 自分の手番
stones.Add(Instantiate(stone, new Vector3(Random.Range(37f,47f), 3f, Random.Range(-10f,10f)), Quaternion.Euler(0f, 0f, 0f)).GetComponent<Rigidbody>());
}
}
private IEnumerator autoThrow()
{
yield return new WaitForSeconds(1.0f);
sc_stone = stones[stones.Count - 1].GetComponent<StoneScript>();
if (sc_stone.stoneState == 0 && !sc_stone.player)
{
float power = 4.5f;
if (Random.Range(0, 5) == 0)
{
power = 10f;
}
stones[stones.Count - 1].GetComponent<Rigidbody>().AddForce(new Vector3(-1f, 0f, Random.Range(-0.02f, 0.02f)) * Random.Range(25f, 28f) * power, ForceMode.Impulse);
stones[stones.Count - 1].GetComponent<StoneScript>().stoneState = 1;
}
}
}
ストーンを投げるスクリプトで、ゲームの状態が3のときにストーンを出現させます。
if (StoneScript.gameState == 3)
{
StoneScript.gameState = 0;
SpawnStone(); // ストーンを出現させる
}
StoneScriptの静的プロパティの番号で手番を確認して、相手の時は自動でストーンを動かすためのコルーチンをスタートしています。
public void SpawnStone()
{
if (StoneScript.num % 2 == 1)
{ // 相手の手番
stones.Add(Instantiate(stone, new Vector3(42f, 3f, 0f), Quaternion.Euler(0f, 0f, 0f)).GetComponent<Rigidbody>());
StartCoroutine("autoThrow");
}
else { // 自分の手番
stones.Add(Instantiate(stone, new Vector3(Random.Range(37f,47f), 3f, Random.Range(-10f,10f)), Quaternion.Euler(0f, 0f, 0f)).GetComponent<Rigidbody>());
}
}
自分のストーンを投げるときは、クリックする位置を覚えて真ん中を狙うことは簡単なので、スポーン位置をランダムにしました。
自動でストーンを投げるコルーチンでは、相手のストーンがたまに強く発射されるようにしました。
private IEnumerator autoThrow()
{
yield return new WaitForSeconds(1.0f);
sc_stone = stones[stones.Count - 1].GetComponent<StoneScript>();
if (sc_stone.stoneState == 0 && !sc_stone.player) // 最新のストーンがまだ発射されていなくて、手番が相手のとき
{
float power = 4.5f;
if (Random.Range(0, 5) == 0)
{
power = 10f;
}
stones[stones.Count - 1].GetComponent<Rigidbody>().AddForce(new Vector3(-1f, 0f, Random.Range(-0.02f, 0.02f)) * Random.Range(25f, 28f) * power, ForceMode.Impulse);
stones[stones.Count - 1].GetComponent<StoneScript>().stoneState = 1;
}
}