# Canvas not scaling to screen size

So I have a very simple scene set up with just a camera, a game object called TestGrid with a grid script, and then a canvas. I have a TextMeshPro prefab that I instantiate to fill the 10 x 20 grid with cells.

If I build and run the game, I see all the cells on my screen. However, in the editor play view, I can only see as many grid cell as would fit on startup. Making the game view smaller or larger will scale the ones already there, but everything that didn't fit initially is "clipped" out. The "canvas" is in the bottom left corner of the "grid"

I'll share my code as well:

using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.Diagnostics;

public class TestGrid : MonoBehaviour {
private float _cellSize = 50.0f;

[SerializeField]
private float _width = 0.0f;

[SerializeField]
private float _height = 0.0f;

[SerializeField] private TextMeshProUGUI labelPrefab;

// Start is called before the first frame update
private void Start() {
if (labelPrefab == null) {
Debug.LogError("You must set a label prefab.");
return;
}

GameObject canvas = GameObject.Find("labelCanvas");
if (canvas == null) {
Debug.Log("Unable to find canvas");
return;
}

// This is just a 2D array of ints.
Grid grid = new Grid((int)_width, (int)_height);
var canvasRect = canvas.GetComponent<RectTransform>().rect;
_cellSize = Math.Min((canvasRect.width / _width), (canvasRect.height / _height));

for (int x = 0; x < grid.Data.GetLength(0); ++x) {
for (int y = 0; y < grid.Data.GetLength(1); ++y) {
SpawnLabel(new Vector3(x, y, 0), canvas, grid.Data[x, y].ToString());

// TODO: Replace this with LineRenderer
Debug.DrawLine(GetWorldPosition(new Vector3(x, y)), GetWorldPosition(new Vector3(x, y + 1)), Color.white, 100f);
Debug.DrawLine(GetWorldPosition(new Vector3(x, y)), GetWorldPosition(new Vector3(x + 1, y)), Color.white, 100f);
}
Debug.DrawLine(GetWorldPosition(new Vector3(0f, _height)), GetWorldPosition(new Vector3(_width, _height)), Color.white, 100f);
Debug.DrawLine(GetWorldPosition(new Vector3(_width, 0f)), GetWorldPosition(new Vector3(_width, _height)), Color.white, 100f);
}
}

void Update() {
// NYI
}

private void SpawnLabel(Vector3 localPos, GameObject canvas, string text) {
float x = localPos.x;
float y = localPos.y;
var world = GetWorldPosition(new Vector3(x, y, 0)) + new Vector3(_cellSize, _cellSize) * .5f;
var label = Instantiate(labelPrefab,
world,
Quaternion.identity, canvas.transform);
label.text = text;
label.fontSize = 100;
label.autoSizeTextContainer = true;
}

private Vector3 GetWorldPosition(Vector3 local) {
return local * _cellSize;
}

}



Additional images of environment:

I'm actually not too sure what is going on here, so here is everything I know:

• I'm parenting my TextMeshPro prefab transform to the canvas transform, so that it scales properly
• My Canvas Scalar is set to reference resolution of 2560 x 1440, with a RPPU of 108
• Canvas Scalar is also set to Scale With Screen Size
• Canvas Screen Space is set to Overlay

Expected Results: No matter what the screen size is, I should see my full 10 x 20 grid of "cells" (in play view they're just 0's).

Question: If my canvas is supposed to scale with screen size, why is it that when I choose a cell size calculated from the canvas size, that it thinks the canvas is 2560 x 1440 when the screen size is clearly much smaller than that?

Do I need to calculate with a different value? Must I dynamically resize everything I draw within the canvas? What's going on here?

## 1 Answer

It looks to me like your code is placing things in a grid that you've built in world space. The canvas scaler component doesn't help if your grid is in world space.

Instead of manually creating a grid, use the GridLayoutGroup component. This component lets you easily create a grid on a canvas.

• Hmm.. okay, yeah that makes sense. I looked at that a bit and I'm struggling to make sense of it. There's a GridLayout which is just an abstract class. Then there's a Grid which I can add as a component to my Canvas. But doing that doesn't seem to do anything. How is a UnityEngine.Grid supposed to be used? I see it has a Cell Layout/size etc. But it doesn't draw the cells. I'm not sure how to add game objects to cells and the API doesn't seem to expose anything for that.And then there's GridLayoutGroup. I'm just trying to draw a grid around cells that I can put things in lol – Josh Sanders Jul 29 '20 at 3:13
• @JoshSanders Whoops! I meant to suggest using GridLayoutGroup, not GridLayout. I'll update my answer. GridLayoutGroup is definitely what you want. – Kevin Jul 29 '20 at 5:18
• Hrm. Okay, I'll give that a shot. I'm gonna spend some time to try and see what Grid does as well. That one seems to support Hexagons? At least it had an option for it. – Josh Sanders Jul 29 '20 at 5:21
• @JoshSanders The regular Grid is for placing things in 3D space, e.g. for placing tiles in 2D/2.5D tile-based games (games where the world is made up of tiles), or positioning units in grid-based games (games where the units move on a board-game-style grid, e.g. Fire Emblem). – Kevin Jul 29 '20 at 6:05
• ahh i see, that might be what I want then. I'm building a 2D tile-based game sort of like Heroes of Might and Magic, but just the battle system. – Josh Sanders Jul 29 '20 at 6:44