Transparency not rendering properly in WebGL - unity3d

I am making a 3D puzzle video game and I wish to show a translucent copy of the puzzle piece on its original position when the puzzle piece is near its original position. In other words, to show the player that they are on the right track.
I have done so and it is working fine, here's a 4 second quick gif for demonstration.
However, it does not work when I deploy the game to WebGL. The copy of the object which should be translucent simply isn't.
Here is the function which I use to create a translucent copy of the object. I found the code in this forum thread.
Basically what I am doing is instantiating a copy, deleting uncecessary components, manually changing the material settings to make the object use the Transparent rendering mode, changing the opacity to 0, and then disabling the renderer because for some reason the object is not fully transparent when opacity is set to 0.
GameObject CreateHighlight(GameObject gameObject)
{
GameObject highlight = Instantiate(gameObject);
Destroy(highlight.GetComponent<Rigidbody>());
Destroy(highlight.GetComponent<MeshCollider>());
Destroy(highlight.GetComponent<StayInside>());
Destroy(highlight.GetComponent<ObjectControl>());
// Change render mode to Transparent
Material material = highlight.GetComponent<Renderer>().material;
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
material.SetInt("_ZWrite", 0);
material.DisableKeyword("_ALPHATEST_ON");
material.DisableKeyword("_ALPHABLEND_ON");
material.EnableKeyword("_ALPHAPREMULTIPLY_ON");
material.renderQueue = 3000;
// Change alpha to 0
highlight.GetComponent<MeshRenderer>().material.color = new Color(1.0f, 1.0f, 1.0f, 0.0f);
// Stop rendering the object because setting alpha to 0 does not make the object fully transparent
highlight.GetComponent<MeshRenderer>().enabled = false;
return highlight;
}
I have stumbled upon this Reddit thread and the guy had the same problem as I did. He said he switched the rendering path from Deferred to Forward. I found somewhere one is supposed to change that setting in the MainCamera, so I did. Mine was set on Use Graphics Settings so I explicitly set it to Forward, but nothing changed.

OctangularPRISM Redditor saved the day on Reddit.
What he suggested was creating a new material, making it transparent and then in the code instantiating that material and applying it to the highlighted object instead of changing the rendering mode to Transparent as I tried.
Here are the steps in more detail:
I first created public Material matTransparentMat; as a public variable in my ObjectControl script. This means an additional menu to add a Material was created on all the objects that have the ObjectControl script.
Then, in the project window I created a new Material and made it transparent. You just go Right Click -> Create -> Material, and then choose the material and in the inspector press where it says Opaque and choose Transparent in the drop down menu, and then click the white color and change the alpha from 255 to 0.
Then, drag and drop that Material to the Mat Transparent Mat public variable in the editor.
Now, I changed the code which was changing the rendering mode to Transparent, to /u/OctangularPRISM's code which will instantiate a new material and apply it to the copy of the object.
public Material matTransparentMat;
GameObject CreateHighlight(GameObject GO)
{
GameObject highlight = Instantiate(GO);
Destroy(highlight.GetComponent<Rigidbody>());
Destroy(highlight.GetComponent<MeshCollider>());
Destroy(highlight.GetComponent<StayInside>());
Destroy(highlight.GetComponent<ObjectControl>());
Renderer targetRend = highlight.GetComponent<Renderer>();
Renderer srcRend = GO.GetComponent<Renderer>();
Material newMat = Instantiate(matTransparentMat);
newMat.mainTexture = srcRend.material.mainTexture;
targetRend.material = newMat;
return highlight;
}
Done!

Related

how to change the color of the object while keeping the original material in unity

Clicking an object with the mouse changes the color of the clicked object
When you select it again, I am making the color of the clicked object and turning it back to the original color of white.
Simply(change the selected object color)
Material mat = objectManager.ReturnMat(obj);
mat.color=color.white
Originally, if you made a uv map for each object, there was no problem even if you changed the mat.color in duplicate.
This time, an object without a uv map is used separately, so if mat.color is applied, the original color is
For example, in the uv map, the specified color is painted with uv, so it was not strange because it was overlaid even if the color was changed.
Objects without a uv map change color, so the original color is blown away.
I don’t know exactly about the shader or texture material
I ask you a question.
Is there a way to change the color without losing the original color of the object through these?
I don't know how many objects can be clicked, but if you save the material for each click, you can enter about one.
Emission is not naturally that color is overlap orignial color
Following #4RZG4 answer:
If it's a performance issue, you can make a Dictionary<int, Color> of Colors, and every time you change the Color of your object, save it on the list, with the correspondent GameObject ID.
When GameObject uses the saved Color, remove it from the Dictionary. This way you will only have the references of the currently changed Colors, instead of every one that can be potentially changeable.
Your post was kind of unclear and I don't quite understand what you want, but I assume that you want to keep the original color of the object after you have changed the color to something else.
Implementing this is fairly easy; Just save the material in the Start function like this:
void Start()
{
Material Temp = mat;
}
Now the original material is stored in a variable named Temp.
If you want to return mat to its original value, you can do like this:
mat = temp;

Change line renderer alpha unity

Unity's line renderer component has got a material to attach, so that the line renderer uses it to show the line renderer in the scene accordingly:
The problem is that if you change this material color it works, also in runtime it can be changed in the editor itself. But not so with the alpha.
It does not respond neither in the edit nor in the code.
I tried:
Color targetColor = new Color(0,0,0,a);
_unityEngineLineRender.sharedMaterial.SetColor("Color", targetColor);
and:
Color targetColor = new Color(0,0,0,a);
_unityEngineLineRender.sharedMaterial.color = targetColor;
and it doesn't work.
Can thisn simple thing be done? if so, how?
Thanks in advance
The shader for your material probably does not support alpha, that's why you're not getting any transparency.
The workaround is to write your own shader or use other that's built into Unity.
Create a new material for your line renderer and select shader "Particles/Standard Unlit", set "Rendering mode" to "Fade". Then use it on Line Renderer instead of the default material.
You can access the color using:
renderer.material.SetColor("_Color", new Color(1f, 1f, 1f, 0.3f));

Unity Shader - Access Property

Background:
I created a dissolve Shader using the lightweight render pipiline, in Shader Graph by drag & drop. My object "dissolves" over time & fades in again. (Youtube "Brackeys Dissolve Shader")
Goal:
I want to change the _edgecolor as soon the object has been dissolved.
I can change the color via:
gameObject.GetComponent<Renderer>().material.SetColor("_edgecolor", Color.blue);
Problem:
How do i access the "Alpha" which seems to be modified by the shader, and would be a good indicator if the object is dissolved, right ?!
I tried to get the Alpha
Color c = gameObject.GetComponent<Renderer>().material.GetColor("_Color");
c.a = ....
won't work, because -> Material doesn't have a color property '_Color'
Here's a Screenshot of my ShaderGraph

Changing color of of gameObject in Unity

Okay so I have this code.
void Start () {
gameObject.GetComponent<Renderer> ().material.color = Color.green;
}
I expected my gameObject to change its color to green. I imported it as black and in the inspector it has turned to green however in the actual application it does not appear as green. I cant use gameObject.renderer.material.color = Color.green since unity tell me its basically outdated and that I have to use the new version. This is going to be really simple but what am I missing? Thanks in advance.
UPDATE: When I run the code a tab pops up in the inspector 'Sprites-Default (instance)' and if I change the selection box to Unlit > Color it works. Is there anyway of making this stick?
If you are trying to change a 2D sprite color try GetComponent<SpriteRenderer>().color = Color.green instead of just get "Renderer" component or try to setColor() with specular shader instead of direct attribution (you'll need a light source in scene).
the color changes but you cant see the result because the shader in your material needs light and you don't have lights so you will always see it black so you can add a light source or change the materials shader to unlight.
There are always two possibilities of not seeing the result of this code.
There's no light (a directional light or a point light) as pointed out by user2320445.
There is a light but you haven't imported the System.Collections namespace, i.e., your program misses the statement using System.Collections; in the beginning of the code. If you want to write the code without using the System.Collections namespace, then you can replace the line
gameObject.GetComponent<Renderer> ().material.color = Color.green;
with
gameObject.renderer.material.color = Color.green;
This does not require you to import the System.Collections namespace.

Canvas Screen Scaling with script Instantiated objects?

Can anyone explain to me why, when in the editor my instantiated shop UI looks wonderful (left) but when running on the device (right), it looks squished?, like so (please excuse the dodgy cam picture!):
The UI bars are prefabs, containing individual Canvas's and various UI elements. Each of the canvases is manually set to use Screen Scaling, with the reference resolution set to X: 320 Y: 480, and its set to use the Width as the basis for scaling. This has proved to work brilliantly in my previous games, but this one doesn't seem to hold. I've even manually set each of the instantiated objects' properties for scaling in the script, but still nothing.
The only thing I'm doing differently is building the UI at runtime by instantiating the UI prefabs and filling them when the shop is created.
Has anyone seen this before? Know how to fix it?
When you instantiate a prefab in code and then you add that prefab to some parent, unity ui system tries to compenstate the difference between the size of a prefab when it was created and the size it should be after canvas scaler update.
When I do something like this in my code I use this extension:
public static void SetParentAndReset(this RectTransform rect, Transform parent) {
rect.SetParent(parent);
rect.localScale = Vector3.one;
rect.localPosition = Vector3.zero;
}
...
var newObj = Instantiate(prefab);
var rect = newObj.GetComponent<RectTransform>();
rect.SetParentAndReset(parent);
rect.localPosition = new Vector3(1f, 1f, 1f); // set the actual position