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
I've also read the following links with no luck: https://stackoverflow.com/questions/32347009/unity-canvas-does-not-fill-screen https://answers.unity.com/questions/943190/ui-panel-not-covering-whole-screen.html https://answers.unity.com/questions/1331722/ui-scaling-issues.html
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?