注意
本記事で掲載されている動作の実装方法及びプログラムのソースコードは最適な方法ではない可能性があります。今後不具合等が判明した場合には修正及び改良をおこなう可能性があります。
また今後自分で同機能を実装する場合の参考にする可能性もあるためソースコードだけではなく説明しつつ記事を進めていきます。
Unityによる自作ゲーム開発進捗その24になります!
今回はマップ制作2回目で草木を設置していきます。
Terrainシステムで設置するのと1つ1つ設置して比較すると前者は負荷が大きくなったため1つ1つ設置しました。
軽くする方法は存在するかもしれませんが、小さいマップなので1つ1つ設置しても長期化しないためこちらを選択しています。
以下に動画でのコピー用にソースコードを掲載しています。
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CharacterManager : MonoBehaviour {
static class Number {
public const int Left = 0;
public const int Center = 1;
public const int Right = 2;
}
[SerializeField]
private GameObject m_mob_prefab;
[SerializeField]
private AutoController[] m_auto_script = new AutoController[6];
[SerializeField]
private PopSystem[] m_pop_point = new PopSystem[3];
private List<GameObject> m_mob_prefab_list = new List<GameObject>();
private List<AssultEnemy> m_mob_prefab_script = new List<AssultEnemy>();
private GameObject[] m_left_base = new GameObject[5];
private GameObject[] m_center_base = new GameObject[5];
private GameObject[] m_right_base = new GameObject[5];
private float m_time_count = 0.0f;
private int m_left_state = 2;
private int m_center_state = 2;
private int m_right_state = 2;
private int m_attacker1_position = Number.Center;
private int m_attacker2_position = Number.Center;
private int[] m_character_position = new int[6];
private short m_mob_count = 0;
public void AttackerCommand(int a_attacker, int a_position) {
switch (a_position) {
case Number.Left:
if (a_attacker == 1) {
m_attacker1_position = Number.Left;
m_auto_script[m_character_position[4]].LineChange("Left", m_left_state); // タスク3
} else {
m_attacker2_position = Number.Left;
m_auto_script[m_character_position[5]].LineChange("Left", m_left_state); // タスク3
}
break;
case Number.Center:
if (a_attacker == 1) {
m_attacker1_position = Number.Center;
m_auto_script[m_character_position[4]].LineChange("Center", m_center_state); // タスク3
} else {
m_attacker2_position = Number.Center;
m_auto_script[m_character_position[5]].LineChange("Center", m_center_state); // タスク3
}
break;
case Number.Right:
if (a_attacker == 1) {
m_attacker1_position = Number.Right;
m_auto_script[m_character_position[4]].LineChange("Right", m_right_state); // タスク3
} else {
m_attacker2_position = Number.Right;
m_auto_script[m_character_position[5]].LineChange("Right", m_right_state); // タスク3
}
break;
}
}
public void Initialize(int[] a_number) {
Array.Copy(a_number, m_character_position, m_character_position.Length);
m_mob_count = 30;
string l_line = "Left";
for (int l_loop = 0; l_loop < m_mob_count; l_loop += 1) {
if (l_loop == m_mob_count / 3) l_line = "Center";
if (l_loop == m_mob_count - (m_mob_count / 3)) l_line = "Right";
var l_instance = Instantiate(m_mob_prefab, new Vector3(75.0f, 2.0f, 10.0f), Quaternion.Euler(0, 0, 0));
l_instance.SetActive(false);
m_mob_prefab_list.Add(l_instance);
m_mob_prefab_script.Add(l_instance.GetComponent<AssultEnemy>());
m_mob_prefab_script[l_loop].Initialize(l_line);
}
for (int l_loop = 0; l_loop < 3; l_loop += 1) {
// タスク2
m_left_base[l_loop] = GameObject.Find(string.Format("LeftBase{0}", l_loop));
m_center_base[l_loop] = GameObject.Find(string.Format("CenterBase{0}", l_loop));
m_right_base[l_loop] = GameObject.Find(string.Format("RightBase{0}", l_loop));
}
m_auto_script[m_character_position[0]].Initialize("Center", 3); // タスク3
m_auto_script[m_character_position[1]].Initialize("Left", 0); // タスク3
m_auto_script[m_character_position[2]].Initialize("Center", 0); // タスク3
m_auto_script[m_character_position[3]].Initialize("Right", 0); // タスク3
m_auto_script[m_character_position[4]].Initialize("Center", 1); // タスク3
m_auto_script[m_character_position[5]].Initialize("Center", 2); // タスク3
}
private void Update() {
m_time_count += Time.deltaTime;
if (m_time_count > 1.0f) {
BaseCheck();
ActiveObject();
}
}
private void BaseCheck() {
if (!m_left_base[m_left_state].activeSelf) {
m_left_state -= 1;
if (m_left_state < 0) m_left_state = 0;
switch (m_left_state) {
case 1:
m_pop_point[0].MoveObject(new Vector3(50.0f, 2.5f, 90.0f));
break;
case 0:
m_pop_point[0].MoveObject(new Vector3(50.0f, 2.5f, 65.0f));
break;
}
for (int l_loop = 0; l_loop < m_mob_count / 3; l_loop += 1) {
m_mob_prefab_script[l_loop].BaseChange(m_left_state);
}
m_auto_script[m_character_position[1]].BaseChange(m_left_state); // タスク3
if (m_attacker1_position == Number.Left) m_auto_script[m_character_position[4]].BaseChange(m_left_state); // タスク3
if (m_attacker2_position == Number.Left) m_auto_script[m_character_position[5]].BaseChange(m_left_state); // タスク3
}
if (!m_center_base[m_center_state].activeSelf) {
m_center_state -= 1;
if (m_center_state < 0) m_center_state = 0;
switch (m_center_state) {
case 1:
m_pop_point[1].MoveObject(new Vector3(75.0f, 2.5f, 90.0f));
break;
case 0:
m_pop_point[1].MoveObject(new Vector3(75.0f, 2.5f, 65.0f));
break;
}
for (int l_loop = m_mob_count / 3; l_loop < m_mob_count - (m_mob_count / 3); l_loop += 1) {
m_mob_prefab_script[l_loop].BaseChange(m_center_state);
}
m_auto_script[m_character_position[2]].BaseChange(m_center_state); // タスク3
if (m_attacker1_position == Number.Center) m_auto_script[m_character_position[4]].BaseChange(m_center_state); // タスク3
if (m_attacker2_position == Number.Center) m_auto_script[m_character_position[5]].BaseChange(m_center_state); // タスク3
}
if (!m_right_base[m_right_state].activeSelf) {
m_right_state -= 1;
if (m_right_state < 0) m_right_state = 0;
switch (m_right_state) {
case 1:
m_pop_point[2].MoveObject(new Vector3(110.0f, 2.5f, 90.0f));
break;
case 0:
m_pop_point[2].MoveObject(new Vector3(110.0f, 2.5f, 65.0f));
break;
}
for (int l_loop = m_mob_count - (m_mob_count / 3); l_loop < m_mob_count; l_loop += 1) {
m_mob_prefab_script[l_loop].BaseChange(m_right_state);
}
m_auto_script[m_character_position[3]].BaseChange(m_right_state); // タスク3
if (m_attacker1_position == Number.Right) m_auto_script[m_character_position[4]].BaseChange(m_right_state); // タスク3
if (m_attacker2_position == Number.Right) m_auto_script[m_character_position[5]].BaseChange(m_right_state); // タスク3
}
}
private void ActiveObject() {
m_time_count = 0.0f;
for (int l_loop = 0; l_loop < m_mob_count / 3; l_loop += 1) {
if (m_mob_prefab_list[l_loop].activeSelf == false) {
m_mob_prefab_list[l_loop].SetActive(true);
m_mob_prefab_script[l_loop].MobState(true);
break;
}
}
for (int l_loop = m_mob_count / 3; l_loop < m_mob_count - (m_mob_count / 3); l_loop += 1) {
if (m_mob_prefab_list[l_loop].activeSelf == false) {
m_mob_prefab_list[l_loop].SetActive(true);
m_mob_prefab_script[l_loop].MobState(true);
break;
}
}
for (int l_loop = m_mob_count - (m_mob_count / 3); l_loop < m_mob_count; l_loop += 1) {
if (m_mob_prefab_list[l_loop].activeSelf == false) {
m_mob_prefab_list[l_loop].SetActive(true);
m_mob_prefab_script[l_loop].MobState(true);
break;
}
}
}
}
/*
[規則]
p_ 外部アクセス
m_ メンバー変数
l_ ローカル変数
a_ 引数
[説明]
[バージョン]
2020-12-12 指定数生成及びプーリング呼び出し
2021-03-12 管理拠点を配列化し拠点管理を行いモブに伝える
2021-03-17 センターライン指揮官キャラの生成と名前変更(旧CenterMobManagerEnemy)
2021-03-25 戦闘ラインを1から3ラインに変更
2021-04-05 敵キャラクター生成位置を真ん中へ(左下では生成時にナビエリアが遠くエラーが出る)
2021-05-19 プレイヤーからのライン変更指示を遊撃キャラクターに反映させる
2021-05-28 スタート関数を廃止してプレイヤーコントローラーから初期化を呼ぶように変更
2021-06-04 メニュー画面からのキャラクター配置を戦闘画面へ反映させる
2021-06-10 戦闘エリア変更に伴ってモブの初期位置変更
2021-06-10 川の作成に伴ってモブの沸くポイントの高さ修正
[タスク]
(済)タスク1 プレイヤーキャラのステータスを反映させる
(済)タスク2 臨時防衛拠点数
タスク3 メニュー画面から各ラインのキャラクターを受け取るようにする
*/
m_pop_point[0].MoveObject(new Vector3(50.0f, 2.5f, 90.0f));
今回のプログラム変更点はモブの沸き位置の高さ調整のみです。
川を作成するために高さを上げた際に沸き位置が地面に埋もれてしまっていたためです。
今回の戦闘マップ作製は以下の点です。
- 木や草を設置する