Прилипание спрайта к границам экрана
Представим такую ситуацию, например, нам нужно в рамках экрана разместить некие спрайты, которые будут как часть интерфейса пользователя или может это будет элемент фона. Если мы располагаем объекты на сцене, то ориентируемся прежде всего на текущие настройки, соотношения сторон экрана, так как если переключить соотношение, допустим, с 16:9 на 16:10 то мы увидим изменения по ширине экрана и объекты, которые находятся с левой и правой стороны, будут «обрезаны». Так вот, нам нужно сделать так, чтобы объекты «прилипали» к границам экрана, и соответственно меняли свою позицию при изменении разрешения экрана.
Добавляем на сцену скрипт:
Как видим скрипт не особо сложный, обновление позиций объектов происходит, только когда в игре меняется разрешение. Но в редакторе обновление делается постоянно, для удобства настройки сцены.
Скачать скрипт:
Добавляем на сцену скрипт:
using System.Collections;
using UnityEngine;
[ExecuteInEditMode] // выполнение в редакторе
public class Responsive2D : MonoBehaviour {
private enum Anchor
{
Center,
MiddleLeft,
MiddleRight,
BottomCenter,
BottomLeft,
BottomRight,
TopLeft,
TopRight,
TopCenter
}
[SerializeField] private Prefs[] objectPrefs;
private Vector2 resolution = Vector2.zero;
[System.Serializable] struct Prefs
{
public SpriteRenderer target;
public Vector2 offset;
public Anchor anchor;
}
Vector2 ScreenAnchor(Anchor value, out Vector2 delta) // определяем координаты по якорю
{
Vector2 result = Vector2.zero;
delta = Vector2.zero;
switch(value)
{
case Anchor.Center:
delta = new Vector2(.5f, .5f);
result = new Vector2(Screen.width/2, Screen.height/2);
break;
case Anchor.MiddleLeft:
delta = new Vector2(1f, .5f);
result = new Vector2(0, Screen.height/2);
break;
case Anchor.MiddleRight:
delta = new Vector2(0, .5f);
result = new Vector2(Screen.width, Screen.height/2);
break;
case Anchor.BottomCenter:
delta = new Vector2(.5f, 1f);
result = new Vector2(Screen.width/2, 0);
break;
case Anchor.BottomLeft:
delta = new Vector2(1f, 1f);
result = new Vector2(0, 0);
break;
case Anchor.BottomRight:
delta = new Vector2(0, 1f);
result = new Vector2(Screen.width, 0);
break;
case Anchor.TopCenter:
delta = new Vector2(.5f, 0);
result = new Vector2(Screen.width/2, Screen.height);
break;
case Anchor.TopLeft:
delta = new Vector2(1f, 0);
result = new Vector2(0, Screen.height);
break;
case Anchor.TopRight:
delta = new Vector2(0, 0);
result = new Vector2(Screen.width, Screen.height);
break;
}
return result;
}
void UpdatePosition() // обновление массива спрайтов
{
for(int i = 0; i < objectPrefs.Length; i++)
{
if(objectPrefs[i].target != null)
{
Vector2 delta;
Vector2 anchor = ScreenAnchor(objectPrefs[i].anchor, out delta);
objectPrefs[i].target.transform.position = TargetPosition(objectPrefs[i].target.transform.position, anchor, objectPrefs[i].target.bounds, delta, objectPrefs[i].offset);
}
}
}
Vector3 TargetPosition(Vector3 worldPoint, Vector2 screenPoint, Bounds bounds, Vector2 delta, Vector2 offset)
{
Vector3 worldPosition = Camera.main.ScreenToWorldPoint(screenPoint + offset);
worldPosition.x += bounds.size.x / 2f * (delta.x - screenPoint.x / Screen.width);
worldPosition.y += bounds.size.y / 2f * (delta.y - screenPoint.y / Screen.height);
worldPosition.z = worldPoint.z;
return worldPosition;
}
void LateUpdate()
{
if(resolution.x != Screen.width || resolution.y != Screen.height) // только, если было изменено разрешение экрана
{
UpdatePosition();
resolution.x = Screen.width;
resolution.y = Screen.height;
}
#if UNITY_EDITOR
UpdatePosition(); // постоянное обновление в редакторе
#endif
}
}
Как видим скрипт не особо сложный, обновление позиций объектов происходит, только когда в игре меняется разрешение. Но в редакторе обновление делается постоянно, для удобства настройки сцены.
Скачать скрипт:
Комментариев 5
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.