【问题标题】:Spawn image at random position in canvas在画布中的随机位置生成图像
【发布时间】:2018-07-15 03:18:09
【问题描述】:

我有一个画布,里面有一个面板。我想在面板内的随机位置(屏幕上)生成不同的图像 UI 对象。我采用了面板的 x 和 y 最小和最大限制以生成随机位置(使用这些限制),但问题是对象没有在所需位置实例化。这是我的代码。

public class ImageSpawnerScreen : MonoBehaviour {
    public float waitTime = 2;
    public float cubeSpawnTotal = 10;
    public List<GameObject> cubePrefabList;

    float xPosMinLimit = -347;
    float xPosMaxLimit = 340;
    float yPosMinLimit = -458f;
    float yPosMaxLimit = 450f;

    public GameObject panel;
    void Start()
    {
        StartCoroutine(SpawnCube());
    }


    IEnumerator SpawnCube()
    {
        for (int i = 0; i < cubeSpawnTotal; i++)
        {
            GameObject prefabToSpawn = cubePrefabList[Random.Range(0, cubePrefabList.Count - 1)];
            //Vector3 spawnPosition = Camera.main.ScreenToViewportPoint(new Vector3(Random.Range(0,Screen.width),0,Random.Range(0,Screen.height)));  //Random.Range(xPosMinLimit, xPosMaxLimit);

            float xPos = Random.Range(xPosMinLimit, xPosMaxLimit);
            float yPos = Random.Range(yPosMinLimit, yPosMaxLimit);
            Vector3 spawnPosition = new Vector3(xPos, yPos, 0f);
            GameObject spwanObj = Instantiate(prefabToSpawn, spawnPosition, Quaternion.identity) as GameObject;
            spwanObj.transform.parent = panel.transform;
            spwanObj.transform.position = spawnPosition;
            yield return new WaitForSeconds(waitTime);
        }
    }
}

我检查了实例化对象的位置远离给定的随机范围位置。我做错了什么?我认为它是 Rect Transform 所以我必须以不同的方式设置它的位置。

【问题讨论】:

    标签: c# unity3d canvas unity-ui


    【解决方案1】:

    确实,您需要在Canvas 中使用RectTransform。 您也不需要-1 为您List.Count。检查下面评论中的链接。

    我认为以下脚本会满足您的需求:

    public class ImageSpawnerScreen : MonoBehaviour
    {
        public float waitTime = 2;
        public float cubeSpawnTotal = 10;
        public List<GameObject> imagesList;
    
        public RectTransform panel;
    
        void Start()
        {
            StartCoroutine(SpawnImage());
        }
    
    
        IEnumerator SpawnImage()
        {
            for (int i = 0; i < cubeSpawnTotal; i++)
            {
                GameObject imageToSpawn = imagesList[Random.Range(0, imagesList.Count)]; // Remove -1 after count since is exclusive for int (https://docs.unity3d.com/ScriptReference/Random.Range.html)
    
                Vector3 spawnPosition = GetBottomLeftCorner(panel) - new Vector3(Random.Range(0, panel.rect.x), Random.Range(0, panel.rect.y), 0);
    
                print("Spawn image at position: " + spawnPosition);
    
                GameObject spwanObj = Instantiate(imageToSpawn, spawnPosition, Quaternion.identity, panel);
                yield return new WaitForSeconds(waitTime);
            }
        }
    
        Vector3 GetBottomLeftCorner(RectTransform rt)
        {
            Vector3[] v = new Vector3[4];
            rt.GetWorldCorners(v);
            return v[0];
        }
    }
    

    如果您需要更多解释,请告诉我。

    【讨论】:

      【解决方案2】:

      要管理 Canvas 对象的位置,您绝对应该使用RectTransform 而不是常规的transform。在您的情况下,您必须执行以下操作:

      m_RectTransform = GetComponent&lt;RectTransform&gt;();

      至于设置位置 - 你在 Canvas 内的对象上看到的坐标不是.position 而是RectTransform.anchoredPosition,所以你应该在你的代码中使用它。这是anchoredPosition上的官方documentation

      【讨论】:

      • 我已经通过设置位置而不是位置来解决问题(spwanObj.transform.localPosition = spawnPosition;)。但是您的代码也适用于我。感谢您提供有价值的信息。这是更好的方法。
      【解决方案3】:
      public class ImageSpawnerScreen : MonoBehaviour {
          public float waitTime = 2;
          public float cubeSpawnTotal = 10;
          public List<GameObject> cubePrefabList;
      
          public GameObject panel;
          void Start()
          {
              StartCoroutine(SpawnCube());
          }
      
      
          IEnumerator SpawnCube()
          {
              for (int i = 0; i < cubeSpawnTotal; i++)
              {
                  GameObject prefabToSpawn = cubePrefabList[Random.Range(0, cubePrefabList.Count - 1)];
                  //Vector3 spawnPosition = Camera.main.ScreenToViewportPoint(new Vector3(Random.Range(0,Screen.width),0,Random.Range(0,Screen.height)));  //Random.Range(xPosMinLimit, xPosMaxLimit);
      
                  float xPos = Random.Range(0, Screen.width);
                  float yPos = Random.Range(0, Screen.height);
                  Vector3 spawnPosition = new Vector3(xPos, yPos, 0f);
                  GameObject spwanObj = Instantiate(prefabToSpawn, spawnPosition, Quaternion.identity) as GameObject;
                  spwanObj.transform.parent = panel.transform;
                  spwanObj.transform.position = spawnPosition;
                  yield return new WaitForSeconds(waitTime);
              }
          }
      }
      

      这应该可以帮助你。

      【讨论】:

      • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
      • 如果您解释此代码与问题中的代码有何不同、您更改了什么、更改它的原因以及解决问题的原因,此答案会更有用。跨度>
      猜你喜欢
      • 2014-10-14
      • 2018-06-30
      • 2012-10-10
      • 1970-01-01
      • 1970-01-01
      • 2014-07-03
      • 1970-01-01
      • 2015-10-28
      • 1970-01-01
      相关资源
      最近更新 更多