- Home /
Change Material depending on Collider position?
Hello Everybody! Good morning or afternoon or evening, depending where you are!
Here's the deal, I am working on a game which requires me to create little "Stasis Zones" as in the character spawns a Sphere and everything inside it freezes, I got the textures for it but for the life of me I cannot find a way on the interweb that explains how to do the following:
Imagine a Player, he presses E and in a 4 feet radius it spawns a sphere rotating on itself with a cool texture, everything inside this sphere changes texture, which is easy if you're already in the sphere;
But what if a Box is halfway through the sphere collider? I would like that only the part inside the zone changes material, while the other stays the way it is;
Here is a visual example of what I'm talking about:
I would write a shader to do this. Where for each fragment, it would either render normally and display the default texture, or display the secondary texture, depending on its distance from the centre of the sphere (and therefore whether it's inside it or not).
I can't promise this is the best solution, and can't exactly provide sample code right now.
Yeah, that would definately be the way to go. The shader manual has an example on how to do things by world space coordinates. You just need to pass the parameters of the sphere to the shader.
Answer by NPstudio · Jun 30, 2015 at 07:33 PM
For everyone out there I used Stencil Shaders, they do the trick awesomely~
Answer by karp505 · Jun 30, 2015 at 10:59 PM
Hi, this works for me:
Shader "Custom/shader" {
Properties{
_Color ("Color", Color) = (1, 1, 1, 0.5)
_ForceField ("Force Field Position", Vector) = (0, 0, 0)
}
SubShader {
Tags{ "Queue" = "Geometry"}
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
uniform float4 _Color;
uniform float4 _ForceField;
struct vertexInput{
float4 vertex : POSITION;
};
struct vertexOutput{
float4 pos : SV_POSITION;
float4 worldPos : TEXCOORD0;
};
vertexOutput vert (vertexInput input){
vertexOutput output;
float4x4 modelMatrix = _Object2World;
output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
output.worldPos = mul(modelMatrix, input.vertex);
return output;
}
float4 frag(vertexOutput input) : COLOR{
float4 color = _Color;
if (distance (input.worldPos, _ForceField) > 2.7)
color = float4(0.0,0.0,0.0,1.0);
return float4 (color);
}
ENDCG
}
}
}
Just put that a material with that shader on your boxes and set the Force Field Position property in the editor to wherever your sphere is (or do it through script). Also, change the distance in this line:
if (distance (input.worldPos, _ForceField) > 2.7)
in accordance with how large the sphere is. 2.7 is good for a standard unity sphere with dimensions 5x5x5. Hope that helps! Let me know if you have any questions.