引き続き床の移動に関してです。
コンテンツ
現状
前回、現状発生している床のバグについて記載しました。
良ければ上記参照を見ていただければ幸いです。
その問題に関しては修正しなければならないが、加えて
この通り、事実上生成したものを役目が終わればそのまま破棄をしている。
そもそも
- 床は一定数しか存在しない
- 床は同じ位置から生成される
ので
以下のように破棄せずに使いまわした方が
生成コストと破棄コストがかからずに効率がいい。
また壁の分だけUnityのフレームワークからUpdateが呼ばれるため。
なるべくUpdate処理は記述しないほうが良い。
方法
前回と重複しますが以下のスクリプト
↓床を作るスクリプト
public class WallCreater : MonoBehaviour {
public List<GameObject> WallObjects;
public float wallWidth;
public int firstCreateNum;
public static int WallNum;
private int counter = 0;
// Use this for initialization
void Start () {
//初回に一定数生成
for(int i=0;i<=this.firstCreateNum; i++)
{
Instantiate(WallObjects[i% WallObjects.Count],new Vector3(0.0f,0.0f,-i*this.wallWidth), Quaternion.identity);
WallNum = i;
}
}
// Update is called once per frame
void Update () {
//数が定数より減っていれば生成
if (firstCreateNum > WallNum)
{
Instantiate(WallObjects[counter % WallObjects.Count], new Vector3(0.0f, 0.0f, -this.firstCreateNum * this.wallWidth), Quaternion.identity);
WallNum++;
counter++;
counter %= WallObjects.Count;
}
}
}
この部分
//数が定数より減っていれば生成
if (firstCreateNum > WallNum)
{
Instantiate(WallObjects[counter % WallObjects.Count], new Vector3(0.0f, 0.0f, -this.firstCreateNum * this.wallWidth), Quaternion.identity);
WallNum++;
counter++;
counter %= WallObjects.Count;
}
ここで生成しない
↓床を動かす
public class WallMove : MonoBehaviour {
public float confSpeed;
public static float Speed;
public float confDeletePosZ;
public static float DeletePosZ;
// Use this for initialization
void Start () {
//床を動かす速度を設定
if(this.confSpeed >= 0.0f)
{
Speed = confSpeed;
}
if (this.confDeletePosZ >= 0.0f)
{
DeletePosZ = confDeletePosZ;
}
}
// Update is called once per frame
void Update () {
//床を動かす
transform.Translate(0.0f,0.0f,Speed*Time.deltaTime);
//閾値を越えたらオブジェクトを削除
if(transform.position.z > DeletePosZ)
{
Destroy(gameObject, 0f);
WallCreater.WallNum--;
}
}
}
このスクリプト事態が不要!
移動させるのは「床を作るスクリプト」で行う。
そこで以下のように変える。(ついでに名前も)
public class WallMover : MonoBehaviour
{
// ----------------------------------------------
// 設定項目
// 生成するオブジェクト
[SerializeField] private List<GameObject> m_wallObjects = new List<GameObject>();
// 壁の幅
[SerializeField] private float m_wallWidth = 0.0f;
// 生成する数
[SerializeField] private int m_firstCreateNum = 0;
// 移動速度
[SerializeField] private Vector3 m_speed = Vector3.zero;
// 閾値
[SerializeField] private float m_border = 0.0f;
// ----------------------------------------------
// 内部メンバ変数
// オブジェクトのキャッシュ
private List<GameObject> m_obj = new List<GameObject>();
// 出現位置
private Vector3 m_popPos = Vector3.zero;
// Use this for initialization
void Start()
{
m_obj.Clear();
for (int i=0; i<= m_firstCreateNum; i++)
{
var tmp = new Vector3(0.0f, 0.0f, -i * m_wallWidth);
m_obj.Add(Instantiate(m_wallObjects[i% m_wallObjects.Count], tmp, Quaternion.identity));
m_popPos = tmp;
}
}
// Update is called once per frame
void Update()
{
foreach(var tmp in m_obj)
{
tmp.transform.Translate(m_speed);
// 閾値に達したら初期値に戻す
if(tmp.transform.position.z > m_border)
{
tmp.transform.position = m_popPos;
}
}
}
}
その結果が下です。
音がないのと再生時間が短いので今回はYouTube上げてません。
まとめ
思いのほか昔のスクリプトの試行錯誤感が懐かしく感じました。
他にも似たような挙動をしていると思うので徐々に作り直していこうと思います。
コメントを残す