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;


        }
    }

}
4

2 回答 2

0

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

您的问题的实际解决方案取决于您使用的 Unity 版本。尝试阅读这篇文章UndoMarkAllScenesDirty 之类的东西应该可以帮助你。对于旧版本的 Unity EditorUtility.SetDirty应该会有所帮助。

于 2017-10-09T06:22:06.627 回答
0

因此,正如人们指出的那样,当您使用代码保存预制件时,就像 Vmchar 一样。它使用初始状态保存,没有任何在运行时加载到它的东西。

不过,我找到了一个解决方案,您需要做的就是制作一个脚本,通过在流资产中序列化图像来保存图像(网上有很多关于如何序列化图像的教程),然后在需要时使用 www 流加载它另一个场景。

于 2017-10-10T16:21:25.770 回答