I have had web server that stores the images. In Unity, I can receive one and create gameobject to change it's material. However, I want to receive max no. four images. After 1 mins, I want to receive max no. four images again. Besides, if there is two images in server, I just want to create two new gameobject and change them material. If there is three, just create three. How can I do that, Any one can help me? Here is my code in Unity:
void Start () {
StartCoroutine (LoadImage ());
}
IEnumerator LoadImage(){
filename = "image" + k.ToString () + ".png";
url = "https://wwwfoodparadisehk.000webhostapp.com/" + filename;
WWW www = new WWW (url);
yield return www;
if (www.error != null) {
Debug.Log (www.error);
} else {
Debug.Log (k);
path = "Assets/MyMaterial" + k.ToString () + ".mat";
k = k + 1;
material = new Material (Shader.Find ("Sprites/Default"));
AssetDatabase.CreateAsset (material, path);
Debug.Log (AssetDatabase.GetAssetPath (material));
material.mainTexture = www.texture;
GameObject newPaperInstance = Instantiate (newpaper) as GameObject;
newPaperInstance.transform.Find ("Plane001").gameObject.GetComponent<Renderer> ().material = material;
}
}
I'd first ask my server for a list of the items I can get. For this, you can simply make a text file or make your own PHP file to create a list that you separate by a character like the pipe (|):
MyMaterial1|MyMaterial2|MyMaterial3
Then you can ask the file from your server the same way you'd get the images and create a string[] array object from the result. You can use Split('|') in order to create this array from your result string.
When you're done, you can foreach over the items within the array.
IEnumerator LoadImages()
{
string filename = "imagelist.txt";
string url = "https://wwwfoodparadisehk.000webhostapp.com/" + filename;
WWW www = new WWW (url);
yield return www;
if (www.error != null)
{
Debug.Log (www.error);
}
else
{
string[] images = www.text.Split ('|');
foreach (var image in images)
{
LoadImage (image);
}
}
}
Last but not least, you'll have to create a second function that loads the texture from the string you supply:
IEnumerator LoadImage(string image)
{
string url = "https://wwwfoodparadisehk.000webhostapp.com/" + image;
WWW www = new WWW (url);
yield return www;
if (www.error != null)
{
Debug.Log (www.error);
}
else
{
// turn your image into a texture with www.texture and apply it to your objects.
}
Related
I'm trying to get the url from the php page where am I going wrong? Error is: Curl error 3: malformed
my php file output : https://akdenizsergi.com/yetki/uploads/test3.jpg
my php code:
<?php
echo "test3.jpg"
?>
my gettext code(C#):
IEnumerator GetText()
{
UnityWebRequest www = UnityWebRequest.Get("http://localhost/yetki/eserlistesi2.php");
yield return www.SendWebRequest();
if (www.isNetworkError)
{
Debug.Log(www.error);
}
else
{
// Show results as text
eserurl = www.downloadHandler.text;
}
}
my get texture code:
IEnumerator GetTexture()
{
UnityWebRequest www = UnityWebRequestTexture.GetTexture(eserurl);
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.Log("hata" + www.error);
}
else
{
myTexture = ((DownloadHandlerTexture)www.downloadHandler).texture;
GetComponent<Renderer>().material = myMat;
// texture ı material e atıyor
myMat.mainTexture = myTexture;
// görsel ölçüsünü ekrana yazdırıyor
print("Size is " + myTexture.width + " by " + myTexture.height);
// plane ölçüsünü görselin ölçüsüne göre ayarlıyor
myPlane.transform.localScale += new Vector3(myTexture.width, 0, myTexture.height);
}
}
I've made an app in Unity which has been on the Google Play Store for over a year. Today I wanted to deployt it on Apple App Market but the translations don't work there.
I use the following code to load my app translations
public bool LoadLocalizedText(SystemLanguage language)
{
localizedText = new Dictionary<string, string>();
string filePath = Path.Combine(Application.streamingAssetsPath, "localizedText_" + language + ".json");
WWW reader = new WWW(filePath);
if (reader.text == null || reader.text == "") return false;
while (!reader.isDone) { }
string dataAsJson;
dataAsJson = reader.text;
LocalizationData loadedData = JsonUtility.FromJson<LocalizationData>(dataAsJson);
for (int i = 0; i < loadedData.items.Length; i++)
{
localizedText.Add(loadedData.items[i].key, loadedData.items[i].value);
}
Debug.Log("Data loaded, dictionary contains: " + localizedText.Count + " entries");
if (localizedText.Count == 0) return false;
else
{
isReady = true;
return true;
}
}
Yet somehow, all text fields display "Localized Text Not Found" because it cannot find my Assets... what could this be?
Is this because the StreamingAssets folder isn't copied to xCode?
Is it because the location is different on iOS?
Something else?
This is my folder structure
The WWW or UnityWebRequest API is used to read files on the StreamingAssets on Android. For iOS, The any API from the System.IO namespace such as System.IO.File.ReadAllText should be used.
Something like this:
IEnumerator ReadFromStreamingAssets()
{
string filePath = System.IO.Path.Combine(Application.streamingAssetsPath, "MyFile");
string result = "";
if (filePath.Contains("://"))
{
UnityEngine.Networking.UnityWebRequest www = UnityEngine.Networking.UnityWebRequest.Get(filePath);
yield return www.SendWebRequest();
result = www.downloadHandler.text;
}
else
result = System.IO.File.ReadAllText(filePath);
}
Also, the WWW API is made to be used in a coroutine function so that you can wait or yield it until the download is complete. Your while (!reader.isDone) { } can freeze Unity. That should be while (!reader.isDone) yield return null; which waits every frame until download is finished. The LoadLocalizedText function must also be a coroutine function so the return type should be IEnumerator instead of bool. To make it return bool too, use Action<bool> as parameter.
After fixing both issues, below is what the new code should look like:
public IEnumerator LoadLocalizedText(SystemLanguage language, Action<bool> success)
{
localizedText = new Dictionary<string, string>();
string filePath = Path.Combine(Application.streamingAssetsPath, "localizedText_" + language + ".json");
string dataAsJson;
//Android
if (filePath.Contains("://"))
{
WWW reader = new WWW(filePath);
//Wait(Non blocking until download is done)
while (!reader.isDone)
{
yield return null;
}
if (reader.text == null || reader.text == "")
{
success(false);
//Just like return false
yield break;
}
dataAsJson = reader.text;
}
//iOS
else
{
dataAsJson = System.IO.File.ReadAllText(filePath);
}
LocalizationData loadedData = JsonUtility.FromJson<LocalizationData>(dataAsJson);
for (int i = 0; i < loadedData.items.Length; i++)
{
localizedText.Add(loadedData.items[i].key, loadedData.items[i].value);
}
Debug.Log("Data loaded, dictionary contains: " + localizedText.Count + " entries");
if (localizedText.Count == 0)
success(false);
else
{
isReady = true;
success(true);
}
}
And used like this:
StartCoroutine(LoadLocalizedText(languageInstance, (status) =>
{
if (status)
{
//Success
}
}));
JsonUtility has a problem with iOS so it doesn't work
and if you test in local use File.OpenRead(path) works in iOS
filePath = Application.streamingAssetsPath
StreamReader streamReader = new StreamReader(File.OpenRead(string.Format("{0}/{1}.txt", filePath, fileName)));
and streamingAssets read only if you want to write the file in iOS use this path -> Application.persistentDataPath
Actually the problem is that Application.streamingAssetsPath is not fully correct for iOS device. You need to add "file://" manually to the path as well. Please note that it should be done outside of Path.Combine() method because for some reason, Combine() method strips it =) I wasted couple of hours trying to understand what is going wrong and I hope my post will save someone's time. Proper way to do is: filePath = "file://" System.IO.Path.Combine(Application.streamingAssetsPath, "MyFile"); The rest of the code is the same (this is true for AssetBundles as well)
I put some png files into /Assets/StreamingAssets, what i want to do is load a image's texture from that floder.
here is my c# code below:
string path = "file://" + Application.streamingAssetsPath + "/sunny.png";
private IEnumerator GetMatByWWW(string url)
{
WWW www = new WWW(url);
yield return www;
RawImage rawImage = gameObject.GetComponent<RawImage>();
rawImage.texture = www.texture;
}
On OSX, the code working perfect. But i need to make it working on IOS. So i remove the prefix of "file://" and the path is :
string path = Application.streamingAssetsPath + "/sunny.png";
It just showed a red question-mark after build and run at my iPhone. And i also tried
string path = "file:/" + Application.streamingAssetsPath + "/sunny.png";
Who can tell me how to do it correctly?
string ab_path = Application.streamingAssetsPath + "/" + "bundlename";
AssetBundle ab = AssetBundle.LoadFromFile(ab_path);
if(ab == null)
{
Debug.Log("ab is null");
}
Gameobject prefab = ab.LoadAsset<GameObject>("prefab_name");
Gameobject go = GameObject.Instantiate(prefab);
please check this link.
https://docs.unity3d.com/ScriptReference/AssetBundle.LoadFromFile.html
I am trying to get product description from server using web service. This is working fine in unity editor but when i created web player build it's not working.
what should be the problem ? Why it is not working in web player build ?
this is the sample code i am trying :
public void product_detail()
{
string url = "http://*****/api.php?method=get_product_detail&product_id=" + name + "";
Debug.Log(url);
WWW www = new WWW(url);
StartCoroutine(WaitForRequest1(www));
}
IEnumerator WaitForRequest1(WWW www)
{
yield return www;
// check for errors.
if (www.error == null)
{
Debug.Log("WWW data: " + www.data);
Processjson(www.data);
}
else
{
Debug.Log("WWW Error: " + www.error);
}
}
private void Processjson(string jsonString)
{
JsonData jsonvale = JsonMapper.ToObject(jsonString);
var vc = JsonConvert.DeserializeObject(jsonString,typeof(Rootobject)) as Rootobject;
//string status = jsonString;
p_deail = jsonvale["detail"].ToString();
p_price = jsonvale["price"].ToString();
PlayerPrefs.SetString ("P_detail",p_deail);
PlayerPrefs.SetString ("P1_price",p_price);
Component com = GameObject.Find("FPSController").GetComponent("FirstPersonController") as MonoBehaviour;
(com as MonoBehaviour).enabled = false;
PlayerPrefs.SetString("Product",prefab.name.ToString());
GUIWindow.SetActive(true);
GameObject clone = Instantiate (prefab, Vector3.zero, Quaternion.identity) as GameObject;
clone.AddComponent<zoomC>();
clone.AddComponent<rotatC>();
clone.transform.position = Camera.main.transform.position + Camera.main.transform.forward*1.0f + Camera.main.transform.right*-0.5f + Camera.main.transform.up*-0.2f;
clone.transform.rotation = new Quaternion( Camera.main.transform.rotation.x, Camera.main.transform.rotation.y, Camera.main.transform.rotation.z, Camera.main.transform.rotation.w );
clone.transform.localScale = new Vector3(0.5f,0.5f,0.5f);
}
In my program, I want to save some screenshots and load them later on to compute somethings. I created a methode to compute the image names:
static public string generatePhotoName (string cameraName, float time)
{
return "G:/Data/unity/cameraDemo/" +
DataController.measurmentPath +
"/photos" + "/" +
cameraName + "/" +
time.ToString () + "_" + cameraName + ".png";
}
This worked fine for saving, but when I try to load an image, File.Exists (filePath)returns false.
But when I hardcoded the filepath, loading works fine too:
static public string generatePhotoName (string cameraName, float time)
{
return "G:/Data/unity/cameraDemo/demo/photos/Camera/test.png";
}
It even works with "real" image names(i.e. 3.827817_Camera.png).
Using Path.Combine(...) and changing "/" to "\" did not change anything...
// edit: this is my load methode
static public Texture2D loadPhotoToTexture (string filePath)
{
Texture2D tex = null;
byte[] fileData;
if (File.Exists (filePath)) {
fileData = File.ReadAllBytes (filePath);
tex = new Texture2D (2, 2);
tex.LoadImage (fileData); //..this will auto-resize the texture dimensions.
} else {
Debug.Log (filePath + " does not exist");
}
return tex;
}`
// edit2: some more code
This is how I call the methode
Texture2D photo = DataController.loadPhotoToTexture(photoData.getFileName ());
And this is my class PhotoData
public class PhotoData : BaseData
{
private string _cameraName;
public string cameraName {
get { return _cameraName; }
set { _cameraName = value; }
}
private float _time;
public float time {
get { return _time; }
set { _time = value; }
}
public PhotoData ()
{
}
public PhotoData (string cameraName, float time)
{
_cameraName = cameraName;
_time = time;
}
public string getFileName ()
{
return PlayerController.generatePhotoName (_cameraName, _time);
}
}
The problem was, that I tried to save and load the screenshots in one Update()-call.
I fixed it by changing it to right-click to take and save a screenshot and left-click to load the screenshot.
If you want to store images to a certain file on disk, not inside your game folder structure, do this: create a folder, and store its location (filepath). For example:
string screenshotFileName = time.ToString () + "_" + cameraName + ".png"
string screenshotDirectory;
screenshotDirectory = #"C:\someFolder\anotherFolder\";
try { Directory.CreateDirectory(directory); }
catch (Exception e)
{ //you should catch each exception separately
if (e is DirectoryNotFoundException || e is UnauthorizedAccessException)
Debug.LogError("OMG PANIC");
}
FileInfo filepath = new FileInfo(screenshotDirectory+screenshotFileName);
if(filepath.Exists)
{
//load the file
}
You could also simply create a folder, with a relative path, which will be in the same folder as your executable, by changing the screenshotDirectory to
screenshotDirectory = #"screenshots\"+cameraName+#"\";
Edit:
You seem to load the texture correctly. Are you assigning it to the material's main texture? Where is your code encountering the problem? For example if you're running this script on the same object that you want the texture to be applied:
this.GetComponent<Renderer>().material.mainTexture = loadedTexture;
Also, when you want to load images, it's best that you use the Resources folder, which uses forwards slashes, not . Store everything that you might want to load on runtime there, and use Resources.Load().