2020/11/09
というわけで、今回はUnityに関するちょっとしたお話です。
今作成中のゲームで、「前方3方向に飛ばす遠距離攻撃」というものが欲しくなりました。シューティングゲームでよくある「3WAY弾」のような感じです。
結構前にトライして挫折した経験がありましたが、今回やったら割とあっさりいけたので、備忘録として載せておきます。
前方にオブジェクトを飛ばす仕組みの作成
3方向も何も、真正面にオブジェクトを飛ばす仕組みを作らなければ始まりません。
ということで、まずは飛ばされる側のオブジェクトのスクリプトを作成します。
using UnityEngine; public class ShotTestObject : MonoBehaviour { public float shot_speed; protected Vector3 forward; protected Rigidbody rb; protected GameObject characterObject; void Start() { rb = this.GetComponent<Rigidbody>(); forward = characterObject.transform.forward; } void Update() { rb.velocity = forward * shot_speed; } public void SetCharacterObject(GameObject characterObject) { this.characterObject = characterObject; } }
ポイントはオブジェクトの移動方向 (forward
) をキャラクターのtransform.forward
に設定することです。
これを実現するため、インスタンス生成後にキャラクターオブジェクトの情報を受け取れるようSetCharacterObject()
を用意しておきます。
次にキャラクター側のスクリプトとして、オブジェクトを飛ばす処理を作っておきます。Update()
内で入力判定を行い、Instanciate()
時に飛ばしたキャラクターのインスタンスをセットしています。
using UnityEngine; public class Player { public GameObject shotObject; void Update() { if (Input.GetMouseButtonDown(0)) { GameObject shot = Instantiate(shotObject, transform.position, Quaternion.identity); shot.GetComponent<ShotTestObject>().SetCharacterObject(gameObject); } } }
細かい部分は省略していますが、ここまでで「キャラクター前方にオブジェクトを飛ばす」は達成できるかと思います。
斜め前にオブジェクトを飛ばす仕組みの作成
Quaternionに対してベクトルを掛けると、Quaternionの角度分回転したベクトルを取得することができます。
Quaternion.AngleAxis()
でQuaternionの角度が取得できますが、直接書くと汎用性がなくなってしまうので、Instanciate()
後にキャラクターオブジェクトと合わせて設定するようにします。
using UnityEngine; public class ShotTestObject : MonoBehaviour { public float shot_speed; protected Vector3 forward; protected Quaternion forwardAxis; protected Rigidbody rb; protected GameObject characterObject; void Start() { rb = this.GetComponent<Rigidbody>(); forward = characterObject.transform.forward; } void Update() { rb.velocity = forwardAxis * forward * shot_speed; } public void SetCharacterObject(GameObject characterObject) { this.characterObject = characterObject; } public void SetForwordAxis(Quaternion axis) { this.forwardAxis = axis; } }
using UnityEngine; public class Player { public GameObject shotObject; void Update() { if (Input.GetMouseButtonDown(0)) { CreateShotObject(0); CreateShotObject(30f); CreateShotObject(-30f); } } private void CreateShotObject(float axis) { GameObject shot = Instantiate(shotObject, transform.position, Quaternion.identity); var shotTestObject = shot.GetComponent<ShotTestObject>(); shotTestObject.SetCharacterObject(gameObject); shotTestObject.SetForwordAxis(Quaternion.AngleAxis(axis, Vector3.up)); } }
これと前方に飛ばすロジックと合わせて使うと3WAY弾が実現できます。
実際にゲームに組み込んでみると下のような感じ。
GIFアニメーションでは分かりにくいですが、しっかり3方向にでていますね!
前強引に作ったロジックはキャラクターの向きに依存していましたが、それもなさそうです。