Unity : From large image to map / terrain / texture - c#

In Unity, I'd like to generate 2D map from a large image file (965012573).
I already have a tile/image pieces generator but it generates 1900 images 256256, and it seems hard to create a map by hand like this (and I have more then one large image to process...).
These image pieces are sorted like this :
x/y.png
Where x starts from left to right and y from top to bottom.
As MelvMay suggests me here, I should use textures to achieve that, but how?
Do you have any idea of how to achieve that programmatically? Or may be with an existing bundle?
Thanks a lot!
[edit] As a workaround, I tried this :
public class MapGenerator : MonoBehaviour {
private Renderer m_Renderer;
private Texture2D m_MainTexture;
// Use this for initialization
void Start () {
//Fetch the Renderer from the GameObject
m_Renderer = GetComponent<Renderer> ();
m_MainTexture = LoadPNG("Assets/Tiles/Ressources/Map/0/3.png");
m_Renderer.material.mainTexture = m_MainTexture;
}
private Texture2D LoadPNG(string filePath) {
Texture2D tex = null;
byte[] fileData;
if (File.Exists(filePath)) {
UnityEngine.Debug.Log(filePath);
fileData = File.ReadAllBytes(filePath);
tex = new Texture2D(2, 2);
tex.LoadImage(fileData); //..this will auto-resize the texture dimensions.
}
return tex;
}
}
But even if I apply it on an empty object, I only see my dynamic texture in the inspector, not in the scene when I press run...

Related

How do I stop a camera from rendering to a RenderTexture?

I have a camera in my scene that has a Target Texture set as a Render Texture. I want that camera to render the scene into the Render Texture, but then stop rendering anymore, essentially freezing the frame into the Render Texture. How can I achieve this? Disabling the camera or setting its target texture to null seems to just make the Render Texture appear invisible.
If you want to have like a snapshot function you could do it like this
public class SnapshotController : MonoBehaviour
{
[Tooltip("If you want to capture a specific camera drag it here, otherwise the MainCamera will be used")]
[SerializeField] private Camera _camera;
[Tooltip("If you have a specific RenderTexture for the snapshot drag it here, otherwise one will be generated on runtime")]
[SerializeField] private RenderTexture _renderTexture;
private void Awake()
{
if(!_camera) _camera = Camera.main;
if(!_renderTexture)
{
_renderTexture = new RenderTexture(Screen.width, Screen.height , 24 , RenderTextureFormat.ARGB32);
_renderTexture.useMipMap = false;
_renderTexture.antiAliasing =1;
}
}
public void Snapshot(Action<Texture2D> onSnapshotDone)
{
StartCoroutine(SnapshotRoutine(onSnapshotDone));
}
private IEnumerator SnapshotRoutine (Action<Texture2D> onSnapshotDone)
{
// this also captures gui, remove if you don't wanna capture gui
yield return new WaitForEndOfFrame();
// If RenderTexture.active is set any rendering goes into this RenderTexture
// instead of the GameView
RenderTexture.active = _renderTexture;
_camera.targetTexture = _renderTexture;
// renders into the renderTexture
_camera.Render();
// Create a new Texture2D
var result = new Texture2D(Screen.width,Screen.height,TextureFormat.ARGB32,false);
// copies the pixels into the Texture2D
result.ReadPixels(new Rect(0,0,Screen.width,Screen.height),0,0,false);
result.Apply();
// reset the RenderTexture.active so nothing else is rendered into our RenderTexture
RenderTexture.active = null;
_camera.targetTexture = null;
// Invoke the callback with the resulting snapshot Texture
onSnapshotDone?.Invoke(result);
}
}
You would then use it like e.g.
// Pass in a callback telling the routine what to do when the snapshot is ready
xy.GetComponent<SnapshotController>(). Snapshot(HandleNewSnapshotTexture);
...
private void HandleNewSnapshotTexture (Texture2D texture)
{
var material = GetComponent<Renderer>().material;
// IMPORTANT! Textures are not automatically GC collected.
// So in order to not allocate more and more memory consider actively destroying
// a texture as soon as you don't need it anymore
if(material.mainTexture) Destroy (material.mainTexture);
material.mainTexture = texture;
}
You can take a snapchot of the actual render texture in the frame where you start freezing, get this image data and replace the render texture by an actual texture with this freeze image applied.

How to encode to png a webcam texture?

Setup: Unity 2019
I am trying to get the texture from a plane.
I capture the camera input and map it on a plane. Then i want to read the texture continuously.
I tried something like this. PS: I am new with unity.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraInput : MonoBehaviour
{
static WebCamTexture backCam;
void Start()
{
if (backCam == null)
backCam = new WebCamTexture();
GetComponent<Renderer>().material.mainTexture = backCam;
if (!backCam.isPlaying)
backCam.Play();
}
void Update()
{
byte[] bytes = GetComponent<Renderer>().material.mainTexture.EncodeToPNG();
System.IO.File.WriteAllBytes(path, bytes);
Debug.Log(bytes.Length/1024 + "Kb was saved as: " + path);
}
}
Error received:
Unable to retrieve image reference
UnityEngine.ImageConversion:EncodeToPNG(Texture2D)
I think you are missing a few steps
get list of available devices
set device name into webcam
play the webcam before setting the texture
Webcam is a Texture and you can encodetopng Texture2d.
So the solution to this is:
Texture2D tex = new Texture2D(backCam.width, backCam.height);
tex.SetPixels(backCam.GetPixels());
tex.Apply();
byte[] bytes = tex.EncodeToPNG();

Change Texture2D format in unity

I have a Textured2D loaded which is represented in ETC_RGB4 how can I change this to another format? say RGBA32. Basically I want to switch from 3 channels to 4 and from 4 bit per channel to 8 per channel.
Thanks
You can change texture format during run-time.
1.Create new empty Texture2D and provide RGBA32 to the TextureFormat argument. This will create an empty texture with the RGBA32 format.
2.Use Texture2D.GetPixels to obtain the pixels of the old texture that's in ETC_RGB4 format then use Texture2D.SetPixels to put those pixels in the newly created Texture from #1.
3.Call Texture2D.Apply to apply the changes. That's it.
A simple extension method for this:
public static class TextureHelperClass
{
public static Texture2D ChangeFormat(this Texture2D oldTexture, TextureFormat newFormat)
{
//Create new empty Texture
Texture2D newTex = new Texture2D(2, 2, newFormat, false);
//Copy old texture pixels into new one
newTex.SetPixels(oldTexture.GetPixels());
//Apply
newTex.Apply();
return newTex;
}
}
USAGE:
public Texture2D theOldTextue;
// Update is called once per frame
void Start()
{
Texture2D RGBA32Texture = theOldTextue.ChangeFormat(TextureFormat.RGBA32);
}

Download and open png image?

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.

XNA: How to change texture reference midgame?

I'm currently making a game in XNA. I have been going well so far but I don't know how to change the texture of a sprite whilst running the game. An example of this would be. When the character is still that's one image, then when he walks that's a different image. How would I make this happen?
Run checks and just set the instance's Texture2D texture to some other texture from your preloaded library.
I usually load all the textures in my content folder into a dictionary and use like so:
var StringTextureDic = new Dictionary<string, Texture2D>();
// code that loads all textures into the dictionary, file names being keys
// whenever I need to assign some texture, I do this:
if (!playerIsMoving)
Player.texture = StringTextureDic["player standing"];
if (playerIsMoving)
Player.texture = StringTextureDic["player moving"];
Well, actually, change the player texture midgame is a bad idea. In such cases, i prefer to use a texture sheet.
Rectangle frame;
int curFrame;
int frameWidth;
int frameHeight;
int runAnimationLength;
Update()
{
//Handle your "animation code"
if(playerIsMoving)
curFrame++; //Running
if(curFrame == runAnimationLength)
curFrame =0;
else
curFrame = 0; //Standing still
}
Draw(SpriteBatch spriteBatch)
{
frame = new Rectangle(curFrame*frameWidth,curFrame*frameHeight,frameWidth,frameHeight);
spriteBatch.Draw(
texture,
position,
**frame**,
color,
rotation,
origin,
SpriteEffects.None,
1);
}

Categories

Resources