Unityでチャージショットを撃ってみます。
マウス左クリックを押すとチャージが始まって、離すと発射します。
Sphereオブジェクトをプレハブ化して、Rigidbodyをつけます。
以前の記事で作ったカメラの方向へ玉を飛ばすスクリプトを修正して、空のゲームオブジェクトに付けます。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ThrowBallScript2 : MonoBehaviour
{
public GameObject ball;
public float thrust = 10f;
Vector3 cursorPosition;
Vector3 cursorPosition3d;
RaycastHit hit;
Vector3 cameraPosition;
Rigidbody rb_ball;
float power;
MeshRenderer ballMeshRenderer;
Color ballColor;
// Start is called before the first frame update
void Start()
{
power = 0f;
ballColor = new Color(0f, 0.2f, 0.2f);
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0)) // マウスの左クリックをしたとき
{
rb_ball = Instantiate(ball, Camera.main.transform.position + ThrowDirection() / 4f, transform.rotation).GetComponent<Rigidbody>(); // 玉を生成
ballMeshRenderer = rb_ball.GetComponent<MeshRenderer>();
rb_ball.isKinematic = true;
StartCoroutine("ChargeUp");
}
else if (Input.GetMouseButtonUp(0))
{
StopCoroutine("ChargeUp");
rb_ball.isKinematic = false;
rb_ball.AddForce(ThrowDirection() * thrust * power, ForceMode.Impulse); // カーソルの方向に力を一度加える
power = 0f;
}
}
Vector3 ThrowDirection() // ボールを投げる方向を計算する
{
cameraPosition = Camera.main.transform.position; // カメラの位置
cursorPosition = Input.mousePosition; // 画面上のカーソルの位置
cursorPosition.z = 10.0f; // z座標に適当な値を入れる
cursorPosition3d = Camera.main.ScreenToWorldPoint(cursorPosition); // 3Dの座標になおす
return cursorPosition3d - cameraPosition; // 玉を飛ばす方向
}
IEnumerator ChargeUp()
{
while (true)
{
power += 0.03f;
ballColor.r = power;
ballMeshRenderer.material.SetColor("_BaseColor",ballColor);
if (power >= 1f)
{
yield break;
}
yield return new WaitForSeconds(0.01f);
}
}
}
コルーチンを使う
マウスをクリックしたときに、カーソルがある方向へ玉を生成して、isKinematicをTrueにして静止させておきます。
この時に、玉の色を変えるためにメッシュレンダラーコンポーネントを取得しておきます。
rb_ball = Instantiate(ball, Camera.main.transform.position + ThrowDirection() / 4f, transform.rotation).GetComponent<Rigidbody>(); // 玉を生成
ballMeshRenderer = rb_ball.GetComponent<MeshRenderer>();
rb_ball.isKinematic = true;
そして、コルーチンを開始して、その中でpowerの値を増加させます。
IEnumerator ChargeUp()
{
while (true)
{
power += 0.03f;
ballColor.r = power;
ballMeshRenderer.material.SetColor("_BaseColor",ballColor);
if (power >= 1f)
{
yield break;
}
yield return new WaitForSeconds(0.01f);
}
}
増加した値を玉の色のR値に入れることで、チャージ中に溜まったパワーに合わせて玉の色が赤くなっていきます。
powerが1以上になるとコルーチンが終了します。
マウスを離すと、isKinematicをfalseにしてから、その時点のpower値を使って玉を前に飛ばします。
StopCoroutine("ChargeUp");
rb_ball.isKinematic = false;
rb_ball.AddForce(ThrowDirection() * thrust * power, ForceMode.Impulse); // カーソルの方向に力を一度加える
power = 0f;
玉に与えるベクトルにpowerをかけていますが、powerは最大で1なので、変数thrustに設定した値が玉に与える力の最大値です。