I can successfully load a material saved in my Unity project using the code below:
RenderSettings.mat1 = (Material)Resources.Load ("images/img1.jpg", typeof(Material));
However, I am now trying to load an external image by downloading it.
Texture2D imgDownloaded;
string url = "http://www.intrawallpaper.com/static/images/1968081.jpg";
void Start()
{
StartCoroutine(getImg());
fucntionx ();
}
public void functionx()
{
RenderSettings.mat1 = (Material)imgDownloaded;
}
IEnumerator getImg()
{
yield return 0;
WWW dl = new WWW(url);
yield return dl;
imgDownloaded = dl.texture;
}
However, I get the message that I cannot convert from Texture2D to Material .
Is there any way to fix this?
Try:
yourMaterial.mainTexture = yourTexture;
A material consists of many textures, so naturally you can't convert between them.
Related
i am creating a video game like Crypt of the necrodancer and i am blocked when i want to generate a map
my idea was simple :
make a grid system and replace some tiles to have specific tiles (obstacle, wall...) but i don't know how i should store the information to replace my tile.
I based my grid generation map from Sebastian Lague tutorial
i would like to replace in the inspector my tiles
as far as i am, i've found a script for replacing some tiles by another but i can't save it...
Here is the script for replacing stuff
using UnityEngine;
using UnityEditor;
public class ReplaceWithPrefab : EditorWindow
{
[SerializeField] private GameObject prefab;
[MenuItem("Tools/Replace With Prefab")]
static void CreateReplaceWithPrefab()
{
EditorWindow.GetWindow<ReplaceWithPrefab>();
}
private void OnGUI()
{
prefab = (GameObject)EditorGUILayout.ObjectField("Prefab", prefab, typeof(GameObject), false);
if (GUILayout.Button("Replace"))
{
var selection = Selection.gameObjects;
for (var i = selection.Length - 1; i >= 0; --i)
{
var selected = selection[i];
var prefabType = PrefabUtility.GetPrefabType(prefab);
GameObject newObject;
if (prefabType == PrefabType.Prefab)
{
newObject = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
}
else
{
newObject = Instantiate(prefab);
newObject.name = prefab.name;
}
if (newObject == null)
{
Debug.LogError("Error instantiating prefab");
break;
}
Undo.RegisterCreatedObjectUndo(newObject, "Replace With Prefabs");
newObject.transform.parent = selected.transform.parent;
newObject.transform.localPosition = selected.transform.localPosition;
newObject.transform.localRotation = selected.transform.localRotation;
newObject.transform.localScale = selected.transform.localScale;
newObject.transform.SetSiblingIndex(selected.transform.GetSiblingIndex());
Undo.DestroyObjectImmediate(selected);
}
}
GUI.enabled = false;
EditorGUILayout.LabelField("Selection count: " + Selection.objects.Length);
}
}
any ideas for how i could save the informations?
Unity recently added a tilemap system a few versions ago. It seems to be what you're looking for and it already handles the grids for you.
You can read more about it here:
https://docs.unity3d.com/Manual/class-Tilemap.html
You can edit the tilemap with the SetTile method and a Tile object, rather than instanciating a bunch of prefabs. The Tiles themselves are created with a tile palette which you can also read more about in the page above.
I am very new to Unity and after doing some research I found a lot of discussion on how I shouldn't use Resources.Load and instead use Addressables.
Previously I was loading card art with
cardPrefab.cardArt.sprite = Resources.Load<Sprite>("CardSprite/Justice");
However I can't seem to get Addressable to work. Trying the following gives me an error:
Sprite Test = Addressables.LoadAssetAsync<Sprite>("CardSprite_Justice");
I get this error:
Cannot implicitly convert type 'UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle<UnityEngine.Sprite>' to 'UnityEngine.Sprite'
Which is really confusing.
Get it with callback
private void Sprite_Completed(AsyncOperationHandle<Sprite> handle)
{
if (handle.Status == AsyncOperationStatus.Succeeded)
{
Sprite result = handle.Result;
// Sprite ready for use
}
}
void Start()
{
AsyncOperationHandle<Sprite> SpriteHandle = Addressables.LoadAsset<Sprite>("CardSprite_Justice");
SpriteHandle.Completed += Sprite_Completed;
}
and you can use coroutines or task to get it , watch document :
https://docs.unity3d.com/Packages/com.unity.addressables#0.7/manual/AddressableAssetsAsyncOperationHandle.html
void Start()
{
Addressables.LoadResourceLocationsAsync("SpriteName",typeof(Sprite)).Completed += SpriteLocation;
}
void SpriteLocation(AsyncOperationHandle<IResourceLocation> obj)
{
Addressables.LoadAssetAsync<Sprite>(_spriteName).Completed += obj => item.mysprite.sprite = obj.Result;
}
I want to show a list of achievements each one with a different image. I've downloaded the images from the server but they appear very slow in my game. Is it a way to show them faster? Thank you in advance.
This is my code:
public GameObject filePrefab;
public GameObject contentRef;
private Texture2D downloadedImages;
public void AchievementsList_Bttn()
{
new GameSparks.Api.Requests.LogEventRequest ()
.SetEventKey ("LISTACHIEVEMENTS")
.Send ((response) => {
if(!response.HasErrors)
{
Debug.Log("List Achivements Loaded Sucessfully...");
GSData scriptData = response.ScriptData;
List<GSData> achievements = scriptData.GetGSDataList("achievements"); //retrieve the array of objects
for (int i = 0; i < achievements.Count; i++)
{
string name = achievements[i].GetString("name");
string description = achievements[i].GetString("description");
int? currency1Award = achievements[i].GetInt("currency1Award");
bool? earned = achievements[i].GetBoolean("earned");
GameObject tempFile = Instantiate (filePrefab, contentRef.transform);
Text tempName = tempFile.transform.GetChild(0).GetComponent<Text>();
Text tempDescription = tempFile.transform.GetChild(1).GetComponent<Text>();
Text tempCurrency1Award = tempFile.transform.GetChild(2).GetComponent<Text>();
RawImage tempImage = tempFile.transform.GetChild(3).GetComponent<RawImage>();
tempName.text = name;
tempDescription.text = description;
tempCurrency1Award.text = currency1Award.ToString();
DownloadtheFiles(name, tempImage);
}
}
});
}
public void DownloadtheFiles(string name, RawImage tempImage)
{
new GetDownloadableRequest()
.SetShortCode(name+"_icon")
.Send((response) => {
if(!response.HasErrors)
{
StartCoroutine(DownloadImages((response.Url), tempImage));
}
});
}
public IEnumerator DownloadImages(string downloadUrl, RawImage tempImage)
{
var www = new WWW(downloadUrl);
yield return www;
downloadedImages = new Texture2D(200, 200);
www.LoadImageIntoTexture(downloadedImages);
tempImage.texture = downloadedImages as Texture;
}
And this is what I want to show:
Minor point, but definitely slow and seen to o often:
string name = achievements[i].GetString("name");
makes a dictionary lookup in the loop. Get the ordinals of the fields outside the loop, pu them into a variable and then use GetString(variable) (with the variable being integer type) - faster lookips.
Use a profiler.
Likely DownloadTheFiles is the bottleneck (do NOT make us do your basic work) and there is no way around this outside of hiding it (i.e. preloading or something else). It is, without you doing the base work and actually doing some debugging and profiling, the only thing that stands out because it does need to really do a network round drop for every image.
Need your help.
I am making simple application (and I'm a new to Unity3d also), which takes video from IP-camera and displays it onto Texture2D.
Video format is MJPG.
For simple jpg-images the code below works fine, but when I try to display MJPG I just get gray screen.
Did I make a mistake in code?
public class testVid : MonoBehaviour {
//public string uri = "http://24.172.4.142/mjpg/video.mjpg"; //url for example
public Texture2D cam;
public void Start() {
cam = new Texture2D(1, 1, TextureFormat.RGB24, false);
StartCoroutine(Fetch());
}
public IEnumerator Fetch() {
while(true) {
Debug.Log("loading... " + Time.realtimeSinceStartup);
WWWForm form = new WWWForm();
WWW www = new WWW("http://24.172.4.142/mjpg/video.mjpg");
yield return www;
if(!string.IsNullOrEmpty(www.error))
throw new UnityException(www.error);
www.LoadImageIntoTexture(cam);
}
}
public void OnGUI() {
GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), cam);
}
}
I used this plugin https://www.assetstore.unity3d.com/en/#!/content/15580
Add the script to a game object
Set the URL of the video in the script
Create a new material of Unlit 2D
Add this material to the movie script in the inspector
Then assign the same material to the game object you
want to display the video (e.g. a quad)
Hope it helps
In Unity, this script loads on the start of the program. I want to download an image, and after that show it on the main screen. What should I do? The following code did not work.
My code:
using UnityEngine;
public class PushNotifications : MonoBehaviour {
IEnumerator Start () {
Texture2D textWebPic = null;
WWW image = new WWW("http://www.test.com/image.png");
yield return image;
image.LoadImageIntoTexture(textWebPic);
}
void Update () {
}
}
You can't pass null to LoadImageIntoTexture, since then Unity has no idea where to put the output (it is not ref). The texture must be initialized first.
It does not really matter, however, with what size or format you initialize it, unity will resize it anyway. So you can initialize some dummy, like this to load the image:
IEnumerator Start () {
Texture2D textWebPic = new Texture2D(2,2);
WWW image = new WWW("http://www.test.com/image.png");
yield return image;
image.LoadImageIntoTexture(textWebPic);
}
Another, and probably better option is to use WWW.texture instead of LoadImageIntoTexture, like this:
IEnumerator Start () {
WWW image = new WWW("http://www.test.com/image.png");
yield return image;
Texture2D textWebPic = image.texture;
}
See WWW class reference for more examples:
http://docs.unity3d.com/ScriptReference/WWW.html
And then to show it on the screen you have multiple option - creating a material with this texture, creating sprite from texture (best for 2d games) or simply use Graphics.DrawTexture.