我编写了一些代码,允许用户通过在流媒体资源中加载输入图像,然后使用这些图像创建对象,以编辑器模式实例化对象。
这很有效,问题是当我尝试使用其中一个对象创建预制件时。出于某种原因,图像不会保存在预制件中,因此当我加载该预制件时,我会获得白色图像而不是原始游戏对象中的图像。
更新:事实证明我的背景屏幕实际上正常工作,但没有其他游戏对象。所以我不确定什么是错的,为什么它只适用于某些对象而不是其他对象。
这是我的代码:
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 :(得分:0)
当您通过检查器脚本更改某个对象的状态时,您必须告诉Unity,您已经做了一些更改,否则它不知道现场的对象发生了什么。并根据有关场景变化的信息(当您手动更改时,而不是通过脚本更改)Unity会序列化场景中的所有数据以保存所有信息。当您加载场景(在编辑器或播放模式下无关紧要)时,Unity会反序列化场景中的所有对象以向您显示。至于序列化/反序列化对象是相当昂贵的操作Unity只在真正需要时才这样做 - 在保存场景/对象的情况下,只有当它知道需要保存的某些更改时才会执行。
问题的实际解决方案取决于您使用的Unity版本。试试这个post。 Undo和MarkAllScenesDirty等内容可以为您提供帮助。对于旧版本的Unity EditorUtility.SetDirty应该有所帮助。
答案 1 :(得分:0)
正如人们指出Vmchar一样,当你使用代码保存预制件时。它使用初始状态保存,没有任何在运行时加载到它的东西。
我找到了一个解决方案,但你需要做的就是制作一个脚本,通过在流媒体集中序列化来保存图像(大量有关如何序列化图像的教程),然后使用www流加载它在其他场景需要时。