RPG Battle System

https://itch.io/embed/215736

GET IT HERE: http://u3d.as/14×7

RPG Battle System is an easy to learn turn based battle system that can plug into any RPG Game or be the starting point for your new RPG Game. ⚔️

Requires DOTween or DOTween Pro to be imported and setup in the project before importing the RPG Battle System package. 

⚡️FEATURES⚡️

⚡️ Character Creation: Simple character creation done with native objects & includes many options like, PortraitElementAttacks & More!

⚡️ Attack Creation: Simple attack creation done with native objects & includes options like, CostElementAttack Type (Melee, Ranged, Stat Boosting) & More!

⚡️ Environment Creation: Environments can be swapped out depending on the where you want the battle to take place and offers options like, Background ImageBackground Music, and other various things.

⚡️ State Based Logic: Every state is handled by the State Controller and in it’s own script, this makes changing a states visuals or logic easy and understandable.

⚡️ Simple API: The API is very simple and easy to change, and everything is documented and explained in the documentation!

BONUS CONTENT

✨ State Machine: An easy to understand state machine that handles all states within the game. Adding states is as simple as making a script!

✨ View Controller: Handle all your menus, popups and other UI needs using the View Controller!

✨ Pixel Perfect Outline Shader: Used in this demo for highlighting characters who’s turn it is and for selecting attack targets. You can use this shader for all sorts of things and even in other projects!

✨ Sprite Text Component: Easy Sprite Text component to use custom sprites for fonts instead of using font files!

Shader HLSL | Outline Pixel Art Shader

Introduction

This shader was made for Zeoland, a 2D retro style tactics game, still in development. I’m in charge of all the programming and effects. Raul, the game’s artist, wanted each character when selected to have a white outline, this both has a unique look and allows for a clearer visual effect for the player.

The problem was the outline was going to be done by hand and an additional animation would need to be provided for every character. This would cost a lot of resources, I decided that a shader would be necessary to reduce the extra asset load.

As I started thinking about solving the problem with a shader, I realized it would be fairly simple to create this effect. I just needed all the frames of the animation to have a 1-pixel alpha border. This would allow me to return a color (white) in the frag function instead of the alpha.

Here you can see the finished product of the outline shader.

tumblr_inline_olc2y4QmMP1toto34_500.gif

Here’s the simple shader, to use it in Unity create a material called “SpriteOutline”, then apply the material to any sprite you wish to have an outline.

Shader "Sprite/Outline" 
{
	Properties 
	{
	  	_MainTex ("Texture", 2D) = "white" {}
        _Color ("Color", Color) = (1,1,1,1)

        _Outline ("Outline", Float) = 0
        _OutlineColor ("Outline Color", Color ) = (1,1,1,1)
	}

	SubShader 
    {
 
        Tags 
        { 
        	"Queue"="Transparent" 
        	"IgnoreProjector"="True" 
        	"RenderType" = "Transparent" 
        	"PreviewType"="Plane"
        	"CanUseSpriteAtlas"="True"
        }

        Cull Off
        Lighting Off
        ZWrite Off
        Blend SrcAlpha OneMinusSrcAlpha
 
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma target 2.0
 
            #include "UnityCG.cginc"

             sampler2D _MainTex;
             float4 _MainTex_ST;
             float4 _MainTex_TexelSize;
             float4 _Color;

             float _Outline;
             float4 _OutlineColor;

			struct v2f 
            {
                float4  pos : SV_POSITION;
                float2  uv : TEXCOORD0;
            };

            v2f vert (appdata_base IN)
            {
                v2f OUT;

                OUT.pos = mul (UNITY_MATRIX_MVP, IN.vertex);
                OUT.uv = TRANSFORM_TEX(IN.texcoord, _MainTex);

                return OUT;
            }

            fixed4 frag(v2f IN) : SV_Target
            {
            	fixed4 col = tex2D(_MainTex, IN.uv) * _Color;

            	if ( _Outline > 0 && col.a == 0)
            	{
            		fixed4 pixelUp = tex2D( _MainTex, IN.uv + fixed2(0,_MainTex_TexelSize.y));
                	fixed4 pixelDown = tex2D( _MainTex, IN.uv - fixed2(0,_MainTex_TexelSize.y));
                	fixed4 pixelRight = tex2D( _MainTex, IN.uv + fixed2(_MainTex_TexelSize.x,0));
                	fixed4 pixelLeft = tex2D( _MainTex, IN.uv - fixed2(_MainTex_TexelSize.x,0));
                		 
                	if ( pixelUp.a != 0 || pixelDown.a != 0  || pixelRight.a != 0  || pixelLeft.a != 0)
                	{
                		col.rgba = _OutlineColor;
                	}
            	}

            	return col;
            }
            ENDCG
         }
		
	}
	FallBack "Diffuse"
}

 

To add and remove the outline from your sprite you need to modify the “_Outline” property of the shader.

Here’s a simple script that will allow you to turn on and off the sprite outline.

 

Shader HLSL | Teleport Effect Shader

Introduction:

Ah yes, now for another fun shader that reduced the size of all of our assets.

As we were playing around with the game we hated the idea that the character would have to walk like in Final Fantasy Tactics Advanced or Fire Emblem. This would cause our asset list to grow quite large, every unit would have a walk animation and have to be facing 4-5 different directions, yuck!

Instead, we decided to go with having each character “teleport” to each location. Here was the first iteration.

tumblr_inline_olc3r2NDta1toto34_500.gif

Nice! The character teleported to where he was supposed to. Seems decent right? Well I and Raul felt something was a bit off, it was too sudden and the effect seemed very dull. How do we make it more fun?

We tried some ideas with some custom art but felt that it would take too many resources to have every unit have their own teleport animation, we wanted to achieve the below effect for every unit no matter which way that unit was facing.

tumblr_inline_olc40hxtRP1toto34_500.gif

The shader was easy enough to make, I just returned no color for every odd x pixel to make the image look like it was in strips. The effect wasn’t quite complete, though. In the effect above the image looks like it’s getting stretched on the y-axis to simulate a teleport animation.

In code, I decided to stretch the y-axis myself. But now I couldn’t apply this shader and the shader I had originally used for the sprite, so I added a “ghost” object sprite that is set active when the AI or Player is trying to move, the ghost sprite is just an object with a sprite renderer that takes the current sprite from the moving object.

The effect turned out like this.

tumblr_inline_olc4i44d7W1toto34_500.gif

Here’s the final shader:

Shader "Sprite/Teleport" 
{
	Properties 
	{
	  	_MainTex ("Texture", 2D) = "white" {}
        _Color ("Color", Color) = (1,1,1,1)
        _PixelsPerUnit("Pixels Per Unit", Float)= 16
	}

	SubShader 
    {
 
        Tags 
        { 
        	"Queue"="Transparent" 
        	"IgnoreProjector"="True" 
        	"RenderType" = "Transparent" 
        	"PreviewType"="Plane"
        	"CanUseSpriteAtlas"="True"
        }

        Cull Off
        Lighting Off
        ZWrite Off
        Blend SrcAlpha OneMinusSrcAlpha
 
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma target 2.0
 
            #include "UnityCG.cginc"

             sampler2D _MainTex;
             float4 _MainTex_ST;
             float4 _MainTex_TexelSize;
             float4 _Color;
             float _PixelsPerUnit;

            float4 AlignToPixelGrid(float4 vertex)
			{
				float4 worldPos = mul(unity_ObjectToWorld, vertex);

				worldPos.x = floor(worldPos.x * _PixelsPerUnit + 0.5) / _PixelsPerUnit;
				worldPos.y = floor(worldPos.y * _PixelsPerUnit + 0.5) / _PixelsPerUnit;

				return mul(unity_WorldToObject, worldPos);
			}

			struct v2f 
            {
                float4  pos : SV_POSITION;
                float2  uv : TEXCOORD0;
            };

            v2f vert (appdata_base IN)
            {
                v2f OUT;

                float4 alignedPos = AlignToPixelGrid(IN.vertex);

                OUT.pos = mul (UNITY_MATRIX_MVP, alignedPos);
                OUT.uv = TRANSFORM_TEX(IN.texcoord, _MainTex);

                return OUT;
            }

            fixed4 frag(v2f IN) : SV_Target
            {
           		float2 texSize = _MainTex_TexelSize.zw;
            	fixed4 col = fixed4(0,0,0,0);

            	float2 vpos = texSize  * IN.uv;

            	if ( vpos.x % 2.0 >= 1.0 )
            	{
            		col = tex2D(_MainTex, IN.uv) * _Color;
            	}

            	return col;

            }
            ENDCG
         }
		
	}
	FallBack "Diffuse"
}

It has an extra pixel per unit code for displaying pixel perfect sprites that you may or may not want to take out 🙂

Hope you enjoy your day! 🙂