Unity3D trying to load a texture resource after build - unity3d

I have a material that is using a texture (image) located in the Resources directory under Assets. Using Resources.load works while in the editor. The texture also loads properly on a build, but I would like to replace that image after the build by placing a different image (with the same name) in the built Resources directory.
On Windows, I think that directory is buildname_Data>Resources and on Mac I'm thinking it's Contents>Resources (after opening Package Contents). This works for a text file I'm using to load some data at startup, but the process is a bit different there as I'm not using Resources.load in that case.
The problem I'm having is that just placing a new image in the (i think) proper location does not override the image that the app was built with. I'm still seeing the original image. I've been scratching my head over this for the past couple days, and the Documentation (as well as various google searches) have not yielded insight into a solution (although it's likely staring me right in the face).
var MyTexture : Texture = Resources.Load("colorPatch");
var wbpLineRenderer : LineRenderer = someGameObject.AddComponent(LineRenderer);
wbpLineRenderer.material = new Material (Shader.Find("Particles/Alpha Blended"));
wbpLineRenderer.material = Resources.Load("curveLine") as Material;
wbpLineRenderer.material.mainTexture = MyTexture;
curveLine is a material in the Assets/Resources directory of the Editor.
colorPatch is an image file named colorPatch.png in the Assets/Resources directory of the Editor
Can someone please screw my head on straight about this? Can I actually swap an image used on a texture after build?

After a good breakfast and a bit more googling I have (re)discovered the solution, detailed here.
my implementation is as follows:
var textureURL : String = "file://" + Application.dataPath + "/Resources/colorPatch.png";
var www : WWW = new WWW(textureURL);
var tempTexture : Texture2D = new Texture2D(2, 2); //doesn't have to be the actual size
www.LoadImageIntoTexture(tempTexture); //image loads at 100% not 2x2 specified above
var wbpLineRenderer : LineRenderer = wellBorePath.AddComponent(LineRenderer);
wbpLineRenderer.material = new Material (Shader.Find("Particles/Alpha Blended"));
wbpLineRenderer.material = Resources.Load("curveLine") as Material;
wbpLineRenderer.material.mainTexture = tempTexture;
Once the app is built, place an image named colorPatch.png in the location:
Windows - appname_Data/Resources
Mac - Contents/Resources (after opening Package Contents).
Switching out the image colorPatch.png with another image (but still titled colorPatch.png) then launching the app, displays the new image as the texture.

Related

How can I make assets accessible to players for modding?

My game includes image files and json configuration files that I would like to make accessible in the deployed game's folder structure so that players can easily edit or swap them out.
I have considered/tried the following approaches:
My initial approach was to use the Resources folder and code
such as Resources.Load<TextAsset>("Rules.json"). Of course,
this did not work as the resources folder is compiled during builds.
I investigated the Addressables and AssetBundle features, but they do not seem aimed at solving this problem.
After asking around, I went for using .NET's own file methods, going
for code like File.ReadAllText(Application.dataPath + Rules.json). This seems like it will work, but such files are still not deployed automatically and would have to manually be copied over.
It seems that the StreamingAssets folder exists for this, since the manual advertises that its contents are copied verbatim on the target machine. I assume that its contents should be read as in the previous point, with non-Unity IO calls like File.ReadAllText(Application.streamingAssetsPath + Rules.json)?
So yeah, what is the 'canonical' approach for this? And with that approach, is it still possible to get the affected files as assets (e.g. something similar to Resources.Load<Sprite>(path)), or is it necessary to use .NET IO methods to read the files and then manually turn them into Unity objects?
After asking the same question on the Unity forums, I was advised to use the StreamingAssets folder and told that it is necessary to use .NET IO methods with it.
An example for how to load sprites as files using standard IO can be seen here: https://forum.unity.com/threads/generating-sprites-dynamically-from-png-or-jpeg-files-in-c.343735/
static public Sprite LoadSpriteFromFile(
string filename,
float PixelsPerUnit = 100.0f,
SpriteMeshType type = SpriteMeshType.FullRect)
{
// Load a PNG or JPG image from disk to a Texture2D, assign this texture to a new sprite and return its reference
Texture2D SpriteTexture = LoadTexture(filename);
Sprite NewSprite = Sprite.Create(
SpriteTexture,
new Rect(0,
0,
SpriteTexture.width,
SpriteTexture.height),
new Vector2(0, 0),
PixelsPerUnit,
0,
type);
return NewSprite;
}
static private Texture2D LoadTexture(string FilePath)
{
// Load a PNG or JPG file from disk to a Texture2D
// Returns null if load fails
Texture2D Tex2D;
byte[] FileData;
if (File.Exists(FilePath))
{
FileData = File.ReadAllBytes(FilePath);
Tex2D = new Texture2D(2, 2);
// If the image is blurrier than what you get with a manual Unity import, try tweaking these two lines:
Tex2D.wrapMode = TextureWrapMode.Clamp;
Tex2d.filterMode = FilterMode.Bilinear;
// Load the imagedata into the texture (size is set automatically)
if (Tex2D.LoadImage(FileData))
{
return Tex2D; // If data = readable -> return texture
}
}
return null;
}

How to persist markers using ADF in TangoARPoseController

I am trying to persist markers in an augmented reality game. Here is the gist of what I am doing:
I have my users recording and saving an area to an ADF. Then they drop marker’s into the scene and save out their position data in Unity World coordinates to a text file. I then restart the app, load and localize to the ADF and load the markers.
In order to get this working, I've modified the ARPoseController.cs file in the Unity demo package to use the Area Description as it's base frame. In the _UpdateTransformation method I've swapped out the frame pairs
pair.baseFrame = TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_START_OF_SERVICE;
pair.targetFrame = TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_DEVICE;
for
pair.baseFrame = TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_AREA_DESCRIPTION;
pair.targetFrame = TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_DEVICE;
I've also added some code confirming that I'm successfully localizing to the ADF, but I'm noticing that my markers position in Unity World Space do not position properly relative to real environment.
I can confirm that my markers save and load properly based on START_OF_SERVICE origin so I assume that they are properly serializing and deserializing. What could be causing this? Am I wrong in assuming this should just work by switching the base framepair to Area_Description instead of START_OF_SERVICE?
I had a similar problem getting the AR and ADF integrated, I had to modify the TangoPointCloud to check if you're using an AreaDescription in OnTangoDepthAvailable() and adjust the baseFrame target as required.
i.e.:
if (m_tangoDeltaPoseController.m_useAreaDescriptionPose)
{
pair.baseFrame = TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_AREA_DESCRIPTION;
pair.targetFrame = TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_DEVICE;
}
else
{
pair.baseFrame = TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_START_OF_SERVICE;
pair.targetFrame = TangoEnums.TangoCoordinateFrameType.TANGO_COORDINATE_FRAME_DEVICE;
}
That way, the geometry of the point cloud adjusts itself based on the ADF offset instead of from device start.
After that change, when I'm using the sample code for AR to drop markers, it registers the surface properly so I'm placing the markers in the correct spots and orientation. I'm still encountering some flakiness with the markers not adjusting when relocalized though, have to look into the AreaLearningInGameController for loop closure events.
Hope that helps!

Unity 4.6 assets not getting applied in Windows 8.1 export

I am building a game in which I need to change its theme at runtime according to player's choice. Here is a chunk of code to change background image:
string path;
string themeName;
themeName = PlayerPrefs.GetString("Theme_Name");
//Change Background Image
path = "Assets/Textures/" + themeName + "/Background.jpg";
Background_Image.GetComponent<Image>().sprite = Resources.LoadAssetAtPath<Sprite>(path);
This works perfectly in Unity however no image gets applied to the background when I export the game for Windows 8.1. The variable 'path' evaluates to "Assets/Textures/Default/Background.jpg" which is the right path and works for Unity project but not Windows.
Do I need to separately export my images folder or use a different path after exporting game or something? Might be a very stupid thing but I am kinda lost here
Use Resources.Load instead. Resources.LoadAssetAtPath works only in the Editor.
Create a folder called "Resources" under the "Assets" folder. Move all your images to this folder.
Then change your code to the below
path = themeName + "/Background.jpg";
Background_Image.GetComponent<Image>().sprite = Resources.Load<Sprite>(path);
The above code assumes that you have a subfolder named with your themes inside the Resources folder.
For example, if one of your themes is called "Theme1", then the background Image should be stored in {Your_Project_Folder}/Assets/Resources/Theme1/Background.jpg

Storing images in windows phone 8

I have been really cracking my head trying to write and read png files into a folder in Windows Phone 8. From few blogs sites and codeplex i found that the there is an extension to the WritableBitmap Class which provides few extra functionalities. ImageTools has PNG encoder and decoder. But I really cant find examples to use them.
What Im trying to achieve here is to create a folder called page and then in it a file called Ink File. I want to convert the bitmap to a PNG and store it there. The bitmap is created from the strokes drawn on a canvas. The class ImageTools provides a function called ToImage to convert the strokes from the canvas to image.
For storing
ExtendedImage myImage = InkCanvas.ToImage();
var encoder = new PngEncoder();
var dataFolder = await local.CreateFolderAsync("Page", CreationCollisionOption.OpenIfExists);
StorageFile Ink_File = await dataFolder.CreateFileAsync("InkFile", CreationCollisionOption.ReplaceExisting);
using (var stream = await Ink_File.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite))
{
using (var s = await Ink_File.OpenStreamForWriteAsync())
{
encoder.Encode(myImage, s);
await s.FlushAsync();
s.Close();
}
}
Is this a correct method? I receive some null exceptions for this. How do i find if the image is saved as png. How is this image saved? Is it encoded and saved in a file or is it saved as a png itsef. And how do we read this back?
I have checked out this, this , this and lot more like this.
I'm developing app for WP8
I have used the PNG Writer Library found in ToolStack and it works :)

ClearCanvas DICOM Library - How to use Overlay Planes?

NOTE:: This may be a better question to answer:: Free DICOM files, with Multiple Overlays
Hi, I have a question relating to tag DicomTags.OverlayData & Overlay Planes.
As of now I can get back overlay data from a DICOM file in ClearCanvas and uncompress & display it using:
var overlayData = dicomFile.DataSet[DicomTags.OverlayData];
I also use other tags in the DICOM file for Overlays such as, OverlayOrigin, OverlayColumns, OverlayRows etc...
So my question is, how do OverlayPlanes come into play here? All these Overlay tags seem to be global & not grouped in a OverlayPlane tag or something.
Is plane data layered in the OverlayData tag?? I'm new to DICOM & a little confused about this.
The ClearCanvas DICOM assembly has several helper IOD classes that make it a bit easier to access specific modules within a DICOM Message. The OverlayPlaneModuleIod class is one such IOD class that make it easier to access all of the tags together within an overlay plane. The following code shows an example of how to use this class to check and access an each of the potential overlay planes, without having to worry about the various tags involved:
DicomFile theFile = new DicomFile("filename.dcm");
theFile.Load();
OverlayPlaneModuleIod iod = new OverlayPlaneModuleIod(theFile.DataSet);
for (int i = 0; i &lt 16; i++)
{
if (iod.HasOverlayPlane(i))
{
OverlayPlane overlay = iod[i];
byte[] overlayData = overlay.OverlayData;
string description = overlay.OverlayDescription;
}
}
This link answered my question for the most part as I needed to just understand something about overlay grouping.
http://www.medicalconnections.co.uk/wiki/Number_of_Overlays_in_Image