- Home /
One outline material for multiple objects?
Hello! Quick question- I am working on a 2D pixel topdown rpg, and I have made a simple outline shader, with a material, and am using it on my sign object. Morse specifically, when you hover your mouse over it, an outline appears. However, currently, when I hover over ONE sign, ALL OF THEM get an outline. I achieve this by having a OnMouseOver() script that sets the Material's outline thickness variable. So: is there a way for the material to have separate variables of every object or do I have to make multiple materials that use that shader? Thanks!
Answer by BeastDevBoi · Nov 24, 2020 at 12:44 PM
**public class SignHandler : MonoBehaviour
{
public DInteractible din;
public DialogHandler dih;
public Material outl;
void Update()
{
}
public void OnMouseOver()
{
bool isdialogue = FindObjectOfType<DialogHandler>().dialoguestarted;
//this is a bolean that blocks the dialogue script from starting if a dialog has already started
this.outl.SetVector("Vector2_AD1BF9C3", new Vector2(1, 0));
//outl is my outline material, and Vector2_AD1BF9C3 is the the outline thickness vector
if (Input.GetKeyDown(KeyCode.Mouse0)&&!isdialogue) //i use this to start a dialogue
{
din.TriggerDialogue();
}
}
public void OnMouseExit()
{
this.outl.SetVector("Vector2_AD1BF9C3", new Vector2(0, 0));
}
}**
Sure, here you go! I am also fairly new in unity, so please be as direct as you can with what I should use. Thanks!
Ok I see what you are doing wrong let me quickly explain it so you can understand it too.
From what I see you are dragging the material from the asset to the material outL field in the inspector, this changes the variables for the "master" material thus changing the variables for all sprites with the material.
what you should do instead of have a public material is this
**public class SignHandler : $$anonymous$$onoBehaviour
{
public DInteractible din;
public DialogHandler dih;
private $$anonymous$$aterial outl;
private void Start(){
outl = GetComponent<SpriteRenderer>().material;
}
void Update()
{
}
public void On$$anonymous$$ouseOver()
{
bool isdialogue = FindObjectOfType<DialogHandler>().dialoguestarted;
//this is a bolean that blocks the dialogue script from starting if a dialog has already started
this.outl.SetVector("Vector2_AD1BF9C3", new Vector2(1, 0));
//outl is my outline material, and Vector2_AD1BF9C3 is the the outline thickness vector
if (Input.GetKeyDown(KeyCode.$$anonymous$$ouse0)&&!isdialogue) //i use this to start a dialogue
{
din.TriggerDialogue();
}
}
public void On$$anonymous$$ouseExit()
{
this.outl.SetVector("Vector2_AD1BF9C3", new Vector2(0, 0));
}
}**
so you make the material private and you get it from the SpriteRenderer of the sprite, then when you make change the changes only apply to that sprites spriteRenderer and not all sprites with the material. If you have any more question feel free to ask!
WOW! Thanks SO $$anonymous$$UCH for how fast and direct you answered! I even understood what you are talking about, which I don't on most of the forums I've been. I HAVE heard that making everything public is a bad practice, but I found stuff is usually harder to work with if I don't. I totally forgot what component even USED the material, I kinda feel embarrassed now... Again, thanks and I will stick around if I need anything else.
Answer by Envans · Nov 24, 2020 at 12:27 PM
When changing a material the result you would normally get is just changing that objects material variable not all objects that have that material. Maybe you can post the OnMouseOver script so we can take a look and help you further?