簡體   English   中英

在鼠標坐標處將預制件實例化到畫布

[英]Instantiate prefabs to a canvas at mouse coordinates

在我目前正在進行的一個項目中,我讓用戶單擊一個區域,稍后將其放置在該區域中,將它們放置到環境中。 我想用放置在畫布上的簡單標記來可視化它們放置的內容,以便在它們添加和刪除點時標記也可以移動。

我找到了一些有關如何開始的資源,列出了如何將預制件實例化到畫布中,但是它似乎對我沒有用。 我覺得這一定與我使用坐標的方式有關,但我不確定。

public GameObject markerPrefab;

然后稍后在另一個函數中

GameObject boatMarker = Instantiate(markerPrefab, Input.mousePosition, Quaternion.identity);
boatMarker.transform.SetParent(GameObject.FindGameObjectWithTag("Canvas").transform, false);

代碼運行,並且預制件確實進入了場景,但是它們都出現在畫布的右上角,一種在另一種之上。 有任何想法我在這里做錯了嗎? 另外,雖然我不想讓你們為我編寫代碼,但對於以后如何刪除預制件的特定實例有何建議?

我要說的主要問題是,您正在使用帶有第二個參數false SetParent

如果為true ,則會修改父相對位置,比例和旋轉,以使對象保持以前相同的世界空間位置 ,旋轉和比例。

在您的情況下,您保持相同的世界空間位置。

由於您的畫布是Screenspace overlay其寬度和高度(以Unity單位為單位)與顯示/窗口像素的寬度和高度完全匹配。 因此,當你做

GameObject boatMarker = Instantiate(markerPrefab, Input.mousePosition, Quaternion.identity);

對象已經在正確的位置。 為了直觀地看到我只是給它一個立方體,所以您看到它在我單擊的位置已經生成了(您看不到該圖像,因為它不是Canvas的孩子):

在此處輸入圖片說明

如果將那個false參數傳遞給SetParent會發生什么,那就是它不會保留其當前的世界空間位置,而是保留其當前的localPosition並移至其父對象內的相對位置。 由於它是Canvas並且您的預制件也可能使用RectTransform ,因此生成的位置取決於很多事情,例如,預制件RectTransform的軸和錨設置,還RectTransform Canvas Scaler RectTransform > Scale Factor

如果您的預制件例如固定在中心(通常是默認值),而您恰好單擊窗口的中心,它將顯示在右上角。

在此處輸入圖片說明

為什么?

  1. 您單擊(windowWidth / 2, WindowHeight / 2) 所以預制件最初是在這里產生的

  2. 比起使用帶有false SetParent,它可以保持該位置,但是這次相對於Canvas的中心

    =>畫布位置的中心是(windowWidth / 2, WindowHeight / 2)因此添加本地預制坐標(windowWidth / 2, WindowHeight / 2)得出最終位置(WindowWidth, WindowHeight) ==右上角。


因此,您可以通過將預制件固定在左下角來解決此問題

在此處輸入圖片說明

或不要將false作為參數傳遞給SetParent

boatMarker.transform.SetParent(_canvas.transform);

您實際上也可以在一個電話中完成

Instantiate(markerPrefab, Input.mousePosition, Quaternion.identity, _canvas.transform);

此外,您不應一次又一次使用FindObjectWidthTag 我寧願只獲取一次,甚至在可能的情況下通過檢查器進行引用:

public GameObject markerPrefab;

[SerializeField] private Canvas _canvas;

private void Awake()
{
    // If no canvas is provided get it by tag
    if (!_canvas) _canvas = GameObject.FindGameObjectWithTag("Canvas").GetComponent<Canvas>();
}

// Update is called once per frame
private void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
       Instantiate(markerPrefab, Input.mousePosition, Quaternion.identity, _canvas.transform);
    }
}

在此處輸入圖片說明

嘗試這個 :
1-將按鈕插入畫布
2-獲取此按鈕的游戲對象參考
3-將按鈕分配給按鈕變量並將游戲畫布分配給代碼Canvas變量后嘗試此代碼,它將正常工作

    public GameObject refButton;
    public GameObject canvas;
    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            GameObject button = Instantiate(refButton, Input.mousePosition,Quaternion.identity);
            button.transform.SetParent(canvas.transform);
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM