2017-10-09 86 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加載它在其他場景需要時流。