首页 文章

Unity预制表演怪异吗?

提问于
浏览
0

我编写了一些代码,允许用户通过在流媒体资源中加载输入图像,然后使用这些图像创建对象,以编辑器模式实例化对象 .

这很好用,问题是当我尝试使用其中一个对象创建一个预制件时 . 由于某种原因,图像不会保存在预制件中,因此当我加载预制件时,我会获得白色图像而不是原始游戏对象中的图像 .

更新:事实证明我的背景屏幕实际上正常工作,但没有其他游戏对象 . 所以我不确定是什么问题以及为什么它只适用于某些物体但不适用于其他物体 .

这是我的代码:

public class PlacementObject : MonoBehaviour
{
    private loadbackgroundImages backgroundReference;
    public Sprite mouseShape;
    private Image mouseSprite;
    private RectTransform mouseMovement;
    public Canvas myCanvas;
    private int currentState = 0;
    private bool canMove = true;
    public List<Texture2D> allButtons;
    private List<Sprite> allButtonsSprite;
    private List<Sprite> allUISprites;
    private List<Texture2D> allUIElements;
    private int uiButtonStates = 0;
    private int uiElementStates = 0;
    public GameObject afterImport;
    private GameObject clonedObject;
    public GameObject child;

    public GameObject objectToBeExported;
    private bool isLoading = true;
    private bool isfinishedUploading;
    private Vector2 defaultSize;
    // Use this for initialization
    void Start()
    {
        allUIElements = new List<Texture2D>();
        allButtons = new List<Texture2D>();
        var info = new DirectoryInfo(Application.streamingAssetsPath + "/" + "UIButtons");
        var fileInfo = info.GetFiles();
        foreach (FileInfo file in fileInfo)
        {
            if (file.Extension == ".png" || file.Extension == ".jpg")
            {

                StartCoroutine(uploadButtonImages(System.IO.Path.Combine("file:///" + Application.streamingAssetsPath, "UIButtons/" + file.Name)));
            }
        }
        var info2 = new DirectoryInfo(Application.streamingAssetsPath + "/" + "UIElements");
        var fileInfo2 = info2.GetFiles();
        foreach (FileInfo file2 in fileInfo2)
        {
            if (file2.Extension == ".png" || file2.Extension == ".jpg")
            {

                StartCoroutine(uploadUiImages(System.IO.Path.Combine("file:///" + Application.streamingAssetsPath, "UIElements/" + file2.Name)));
            }
        }

        allButtonsSprite = new List<Sprite>();
        allUISprites = new List<Sprite>();
        //createSpritesForButtons(allButtons);
        // createSpritesForElements(allUIElements);
        mouseSprite = GetComponent<Image>();
        mouseSprite.sprite = mouseShape;
        mouseMovement = GetComponent<RectTransform>();
        backgroundReference = FindObjectOfType<loadbackgroundImages>();
        isfinishedUploading = true;
        defaultSize = mouseMovement.sizeDelta;
    }

    // Update is called once per frame
    void Update()
    {
        print(isLoading);
        if (isfinishedUploading && backgroundReference.isfinished)
        {
            isLoading = false;
        }

        Cursor.visible = false;
        transform.position = Input.mousePosition;
        Vector2 pos;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(myCanvas.transform as RectTransform, Input.mousePosition, myCanvas.worldCamera, out pos);
        transform.position = myCanvas.transform.TransformPoint(pos);


        if (isLoading == false)
        {
            if (currentState == 2)
            {
                mouseSprite.sprite = allUISprites[uiElementStates];
            }
            if (currentState == 1)
            {
                mouseSprite.sprite = allButtonsSprite[uiButtonStates];


            }
            if (Input.GetKeyDown(KeyCode.V))
            {
                currentState = 0;
                mouseSprite.sprite = mouseShape;
                mouseMovement.sizeDelta = defaultSize;
            }



            else if (Input.GetKeyDown(KeyCode.B))
            {
                currentState = 1;

            }
            else if (Input.GetKeyDown(KeyCode.N))
            {
                currentState = 2;
            }
            if (Input.GetMouseButtonDown(0))
            {
                placeObject();
            }

            if (Input.GetAxis("Horizontal") > 0 && canMove)
            {
                canMove = false;

                if (currentState == 0)
                {
                    changeBackgroundNext();
                }
                else if (currentState == 1)
                {
                    changeButtonNext();
                }
                else if (currentState == 2)
                {
                    changeElementNext();
                }

            }
            if (Input.GetMouseButton(1))
            {
                rotateObject();
            }
            if (Input.GetAxis("Vertical") < 0)
            {

                if (currentState == 1 || currentState == 2)
                {
                    mouseMovement.sizeDelta -= new Vector2(1, 1);
                }
            }
            if (Input.GetAxis("Vertical") > 0)
            {
                if (currentState == 1 || currentState == 2)
                {
                    mouseMovement.sizeDelta += new Vector2(1, 1);
                }
            }


            if (Input.GetAxis("Horizontal") < 0 && canMove)
            {

                canMove = false;
                if (currentState == 0)
                {
                    changeBackgroundPrev();
                }
                else if (currentState == 1)
                {
                    changeButtonPrev();
                }
                else if (currentState == 2)
                {
                    changeElementPrev();
                }
            }
            if (Input.GetAxis("Horizontal") == 0)
            {
                canMove = true;

            }


            if (Input.GetKeyDown(KeyCode.Space))
            {
                var newBackgroundSprite = backgroundReference.allSprites[backgroundReference.imageIndex];
                backgroundReference.imageReference.sprite = newBackgroundSprite;


                // exportObject();
                // importObject();
#if UNITY_EDITOR
              var prefab =  PrefabUtility.CreatePrefab( "Assets/Resources/Image.prefab", FindObjectOfType<loadbackgroundImages>().gameObject);

                AssetDatabase.Refresh();
#endif

            }
        }
    }
    void rotateObject()
    {
        if (currentState == 1 || currentState == 2)
            mouseMovement.eulerAngles += new Vector3(0, 0, 1);
    }
    private void exportObject()
    {
        UIData saveData = new UIData();
        saveData.inputObject = objectToBeExported;


        //Save data from PlayerInfo to a file named players
        DataSaver.saveData(saveData, "UI");


    }
    public void importObject()
    {
        UIData loadedData = DataSaver.loadData<UIData>("UI");
        if (loadedData == null)
        {
            return;
        }

        //Display loaded Data
        Debug.Log("Life: " + loadedData.inputObject);
        afterImport = loadedData.inputObject;


    }
    private void changeBackgroundNext()
    {
        backgroundReference.imageIndex++;
        if (backgroundReference.imageIndex >= backgroundReference.allSprites.Count)
        {
            backgroundReference.imageIndex = 0;
        }

    }
    private void changeButtonNext()
    {
        uiButtonStates++;
        if (uiButtonStates >= allButtonsSprite.Count)
        {
            uiButtonStates = 0;
        }

    }
    private void changeElementNext()
    {
        uiElementStates++;
        if (uiElementStates >= allUISprites.Count)
        {
            uiElementStates = 0;
        }

    }
    private void changeElementPrev()
    {
        uiElementStates--;
        if (uiElementStates < 0)
        {
            uiElementStates = allUISprites.Count - 1;
        }

    }
    private void changeButtonPrev()
    {
        uiButtonStates--;
        if (uiButtonStates < 0)
        {
            uiButtonStates = allButtonsSprite.Count - 1;
        }

    }
    private void changeBackgroundPrev()
    {
        backgroundReference.imageIndex--;
        if (backgroundReference.imageIndex < 0)
        {
            backgroundReference.imageIndex = backgroundReference.allSprites.Count - 1;
        }
    }
    IEnumerator uploadButtonImages(string url)
    {
        WWW www = new WWW(url);

        yield return www;
        if (www != null)
        {
            allButtons.Add(www.texture);
            allButtonsSprite.Add(Sprite.Create(www.texture, new Rect(0, 0, www.texture.width, www.texture.height), new Vector2(0.5f, 0.5f)));
        }
    }

    private void createSpritesForButtons(List<Texture2D> allTextures)
    {


        for (int i = 0; i < allTextures.Count; i++)
        {
            Sprite tempSprite = Sprite.Create(allTextures[i], new Rect(0, 0, allTextures[i].width, allTextures[i].height), new Vector2(0.5f, 0.5f));
            tempSprite.name = "Button" + i;
            allButtonsSprite.Add(tempSprite);

        }


    }
    IEnumerator uploadUiImages(string url)
    {

        WWW www = new WWW(url);

        yield return www;
        print(url);
        if (www != null)
        {
            allUIElements.Add(www.texture);
            allUISprites.Add(Sprite.Create(www.texture, new Rect(0, 0, www.texture.width, www.texture.height), new Vector2(0.5f, 0.5f)));
        }
    }
    private void createSpritesForElements(List<Texture2D> allTextures)
    {


        for (int i = 0; i < allTextures.Count; i++)
        {
            Sprite tempSprite = Sprite.Create(allTextures[i], new Rect(0, 0, allTextures[i].width, allTextures[i].height), new Vector2(0.5f, 0.5f));
            tempSprite.name = "" + i;

            allUISprites.Add(tempSprite);

        }


    }

    private void placeObject()
    {
        if (currentState == 1)
        {
            var gameObject = Instantiate(child, transform.position, Quaternion.Euler(mouseMovement.eulerAngles.x, mouseMovement.eulerAngles.y, mouseMovement.eulerAngles.z), backgroundReference.transform);
            gameObject.GetComponent<RectTransform>().sizeDelta = new Vector2(mouseMovement.sizeDelta.x, mouseMovement.sizeDelta.y);
            var newSprite = allButtonsSprite[uiButtonStates];
            gameObject.GetComponent<Image>().sprite = newSprite;
            gameObject.AddComponent<Button>();
        }

        if (currentState == 2)
        {
            var gameObject = Instantiate(child, transform.position, Quaternion.Euler(mouseMovement.eulerAngles.x, mouseMovement.eulerAngles.y, mouseMovement.eulerAngles.z), backgroundReference.transform);
            gameObject.GetComponent<RectTransform>().sizeDelta = new Vector2(mouseMovement.sizeDelta.x, mouseMovement.sizeDelta.y);
            var newSprite = allUISprites[uiElementStates];
            gameObject.GetComponent<Image>().sprite = newSprite;


        }
    }

}

2 回答

  • 0

    当您通过检查器脚本更改某个对象的状态时,您必须告诉Unity,您已经做了一些更改,否则它不知道场景中的对象发生了什么 . 并根据有关场景变化的信息(当您手动更改时,而不是通过脚本更改)Unity会序列化场景中的所有数据以保存所有信息 . 当您加载场景(在编辑器或播放模式下无关紧要)时,Unity会反序列化场景中的所有对象以向您显示 . 至于序列化/反序列化对象是相当昂贵的操作Unity只在真正需要时才这样做 - 在保存场景/对象的情况下,只有当它知道需要保存的某些更改时才会执行 .

    问题的实际解决方案取决于您正在使用的Unity版本 . 试试看这个post . 像UndoMarkAllScenesDirty这样的东西应该可以帮到你 . 对于旧版本的Unity EditorUtility.SetDirty应该有所帮助 .

  • 0

    所以当人们指出像Vmchar时,使用代码保存预制件 . 它使用初始状态保存,没有任何在运行时加载到它的东西 .

    我发现了一个解决方案,你需要做的就是制作一个脚本,通过在流媒体集中序列化来保存图像(大量有关如何序列化图像的教程),然后在需要时使用www流加载它另一个场景 .

相关问题