Пытаюсь зациклить фон игры, при попытке перенести положение объекта слева направо багается
При старте скрипта, я List заполняю детьми объекта к которому был прикреплен скрипт, после в методе Update пытаюсь узнать ушел ли 1 элемент налево за камеру, после проверяю отрисовывается ли он, после чего я получаю последний элемент списка, узнаю его место положение и передаю 1 элементу который уже вышел налево за камеру, местоположение последнего элемента в сцене, что бы он появился за ним, после чего удаляю 1 элемент и добавляю его в конец списка. Но все не получается, может есть другой метод зацикливания фона, помогите пожалуйста
public class LoopBackGround : MonoBehaviour
{
public Vector2 speed = new Vector2 (10, 10);
public Vector2 direction = new Vector2 (-1, 0);
private List<Transform> backgroundPart; // все дети которые пренадлежат элементe на который присоединил скрипт
public bool isLooping = false;
public bool isCamera = false;
private int steps = 0;
private void Start()
{
if (isLooping) // надо ли элемент зациклить
{
backgroundPart = new List<Transform>(); // инициализирую List
for (int i = 0; i < gameObject.transform.childCount; i++)
{
Transform child = transform.GetChild(i);// получая ребенка элемента
if (child.GetComponent<Renderer>() != null) // узнаю есть ли у него компонент рендера
{
backgroundPart.Add(child);// добавляю в List
}
}
backgroundPart = backgroundPart.OrderBy(t => t.position.x).ToList();
}
}
private void Update()
{
Vector3 move = new Vector3(speed.x * direction.x, speed.y * direction.y, 0); // задаю движение элементу
move *= Time.deltaTime; // Умножаю ее на скорость отрисовки кадра
transform.Translate(move); // Передвигаю элемент
if (isCamera) // Это камера ?
Camera.main.transform.Translate(move); // Если да то двигаю камеру
if (isLooping) // Элемент надо зациклить ?
{
/*Vector3 cam = Camera.main.transform.position;*/ // Узнаю координаты камеры
Transform firstChild = backgroundPart.FirstOrDefault(); // получаю 1 элемент
if (firstChild != null) // узнаю не пустой ли 1 элемент
{
for (int i = 0; i < backgroundPart.Count; i++)
{
if ((firstChild.position.x + 20) < Camera.main.transform.position.x) // проверяю ушел ли объект налево
{
if (firstChild.GetComponent<Renderer>().isVisible == false)
{
print(firstChild.gameObject.name);
Transform lastChild = backgroundPart.LastOrDefault(); // получаю последний объект List
print(lastChild.gameObject.name);
firstChild.transform.Translate(new Vector3(lastChild.position.x, lastChild.position.y, lastChild.position.z)); // получаю место нахождение последнего элемента и передаю его первому
backgroundPart.Add(firstChild); // добавляю в List первый элемент
backgroundPart.Remove(firstChild); // удаляю первый элемент что бы двигать список справо налево
//print(backgroundPart[i].gameObject.name);
//lastElem = new Vector3(gameObjects.LastOrDefault().transform.position.x + 40, 0, 0);
//Transform first = gameObjects.FirstOrDefault(); // передаю элемент который ушел налево
//gameObjects[i].transform.Translate(lastElem); // Переношу элемент направо
//gameObjects.Add(first); // Добавляю первый элемент в конец
//gameObjects.Remove(first); // Удаляю первый элемент
//Transform lastChild = backgroundPart.LastOrDefault();
//Vector3 lastPosition = new Vector3(lastChild.transform.position.x, lastChild.transform.position.y, lastChild.transform.position.z);
//Vector3 lastSize = (lastChild.GetComponent<Renderer>().bounds.max - lastChild.GetComponent<Renderer>().bounds.min);
//firstChild.position = new Vector3(lastPosition.x + lastSize.x, firstChild.position.y, firstChild.position.z);
//backgroundPart.Remove(firstChild);
//backgroundPart.Add(firstChild);
}
}
}
}
}
steps++;
print($"{steps}) Проверка порядка элементов!");
for (int i = 0; i < backgroundPart.Count; i++)
{
print(backgroundPart[i].gameObject.name);
}
// СПИСОК НЕ ОБНОВЛЯЕТСЯ, 1 ЭЛЕМЕНТ ПЕРЕНОСИТСЯ В КОНЕЦ ОСТАЛЬНЫЕ НЕ ПЕРЕНОСЯТСЯ
}
}
Ответы (2 шт):
Transform firstChild = backgroundPart.FirstOrDefault(); // получаю 1 элемент
// - Берёте первый элемент из List
...
backgroundPart.Add(firstChild); // добавляю в List первый элемент
// - Добавляю в List ранее взятый элемент (который тау уже есть)
backgroundPart.Remove(firstChild); // удаляю первый элемент что бы двигать список справо налево
// - Удаляете только что добавленный элемент
Звоните 03!
transform.Translate(move); // Передвигаю элемент
// - Какой элемент? Это корневой GameObject
if (isCamera) // Это камера ?
Camera.main.transform.Translate(move); // Если да то двигаю камеру
// - Одно другому не мешает?
Если isLooping false с тем-же успехом можно тупо отключить скрипт.
isCamera ? Что тут забыла камера? Скрипт не о её поведении! И опять же, с тем же успехом...
public class CameraMovement : MonoBehaviour {
public float Speed = 10f;
public Vector2 Direction = new Vector2 (-1, 0);
private void Update () {
Camera.main.transform.Translate(Direction*Speed*Time.deltaTime); // Да так можно! Vector2*float
}
}
public class LoopBackGround : MonoBehaviour {
public List<Transform> _elements;
private float _elementWidth = 20; // Ширина элемента
private float _halfFrameWidth; // Полавина ширина камеры
private void Start () {
_halfFrameWidth = 20; // Не помню как определять, как нибудь сам...
_elements = new List<Transform>();
for (int i = 0; i < gameObject.transform.childCount; i++) {
Transform child = transform.GetChild(i);
if (child.GetComponent<Renderer>() != null)
_elements.Add(child);
}
_elements = _elements.OrderBy(t => t.position.x);
}
private void Update () {
Vector2 CameraPosition = Camera.main.transform.position;
int Count = _elements.Count;
int TotalElements = Mathf.FloorToInt((CameraPosition.x-_halfFrameWidth)/_elementWidth); // Сколько элементов от x0 до левой части камеры
for (int i = 0; i < Count; i++) { // Выстраиваем элементы под катр
int ElementNum = TotalElements+i; // Номер элемента i от х0
int NumOnList = ElementNum%Count; // Номер элемента в кадре (% - остаток от деления)
if (NumOnList < 0)
NumOnList += Count;
_elements[NumOnList].localPosition = new Vector3(ElementNum*_elementWidth, CameraPosition.y, 0);
}
}
}
Решил сам, критику человека понял, использую движение для камеры в отдельном скрипте. По итогу решил сам справиться с задачей. Спасибо за помощь !
Вот код :
`
public class Loop : MonoBehaviour
{
public Vector2 speed = new Vector2(10, 10);
public Vector2 direction = new Vector2(-1, 0);
public bool isLooping = false;
private List<Transform> backgroundPart;
private void Start()
{
// Корневую пустышку нужно зациклить?
if (isLooping)
{
// инициализирую список
backgroundPart = new List<Transform>();
for (int i = 0; i < transform.childCount; i++)
{
// получаю ребенка у корневого объекта
Transform child = transform.GetChild(i);
// проверяю есть ли у него объект рендерера
if (child.GetComponent<Renderer>() != null)
backgroundPart.Add(child);
}
// выполняю сортировку по x кто левее тот первый в списке
backgroundPart = backgroundPart.OrderBy(t => t.position.x).ToList();
}
}
private void Update()
{
Vector3 move = new Vector3(speed.x * direction.x, speed.y * direction.y, 0); // движение корневого объекта
move *= Time.deltaTime; // движение умножаю на скорость отрисовки кадра
transform.Translate(move); // задаю движение корневому объекту
if (isLooping) // корневой объект зацикленный
{
// узнаю координаты камеры
Vector3 pointCamera = Camera.main.transform.position;
// получаю последний объекта списка
Transform firstChild = backgroundPart.FirstOrDefault();
// проверяю есть ли ссылка на объект
if (firstChild != null)
{
// Проверяю ушел ли объект налево
if ((pointCamera.x - 20) > firstChild.transform.position.x)
{
// получаю последний объект списка
Transform lastChild = backgroundPart.LastOrDefault();
// вычитаю из последнего расстояние по x до первого элемента
Vector2 distance = new Vector2(lastChild.position.x - firstChild.position.x, 0);
// Vector3 с дефолтными значениями
Vector3 bias = default;
// узнаю объект является ли платформой
if (transform.gameObject.tag == "Platform")
{
// передаю значения
bias = new Vector3(firstChild.position.x + 50, Random.Range(-5, 5));
// двигаю элементы
firstChild.position = bias;
}
else if (transform.gameObject.tag == "Background")
{
bias = new Vector3(distance.x + 20, firstChild.transform.position.y, firstChild.position.z);
firstChild.transform.Translate(bias);
}
// удаляю найденный объект
backgroundPart.Remove(firstChild);
// добавляю нужный объект в конец списка
backgroundPart.Add(firstChild);
}
}
}
}
}`
![[![][1]](https://i.stack.imgur.com/qDj6F.png)