Is it possible to change the material on a single object in Unity Needle - or assign one material to an object once instantiated ?
The ChangeMaterialOnClick - seems to swap a material on all objects that are using the material.
In Unity it would be : Object.GetComponent ().material = Material1;
Original Post on Discord
by user 634679671727849482
import { GameObject, Behaviour, Renderer, serializable } from “@needle-tools /engine”;
import { Material } from “three”;
import{ Color } from “three”;
export class HK_MaterialSwap extends Behaviour
{
@serializable (Material)
m_material?: Material;
start()
{
console.log("This material " + this.m_material);
if(!this.m_material)
{
const obj = this.gameObject;
obj.getComponent(Renderer).sharedMaterials[0] = this.m_material;
console.log(“Success”);
}
}
by user 634679671727849482
So - this is throwing errors and I’m not sure why ?
by user 634679671727849482
marcel
(marwi)
November 21, 2023, 12:00am
5
What errors are you getting? Your check in if(!this.m_material)
is probably the opposite of what you want. You’re checking if the material is null and then you assign it.
by user 634679671727849482
Sorry - removed that now - but thought this should work ?
by user 634679671727849482
marcel
(marwi)
November 21, 2023, 12:00am
8
You need to check if a renderer exists. The vscode overlay should tell you that if you hover the error.
const renderer = obj.getComponent(Renderer);
if(renderer) { ... }
ok -thanks - I’ll try that- it was actually telling me the material was NUll - I think ??
by user 634679671727849482
by user 634679671727849482
marcel
(marwi)
November 21, 2023, 12:00am
11
well it’s multiple things ^^ your material could be undefined which would be a problem (that’s because you declared it as m_material?
) or your renderer could be null (e.g. if it’s an empty object in Unity or so, not all objects have a renderer)
Just a cube with material assigned in the inspector
by user 634679671727849482
I thought that’s how you serialise a material in this ?
by user 634679671727849482
marcel
(marwi)
November 21, 2023, 12:00am
14
Yes sure, i just mean your typescript code says this because of the way you declare it. And it could really be null because you could not have assigned it in Unity (if you forgot or so) so that’s ok. You just need to check the case in your code and then youre good
const renderer = obj.getComponent(Renderer);
if(renderer && this.m_material) { ... }
ok Thanks Marcel I’ve got this working -
import { Material } from "three";
import{ Color } from "three";
export class HK_MaterialSwap extends Behaviour
{
@serializable(Material)
my_material?: Material;
@serializable(GameObject)
my_gameobject?: GameObject; // = this.gameObject;
start()
{
//this.m_material = this.gameObject.getComponent(Renderer)?.sharedMaterials[0];
console.log("This material " + this.my_material);
// this.my_gameobject = this.gameObject;
//const myobj = this.my_gameobject;
const renderer = this.my_gameobject.getComponent(Renderer);
if(renderer && this.my_material && this.my_gameobject)
{
this.my_gameobject.getComponent(Renderer).sharedMaterials[0] = this.my_material;
}
}
}```
*by user 634679671727849482*
Should this really be a ‘red line’ though or a warning ?
by user 634679671727849482
It works as expected in the browser but has been throwing me all day ?
by user 634679671727849482
marcel
(marwi)
November 21, 2023, 12:00am
18
Yes - well technically you do the check a few lines above - just use the renderer
there instead of getting it again
marcel
(marwi)
November 21, 2023, 12:00am
19
this.my_gameobject.getComponent(Renderer).sharedMaterials[0] = this.my_material;
should be renderer.sharedMaterials[0] = this.my_material;
Yes -sorry again - went through a few things to try to see why it was redlining.
So this is it without redlining : for any other other newbies
import { Material } from "three";
export class HK_MaterialSwap extends Behaviour
{
@serializable(Material)
my_material?: Material;
@serializable(GameObject)
my_gameobject?: GameObject; // = this.gameObject;
start()
{
//this.m_material = this.gameObject.getComponent(Renderer)?.sharedMaterials[0];
console.log("This material " + this.my_material);
// this.my_gameobject = this.gameObject;
const myobj = this.my_gameobject;
if(myobj)
{
const renderer = myobj.getComponent(Renderer);
if(renderer && this.my_material)
{
renderer.sharedMaterials[0] = this.my_material;
}
}
}
}```
*by user 634679671727849482*