I'm new to Unity. How to make Canvas UI Responsive like Small Screens for Small Button and Big Screens for Big button. But when I tested Small buttons in Small Screen are big and Big buttons are Big screens are small. I just wanna reverse this so it will be responsive, Is it possible to do it?
The trick to fully scalable designs in Unity UI, is to never use pixel sizes for anything. Start will all rects fully expanded (0 margins on all sieds) and work your way using anchor points (use alt to force margin zeroing)
I can also recommend a little utility I wrote RectAnchorHelper. If you follow the link, You may get an error with [exposemethodineditor] dependency, just comment it out, or download the whole repo. I am pasting full class code with dependency stripped below.
What RectAnchorHelper does it exposes four sliders that let you adjust your placement in fully proportional way, so you can design your UI without any reference to pixel sizes.
The other part of the equation is using the canvas scaler set to Scale with Screen Size as mentioned by Rakib
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
#if UNITY_EDITOR
using UnityEditor;
#endif
[ExecuteInEditMode]
public class RectAnchorHelper : MonoBehaviour
{
RectTransform rect { get { if (_rect == null) _rect = GetComponent<RectTransform>(); return _rect; } }
RectTransform _rect;
[SerializeField] bool edit;
[SerializeField] bool _symmetricalXMode;
[SerializeField] bool _symmetricalYMode;
public bool symmetricalXMode { get { return _symmetricalXMode; } set { _symmetricalXMode = value; CheckAndSet(); } }
public bool symmetricalYMode { get { return _symmetricalYMode; } set { _symmetricalYMode = value; CheckAndSet(); } }
[Range(0, 1)]
[SerializeField] float _xAnchorMin;
[Range(0, 1)]
[SerializeField] float _xAnchorMax = 1;
[Range(0, 1)]
[SerializeField] float _yAnchorMin;
[Range(0, 1)]
[SerializeField] float _yAnchorMax = 1;
public float xAnchorMin { get { return _xAnchorMin; } set { _xAnchorMin = value; CheckAndSet(); } }
public float xAnchorMax { get { return _xAnchorMax; } set { _xAnchorMax = value; CheckAndSet(); } }
public float yAnchorMin { get { return _yAnchorMin; } set { _yAnchorMin = value; CheckAndSet(); } }
public float yAnchorMax { get { return _yAnchorMax; } set { _yAnchorMax = value; CheckAndSet(); } }
// [SerializeField] [HideInInspector] Vector2 offsetMin;
// [SerializeField] [HideInInspector] Vector2 offsetMax;
public void SetMargin(float f) { margin = f; }
[Range(-1, 15)]
[SerializeField] float _margin = -1;
public float margin { get { return _margin; } set { _margin = value; CheckAndSet(); } }
void CheckAndSet()
{
if (symmetricalXMode) _xAnchorMax = 1 - _xAnchorMin;
if (symmetricalYMode) _yAnchorMax = 1 - _yAnchorMin;
SetValues();
}
void Reset()
{
PrepareRect();
GetValues();
}
void OnValidate()
{
if (symmetricalXMode) xAnchorMax = 1 - xAnchorMin;
if (symmetricalYMode) yAnchorMax = 1 - yAnchorMin;
// if (Application.isPlaying) return;
#if UNITY_EDITOR
bool isSelected = false;
foreach (var s in Selection.gameObjects)
{
if (s == gameObject) isSelected = true;
}
if (!isSelected) { edit = false; return; }
Undo.RecordObject(rect, "RectAnchor");
#endif
if (edit)
{
SetValues();
}
else
GetValues();
}
void SetValues()
{
rect.anchorMin = new Vector2(xAnchorMin, yAnchorMin);
rect.anchorMax = new Vector2(xAnchorMax, yAnchorMax);
if (margin != -1)
{
rect.offsetMin = new Vector2(margin * margin, margin * margin);
rect.offsetMax = new Vector2(-(margin * margin), -(margin * margin));
}
}
void GetValues()
{
_xAnchorMin = rect.anchorMin.x;
_xAnchorMax = rect.anchorMax.x;
_yAnchorMin = rect.anchorMin.y;
_yAnchorMax = rect.anchorMax.y;
}
void PrepareRect()
{
rect.anchorMin = Vector2.zero;
rect.anchorMax = Vector2.one;
rect.offsetMax = Vector2.zero;
rect.offsetMin = Vector2.zero;
rect.localScale = Vector3.one;
}
}
Of course you can do it all without my class, but I personally found typing in float values rather tedious, and the above code will give you sliders enabling easy visual editing.