2017-10-09 79 views
0

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

这很好,问题是当我尝试用这些对象之一创建一个预制件时。出于某种原因,图像没有保存在预制件中,所以当我加载预制件时,我得到的是白色图像,而不是原始游戏对象中的图像。

更新:事实证明,我的背景屏幕实际上正常工作,但没有其他的gameobjects。所以我不确定什么是错的,为什么它只为一些物体而不是另一个物体工作。

这里是我的代码:

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; 


     } 
    } 

} 

回答

0

当你通过你一定要告诉团结,你已经做了一些改变的检查脚本改变某些对象的状态,否则它不知道的东西发生在现场的物体。根据场景变化的信息(当您手动更改而不是脚本时),Unity会序列化场景中的所有数据以保存所有信息。当你加载场景(在编辑器或者玩模式中无关紧要),Unity会反序列化场景中的所有对象来显示你。至于序列化/反序列化对象是相当昂贵的操作,Unity只在真正需要时才会执行 - 在保存场景/对象时,只有在知道需要保存某些更改时才会执行。

问题的实际解决方案取决于您使用的Unity版本。试试看这post。诸如UndoMarkAllScenesDirty应该可以帮到你。对于旧版本的Unity EditorUtility.SetDirty应该有所帮助。

+0

感谢您的回复,所以我尝试了undo.record(gameobject,“添加了更改),并将它放在place对象函数中,但它仍然不起作用。 ?脚本文件有点模糊 –

+0

@SamBasiony添加了撤消操作并对对象进行更改后,Unity是否显示场景中有变化?(它会在层次结构窗口中用星号标记场景名称(* )之后,试着在每次改变场景后对场景中的对象进行脏标记 – vmchar

+0

我试图将场景标记为脏,并且它不工作,因为它表示它在运行时无法工作。我刚刚找到了一个解决方案。 –

0

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

我发现了这个解决方案,但你需要做的是制作一个脚本,通过序列化它在streamingassets(大量的在线教程如何序列化图像)保存图像,然后使用www加载它在其他场景需要时流。