Unity预制表演很奇怪?

时间:2017-10-09 02:16:32

标签: image unity3d load gameobject unity-editor

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

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

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

这是我的代码:

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 :(得分:0)

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

问题的实际解决方案取决于您使用的Unity版本。试试这个postUndoMarkAllScenesDirty等内容可以为您提供帮助。对于旧版本的Unity EditorUtility.SetDirty应该有所帮助。

答案 1 :(得分:0)

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

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