【Unity】敵機捕獲後の自機への追従処理(グラディウスのオプションのようなイメージ)
Captulionでは敵機を捕獲することができますが、捕獲した敵機を自機へ追尾させるための処理についてまとめてみました。
追尾のイメージ
Captulionで敵機を捕獲すると以下の動画のように自機を追尾するようになります。
IMG_3184.TRIM from Kazushige Mori on Vimeo.
敵機の追尾処理について
捕獲した敵機をグラディウスというゲームにでてくるオプションのような動きをさせたかったので、検索してみたところ、とても参考になるgitを見つけましたので、そちらを参考にさせていただき調整することにしました。
#Unity で、プレイヤーを追いかける敵&フォロワー(グラディウスのオプション的なやつ)のサンプルコードを github にあげました。速度指定の強制移動の方式と、フィードバック制御による方式。 https://t.co/OOHeMvqKfN
— Tomo Mizoe (@tmizoe) 2014年11月17日
追尾処理のカスタマイズ
Captulionでは上記の追尾処理を3D用にカスタマイズしています。以下はカスタマイズしたソースコードになります。(参考になったら幸いです。)
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class FollowersController : MonoBehaviour {
public float controlGainP = 1f;
public float controlGainD = 1f;
public GameObject player;
private GameObject _enemy; //instance
private static List<GameObject> _followers = new List<GameObject>();
private List<GameObject> _tmp_Followers = new List<GameObject>();
private float followerVel = 5f;
public float followerDistance = 100f;
public int maxFollowers = 0;
private GameObject[] slaves;
private static List<GameObject> tmp_slaves;
private GameController gameController;
public void resetFollowers() {
slaves = GameObject.FindGameObjectsWithTag ("Slave");
maxFollowers = slaves.Length;
_tmp_Followers = new List<GameObject> ();
for (int i=0; i < slaves.Length;i++) {
_tmp_Followers.Add(slaves[i]);
}
_followers = _tmp_Followers;
}
void Start () {
GameObject gameControllerObject = GameObject.FindGameObjectWithTag ("GameController");
gameController = gameControllerObject.GetComponent<GameController> ();
if (gameController.configMode == true) {
return;
}
PlayerController playerController = player.GetComponent<PlayerController>();
followerVel = playerController.speed;
}
void Update () {
if (gameController.configMode == true) {
return;
}
if (!player) {
player = GameObject.FindWithTag ("Player");
}
if (_followers.Count == 0) {
return;
}
for(int i = 0; i < _followers.Count; i++) {
Vector3 dir;
if (i == 0) {
if (_followers [i] == null) {
resetFollowers ();
break;
} else {
Vector3 playerPosition = new Vector3 (0f, 0f, 0f);
if (player) {
playerPosition = player.transform.position;
}
dir = -1 * _followers [i].transform.position + playerPosition;
}
} else {
if (_followers [i] == null || _followers [i - 1] == null) {
resetFollowers ();
break;
} else {
dir = -1 * _followers [i].transform.position + _followers [i - 1].transform.position;
}
}
if (dir.magnitude > followerDistance) {
_followers [i].GetComponent<Rigidbody> ().velocity = dir.normalized * followerVel; //normalize the direction vector, and get the velocity vector
} else {
_followers [i].GetComponent<Rigidbody> ().velocity = new Vector3 (0f, 0f, 0f);
}
}
}
}