青文字は自分で決められる所です。
敵をX軸で移動させる
敵のスプリクト
【前提条件】
・敵はRigidbody2Dが適用されている。
public class Enemy01 : MonoBehaviour
{
//Inspectorで設定する
[Header("移動速度")] public float speed; //敵の移動速度を決めます。
[Header("重力")] public float gravity; //敵にかかる重力を決めます。
//変数の最初状態
private Rigidbody2D rb2d = null; //rb2dはRigidbody2Dで中身は空です。
private rightTleftF = false; //敵(使用した絵)は左向きです。
//初期設定
void Start()
{
rb2d = GetComponent<Rigidbody2D>(); //Rigidbody2Dをrb2dに代入します。
}
//常にループして実行
void FixedUpdate() //
{
float XSpeed = GetXSpeed.Ene01(); //関数GetXSpeed.Ene01()の値をXSpeedに代入する。
rb2d.velocity = new Vector2(XSpeed,-gravity); //Rigidbody2Dのvelocity(力)を設定して動かします。X軸にXSpeedの力、Y軸に設定した重力を掛けます。
}
//向いている方向に合わせて移動速度を変える
private fioat GetXSpeedEne01()
{
if (!rightTleftF) // もし、左向きなら
{
xSpeed = speed; //設定値のspeed通り
}
else //もし、違う場合
{
xSpeed = -speed; //マイナスの力にする。
}
return xSpeed; //GetXSpeedEne01()の値はxSpeedとします。
}
敵が障害物に接触したら、移動方向を変える
【前提条件】
・障害物(壁)にコライダーを設定する。
・障害物にタグを設定する。
・透明の障害物(BoxCollider)を使用する場合、プレイヤーが通り抜け出来るようにする。そのために、BoxColliderのUsed By Effectorにチェックをいれ、Platform Effctor2Dを加えます。そして、Platform Effctor2DのSurface Arc(角度)を0にします。
プレイヤーに障害物接触判定を付けると、通り抜けできません。
・顔の表面にBoxColliderを付け、接触判定をする子オブジェクト(仮名称Trigger)とする。
・初期状態での敵の向きは左向きで作る。
障害物判定にOnTriggerEnter2D(Collider2D collision)を使用しました。
もし、OnCollisionEnter2D(Collision2D collision)を使用したい場合には、オブジェクトにRigidBody 2Dを適用し、重力を0、BodyTipeをKinematicにすることで使用できると思います。
未確認です。
敵のスプリクト
public class Enemy01 : MonoBehaviour
{
//Inspectorで設定する
[Header("移動速度")] public float speed; //敵の移動速度を決めます。
[Header("接触判定")] public EnemyCollisionCheck checkCollision; //class EnemyCollisionCheck 障害物接触判定を使用する
//変数の宣言
private bool rightTleftF = false; //左向き
//常にループして実行
void FixedUpdate() //
{
float XSpeed = speed; //移動速度XSpeedはInspectorのスピード
if (checkCollision.isOn) //checkCollision(EnemyCollisionCheckのこと)の変数isOnがtrue(接触した)の場合
{
rightTleftF = !rightTleftF; //向きは左向き(右向きではない)
}
int xVector = -1; //進行を反転させるための適当な変数(xVector)
if (rightTleftF) //向きは右向き
{
xVector = 1;
//画像の向きを反転する
transform.localScale = new Vector3(-1, 1, 1); //ローカルスケールx軸をマイナスにすると、画像が反転する
}
else
{
transform.localScale = new Vector3(1, 1, 1); //画像を正規に戻す(左向き)
}
rb2d.velocity = new Vector2(xVector*XSpeed, -gravity); //XSpeedにブラスやマイナスにすることで、進行方向を変える
}
障害物接触判定のスプリクト
public class EnemyCollisionCheck : MonoBehaviour
{
//isOnは他でも使用する変数のため、publicにしている。
//ただ、publicにするとInspectorに表示されるので、HideInInspectorで表示しないようにしている。
[HideInInspector] public bool isOn = false; //接触していない
//変数の宣言
private string groundTag = "ground"; //地面に相当するハタイルマップのタグ
private string enemyTag = "enemy"; //敵同士がぶつかった場合のため
private string ObstacleTag = "Obstacle"; //Box Colliderで作った見えない障害物として
//障害物判定
private void OnTriggerEnter2D(Collider2D collision) //侵入を検知します。
{
//相手のタグと名称が一致したら
if (collision.tag == groundTag || collision.tag == enemyTag || collision.tag == ObstacleTag)
{
isOn = true; //接触しました。
}
}
private void OnTriggerExit2D(Collider2D collision) //抜けたことを検知します。
{
if (collision.tag == groundTag || collision.tag == enemyTag || collision.tag == ObstacleTag)
{
isOn = false; //接触を外れました。
}
}
弾を、キーボードのSpaceボタンを押したら発射するようにする
【前提条件】
・撃つ場所を敵に子オブジェクトとして付けます。
・TransformのPositionで発射する場所を調整します。
・弾の画像を準備します。
弾の撃つ方向がいろいろある場合には、その角度にあった画像を準備する必要があります。ここでは、X軸方向だけとします。
敵のスプリクト
キー入力で弾を生成します。
向きによって、弾の形を変えたいので2つ絵を準備します。
public class Enemy01 : MonoBehaviour
{
//Inspectorで設定する
[Header("左弾")] public GameObject tama01; //プレハブ化した左に飛ぶ弾
[Header("右弾")] public GameObject tama02; //プレハブ化した右に飛ぶ弾
//変数の初期状態
private bool rightTleftF = false; //敵は左向きです。
//常にループして実行
void Update()
{
if (Input.GetKeyDown(KeyCode.Spsce)) //スペースキーを押して
{
if (rightTleftF) //左向きなら
{
Instantiate(tama01, shotPoint.position, shotPoint.rotation);
//左向き用の弾tama01でPrefabからオブジェクトの弾を生成し、shotPoint.positionで決めた場所から、shotPoint.rotation向きはそのままで弾を生成します。
}
else
{
Instantiate(tama02, shotPoint.position, shotPoint.rotation);
//右向き用
}
}
}
弾のスプリクト
弾のスプリクトを別にした理由は、別の敵やプレイヤーにも実装できるようにするためです。
弾の移動は、フレームが変わる毎に移動する量で制御してます。
射程距離は、フレームの表示回数で決めています。
【前提条件】
・弾にCollider(BoxやCircle等)を付ける。
・弾にRigidBody2Dを適用し、重力を0にする。
弾にRigidBody2Dを適用しないと、OnCollisionEnter2Dが使用できない。
・弾が当たった相手が識別できるように、オブジェクトのタグを決める。
【弾の仕様】
・射程距離有効時、射程に達したら弾は削除される(消える)。
・射程距離無効時は、障害物に当たるまで消えない。
・弾は障害物(壁、プレイヤー等)に当たったら削除される。
public class Tama01 : MonoBehaviour
{
//設定値
[Header("弾の速度")] public float dspeed; //弾の移動速度
[Header("射程距離")] public int range; //弾が飛べる範囲
[Header("射程設定有効")] public bool isRange; //射程距離を有効にするか決めるチェックボックス
//変数宣言
private int ofT = 0; //射程距離の回数
private string playerTag = "Player"; //プレイヤーを認識するためのタグ
private string groundTag = "ground"; //地面を認識するためのタグ
private bool isHit = false; //弾が当たっていない
void Update()
{
if (!isHit) //弾が当たっていない場合
{
if (isRange == true) //射程距離を設定する場合
{
if (range >= ofT) //射程表示回数より回数が少ない場合
{
transform.position += new Vector3(-dspeed, 0, 0); //飛び続ける
ofT += 1;
}
else //射程よりオーバーしたら
{
Destroy(this.gameObject); //弾を削除
}
}
else
{
//射程を設定していない場合
transform.position += new Vector3(-dspeed, 0, 0);
}
}
else //弾が当たった場合
{
Destroy(this.gameObject); //弾を削除
}
}
//衝突判定
private void OnCollisionEnter2D(Collision2D collision) //物体が衝突した時に呼ばれる。衝突データを取得します。
{
if (collision.collider.tag == playerTag || collision.collider.tag == groundTag) //collision.colliderは衝突相手を取得する
{
isHit = true; //弾が当たった
}
}
プレイヤーが敵の射程距離(間合い)に入ったら弾を撃ち、プレイヤーが死んだらやめる
敵のスプリクト
【前提条件】
・敵の移動、方向転換、弾りスプリクトは上文を参照。
public class Enemy01 : MonoBehaviour
//Inspectorで設定
[Header("左弾")] public GameObject tama01; //プレハブ化した左に飛ぶ弾
[Header("右弾")] public GameObject tama02; //プレハブ化した左に飛ぶ弾
[Header("弾の発射位置")] public Transform shotPoint; //敵につけた弾の発射位置
[Header("プレイヤー")] public GameObject target; //対象とするオブジェクト
[Header("敵との距離")] public float maai; //間合い
[Header("生死を確認する相手")] public Player pDeath; //生死を確認する相手(プレイヤー)
//変数の宣言
private bool rightTleftF = false; //左向き
private bool playerDeath = false; //プレイヤーは生きている
void Start() //弾の連射
{
InvokeRepeating("Shot", 1f, 1.5f); //弾の生成(Shot)を1秒後に1.5秒間隔で実行する
}
// 弾を生成する
void Shot()
{
playerDeath = pDeath.PlayerDeath(); //プレイヤーの生死確認
if (!playerDeath) //プレイヤーが生きている
{
if (PlayerDistance() <= maai) //プレイヤーが間合いに入った場合
{
if (!rightTleftF && PlayerRed() >= 170f && PlayerRed() <= 180f)
//左向きの敵からみて、プレイヤーが180~170度の間にいる場合
{
Instantiate(tama01, shotPoint.position, shotPoint.rotation); //左弾を生成する
//プレハブを生成し、発射位置と発射向きを取得する
//弾の速度はTama01で設定している
}
else if (rightTleftF && PlayerRed() <= 10f && PlayerRed() >= 0f)
//右向きの敵からみて、プレイヤーが0~10度の間にいる場合
{
Instantiate(tama02, shotPoint.position, shotPoint.rotation); //右弾を生成する
}
}
}
}
//プレイヤーの角度を知る
private float PlayerRed() //プレイヤーの角度
{
Vector2 p1 = transform.position; //敵の位置を取得
Vector2 p2 = target.transform.position; //プレイヤーの位置を取得
float dx = p2.x - p1.x; //x座標の差
float dy = p2.y - p1.y; //y座標の差
float rad = Mathf.Atan2(dy, dx); //xy直行座標における(x,y)の偏角を計算します。
return rad * Mathf.Rad2Deg; //ラジアンから度に変換する
}
private float PlayerDistance() //プレイヤーとの距離
{
Vector2 p1 = transform.position; //敵の位置を取得
Vector2 p2 = target.transform.position; //プレイヤーの位置を取得
float dx = p2.x - p1.x; //x座標の差
return Mathf.Abs(dx);
}
プレイヤーのスプリクト
【前提条件】
・プレイヤーは、弾に当たった、敵に接触した場合、死亡する。
・衝突する相手のタグを設定する。
//プレイヤーの生死確認
public class Player : MonoBehaviour
{
//衝突判定用変数宣言
private string enemyTag = "enemy"; //敵を認識するためのタグ
private string tamaTag = "tama"; //弾を認識するためのタグ
private bool isDown = false; //プレイヤーはダウンしていない
public bool playerDeath = false; //プレインーは死んでない
//衝突判定
private void OnCollisionEnter2D(Collision2D collision) //物体が衝突した時に呼ばれる
{
if (collision.collider.tag == enemyTag || collision.collider.tag == tamaTag) //弾または敵と衝突した
{
isDown = true; //プレイヤーはダウンしました。
}
}
public bool PlayerDeath() //プレイヤーの死亡を他のclassが取得できるようにする
{
playerDeath = isDown;
return playerDeath; //生死を返す
}