Heya,
I am making a 2D racing game. At the moment, I am struggling with the sprites. My car is divided into 2 layers - white shape of a car that is coloured and fixed sprite with alpha applying details.
I want this blank, white layer to be textured with (pre-generated) random textures to give the cars unique feel. As I have a ton of both textures and car shapes, it would be impractical to create seperate sprite for each (also I would feel defeated).
Is there any good way to tackle this problem?
Help highly appreciated.
What is it you’re struggling with? Applying colors to a Texture2D? Or the algorithm for randomly deciding what colors to apply? Or is it something like, how to create a Sprite out of a Texture2D?
What I want to do is to apply a texture to a white sprite (like a color), which is impossible with the default shader. I am looking for a solution that doesn’t require writing shaders, as I don’t excel at it, something like UI mask.
What we casually call a “sprite” is a GameObject with a SpriteRenderer component. The SpriteRenderer takes an object of type Sprite, which you can make from a Texture2D (or some portion thereof) using Sprite.Create.
1 Like
Hi,
I have rethought the problem, to show what I aim to do.
Also, the texture is the same or higher size in comparison to a sprite
As shown in the picture below, I want to change a texture to a sprite, taking the shape of a shape sprite (full white).
Later I want to add another sprite, just paint on the rest.
To show it like a function:
Sprite CreateCarSprite(Texture2D textureOfCar, Sprite shape, Sprite detail)
{
Sprite carSprite = textureOfCar;
cut carSprite in shape of shape;
add detail to a carSprite;
return carSprite;
}
I have no idea how to edit Sprites…
Here, try this out. I altered the Default Sprite shader to accept another texture as an alpha mask.
Create a new shader called “DefaultMasked” and add this code to it:
Shader "Sprites/DefaultMasked"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_BlendTex("Mask Texture (Alpha)", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
[MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Cull Off
Lighting Off
ZWrite Off
Blend One OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#pragma multi_compile _ PIXELSNAP_ON
#pragma multi_compile _ ETC1_EXTERNAL_ALPHA
#include "UnityCG.cginc"
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
fixed4 _Color;
v2f vert(appdata_t IN)
{
v2f OUT;
OUT.vertex = UnityObjectToClipPos(IN.vertex);
OUT.texcoord = IN.texcoord;
OUT.color = IN.color * _Color;
#ifdef PIXELSNAP_ON
OUT.vertex = UnityPixelSnap (OUT.vertex);
#endif
return OUT;
}
sampler2D _MainTex;
sampler2D _BlendTex;
sampler2D _AlphaTex;
fixed4 SampleSpriteTexture (float2 uv)
{
fixed4 color = tex2D (_MainTex, uv);
color.a = tex2D (_BlendTex, uv).a;
return color;
}
fixed4 frag(v2f IN) : SV_Target
{
fixed4 c = SampleSpriteTexture (IN.texcoord) * IN.color;
c.rgb *= c.a;
return c;
}
ENDCG
}
}
}
Then create a new material using this shader, and apply that material to your SpriteRenderer. Then you should be able to put the base car sprite in the material, and whatever you assign to the SpriteRenderer will be masked by the car base.
It will not stretch the texture to fit within the base sprite, hopefully this at least gives you something to work with.
For the windows, I would use a separate overlay sprite.
Looks okay in my tests:
3 Likes
Works, thanks.
I owe you one.
1 Like