1
\$\begingroup\$

I am trying to create the Snake game in Unity, based on this video tutorial. I have also viewed this tutorial.

I have created the new project with the 3D template and manually added the Canvas. I created a prefab from an Image which loads a texture from the Assets. I have this code:

using UnityEngine;
using UnityEngine.UI;
public class GameManager : MonoBehaviour
{
    public GameObject whiteCellPrefab;
    int N = 30, M = 20, size = 16;

    // Start is called before the first frame update
    void Start()
    {
        Transform p = GameObject.Find("Canvas").transform;
        for (int i = 1; i <= N; ++i)
        {
            for (int j = 1; j <= M; ++j)
            {
                GameObject g = Instantiate(whiteCellPrefab, p);
                g.transform.localPosition = new Vector3(i * size, j * size);
            }
        }
    }

    // Update is called once per frame
    void Update()
    {

    }
}

If I manually add a prefab instance to the Canvas, it is positioned as I want: in the bottom-left corner. But the script above, attached to the Main Camera object, creates the Image objects starting from the center point of the Canvas towards the top-right corner of the Canvas.

In the example shown here, I also added a new prefab instance to the Canvas in the Unity editor. It is positioned correctly even when play testing but the ones added with the script are shown somewhere else.

Screenshots

screenshot 1

screenshot 2

screenshot 3

screenshot 4

Download my example

I tried to explain all the steps involved in my problem above, but here is the repo with my problem.

Thank you.

\$\endgroup\$
0

1 Answer 1

1
\$\begingroup\$

Since you are already parenting the prefabs when you set localPosition that is relative to the center point of the canvas.

Change your Start method like this:

void Start()
{
    Transform p = GameObject.Find("Canvas").transform;

    for (int i = 1; i <= N; ++i)
    {
        for (int j = 1; j <= M; ++j)
        {
            GameObject g = Instantiate(whiteCellPrefab, p);
            g.transform.position = new Vector3(i * size, j * size);//set the position NOT the localPosition
        }
    }
}

You need to set he position and NOT the localPosition like this:

g.transform.position = new Vector3(i * size, j * size);

To clarify things further please add this script to your white_cell prefab. It will allow you to see the difference between localPosition and position of each prefab during runtime and designtime.

using UnityEngine;

public class WhiteCellPrefab : MonoBehaviour
{
    public Vector3 LocalPositionDebug;
    // Start is called before the first frame update
    void Start()
    {
        LocalPositionDebug = transform.localPosition;
    }
    private void OnDrawGizmos()
    {
        LocalPositionDebug = transform.localPosition;
    }
}
\$\endgroup\$
4
  • \$\begingroup\$ For working inside a canvas, you may want to adjust the anchors / anchoredPosition instead. \$\endgroup\$
    – DMGregory
    Jan 7, 2020 at 18:18
  • \$\begingroup\$ @DMGregory that is a totally different concept... the anchorPosition is used as pivot relative to the anchors and if there are no anchors they get dynamically calculated. \$\endgroup\$ Jan 7, 2020 at 18:41
  • \$\begingroup\$ 1. Parenting the prefabs means that they are not directly inside the scene, but inside another game object, such as a Canvas? 2. If (1) is true, that relativity to the center point of the canvas is something specific to the Canvas or to the UI system or does it do something similar in the 3D world? 3. When saying that an object does not have anchors, it means that all 4 of them are set to the center of the Canvas (or the parent game object of the game object without anchors)? Thank you. \$\endgroup\$ Jan 8, 2020 at 9:51
  • \$\begingroup\$ 1: That is correct. It means that the localPosition is now relative to the center of the parent. 2 it is specific to the positioning system it so the child obejct's localPosition will be relative to the parent Transform. 3 for this you need to read this link docs.unity3d.com/ScriptReference/… \$\endgroup\$ Jan 8, 2020 at 14:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .