tag:blogger.com,1999:blog-52633944769515815192024-03-13T01:43:46.546+02:00Atsiitech development blogUnity 2D tutorials, thoughts on game development, web programming, etc.Unknownnoreply@blogger.comBlogger14125tag:blogger.com,1999:blog-5263394476951581519.post-7254880754239839602016-02-18T20:19:00.000+02:002016-02-18T20:24:56.729+02:00Unity waypoint system with NavMesh<div style="text-align: justify;">
Unity version: 5.3</div>
<div style="text-align: justify;">
Mode: 3D </div>
<div style="text-align: justify;">
Level: Beginner</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I wanted to create a patrolling NPC for my game so that requires a waypoint system. It is fairly easy to do with the NavMeshAgent.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
First let's create our test scene and add a couple of empty GameObjects.</div>
<div style="text-align: justify;">
<br /></div>
Create a GameObject as a container, name it WaypointsForNPC, or whatever
is your character's name, just so you know who they belong to. Make
sure the location is at zero.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimZ8m_qhxejJ35ghEf7BOoNRgY3StlIZ4NvFhOo6yDaHDn-jnx7if72mT6LZhivtzWEKBHL5ax3uPW5d1p4yBZCfxBR0DQEnCnmip9gaAVtnbFKG8aRTWfKS4eQHBmfFWrKtPejFdyyAZY/s1600/create_waypoints.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimZ8m_qhxejJ35ghEf7BOoNRgY3StlIZ4NvFhOo6yDaHDn-jnx7if72mT6LZhivtzWEKBHL5ax3uPW5d1p4yBZCfxBR0DQEnCnmip9gaAVtnbFKG8aRTWfKS4eQHBmfFWrKtPejFdyyAZY/s1600/create_waypoints.png" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Create a child GameObject and name it Waypoint, you should add an icon to it so you can see the location in the editor. I have provided a simple 'flag' icon you can import as an asset. You can then just make it a prefab and make copies, name them accordingly.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqJgLRSXHgA_0HucEvn31cZngx4bgDm1pgYf2p0Efc46_f_EAp_lggN9f1tIwQKpNQxOCzC7g6D-572ZW_Bu8hD0mAeaJE1cYKEeojWco0tCQ2fgBZP-xuY4JR1APA0xKK2eBlXyP7lJIS/s1600/waypointflag.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqJgLRSXHgA_0HucEvn31cZngx4bgDm1pgYf2p0Efc46_f_EAp_lggN9f1tIwQKpNQxOCzC7g6D-572ZW_Bu8hD0mAeaJE1cYKEeojWco0tCQ2fgBZP-xuY4JR1APA0xKK2eBlXyP7lJIS/s1600/waypointflag.png" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNYgZA1e1BIwUohqtm-bVPWjiqqBv4UQNE0nAsz1jVZsSdjV3UNuMoaHmDbHX4oe89SJX8Ni7O0YJYTx7PsE1nLv9YCre0m0WVaMEA1RAV4upInqWBvfl6FAUX9o_L1X0vgHmSEzGFoq8d/s1600/add_icon.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNYgZA1e1BIwUohqtm-bVPWjiqqBv4UQNE0nAsz1jVZsSdjV3UNuMoaHmDbHX4oe89SJX8Ni7O0YJYTx7PsE1nLv9YCre0m0WVaMEA1RAV4upInqWBvfl6FAUX9o_L1X0vgHmSEzGFoq8d/s1600/add_icon.png" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Place the waypoints on the map, on terrain or plane (as long as it's static and generally walkable)</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0yH8EyEGlfdiF9Bc-lF-GBjKbwi6P0Ny1mH7z1ZoTK-8XxKeOrsUCrGgJC4WYP5fiaJofVUTuqZdnOCJxU1ENB4Lky-khsx5eVUKDGkMm70o0ldh07sK6PIvr-rA3-2sXoLgNPCYabzvC/s1600/place_waypoints.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="224" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0yH8EyEGlfdiF9Bc-lF-GBjKbwi6P0Ny1mH7z1ZoTK-8XxKeOrsUCrGgJC4WYP5fiaJofVUTuqZdnOCJxU1ENB4Lky-khsx5eVUKDGkMm70o0ldh07sK6PIvr-rA3-2sXoLgNPCYabzvC/s320/place_waypoints.png" width="320" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Next, create the NPC. Here we just use a sphere object. Add NavMeshAgent to it.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1s9yAAyQZ0sEBSY5wIjpbprXpZdsFPEN1sxIadakCCAo2tya6qUUFaEMKSBxPmheVGGnPp3-4PcGzoylh892Ndy3bDdRd9xYgwgWzHJrvsM5vuz__i68Oq7_l4ied24dvtKjF_9e8Dg4a/s1600/add_agent.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="198" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1s9yAAyQZ0sEBSY5wIjpbprXpZdsFPEN1sxIadakCCAo2tya6qUUFaEMKSBxPmheVGGnPp3-4PcGzoylh892Ndy3bDdRd9xYgwgWzHJrvsM5vuz__i68Oq7_l4ied24dvtKjF_9e8Dg4a/s320/add_agent.png" width="320" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Next, use the Navigation tab and hit Bake in the bottom. This will bake the navigation mesh for you and it should show the walkable area in the scene view.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheOUpKreKvvZssMBBwTO3i_k0wBvWbSrFbRkptICjq7DdSvq7MC8kVkEHJC7DuaOPmabBm4xuOcFhpf1oZ5x5YN-p1LOGVvqtsQCezlWZ6NEkQYojf8pe-FFsrjI2bMEgMtK128Sy3S4GZ/s1600/navigation_tab.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheOUpKreKvvZssMBBwTO3i_k0wBvWbSrFbRkptICjq7DdSvq7MC8kVkEHJC7DuaOPmabBm4xuOcFhpf1oZ5x5YN-p1LOGVvqtsQCezlWZ6NEkQYojf8pe-FFsrjI2bMEgMtK128Sy3S4GZ/s320/navigation_tab.png" width="253" /></a></div>
<div style="text-align: justify;">
<div style="text-align: justify;">
Now
let's start coding. Select your NPC and add a new script. Let's call it
NPCWalkToWaypoint. Open up the script and add these lines before the
Start() -method:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<div style="background-color: white; padding: 5px;">
<span style="background-color: white;"><span style="font-family: "menlo";">
<span style="color: #009695;"> public</span><span style="color: #333333;"> </span><span style="color: #3364a4;">Transform</span><span style="color: #333333;">[]</span><span style="color: #333333;"> </span><span style="color: #333333;">waypoints</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #009695;">public</span><span style="color: #333333;"> </span><span style="color: #009695;">bool</span><span style="color: #333333;"> </span><span style="color: #333333;">loop</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #009695;">false</span><span style="color: #333333;">;</span><br />
<br />
<span style="color: #333333;"> </span><span style="color: #009695;">private</span><span style="color: #333333;"> </span><span style="color: #3364a4;">NavMeshAgent</span><span style="color: #333333;"> </span><span style="color: #333333;">agent</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #009695;">private</span><span style="color: #333333;"> </span><span style="color: #009695;">int</span><span style="color: #333333;"> </span><span style="color: #333333;">waypointCount</span><span style="color: #333333;">,</span><span style="color: #333333;"> </span><span style="color: #333333;">waypointIteration</span><span style="color: #333333;">;</span></span></span></div>
</div>
<span style="background-color: white;">
</span>
<br />
<div style="text-align: justify;">
<span style="background-color: white;"><br /></span></div>
<span style="background-color: white;"></span>First
is an array of Transforms. These are your waypoints. Next is a boolean
value, determining if we should loop the walking, meaning the NPC will
walk forever between the waypoints. NavMeshAgent is the component you
use to move the NPC and the two integers are used to control what
waypoints to use.<br />
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Now let's initialize those values in Start() -method:</div>
<div style="text-align: justify;">
<br /></div>
<div style="background-color: white; padding: 5px;">
<div style="text-align: justify;">
<span style="font-family: "menlo";">
<span style="color: #333333;"> agent</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">GetComponent</span><span style="color: #333333;"><</span><span style="color: #3364a4;">NavMeshAgent</span><span style="color: #333333;">></span><span style="color: #333333;"> </span><span style="color: #333333;">()</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">agent</span><span style="color: #333333;">.</span><span style="color: #333333;">SetDestination</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #333333;">waypoints</span><span style="color: #333333;"> </span><span style="color: #333333;">[</span><span style="color: #f57d00;">0</span><span style="color: #333333;">]</span><span style="color: #333333;">.</span><span style="color: #333333;">position</span><span style="color: #333333;">)</span><span style="color: #333333;">;</span><br />
<br />
<span style="color: #333333;"> </span><span style="color: #333333;">waypointCount</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">waypoints</span><span style="color: #333333;">.</span><span style="color: #333333;">Length</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">waypointIteration</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #f57d00;">0</span><span style="color: #333333;">;</span></span></div>
</div>
<br />
<br />
Alright,
first we fetch the NavMeshAgent component from the NPC this script is
attached to, then we set its destination to the first waypoint in the
array. Notice we don't do any checks if the array is empty, for
simplicity's sake we just assume it has something.<br />
<br />
Onwards to Update() method:<br />
<br />
<div style="background-color: white; padding: 5px;">
<br />
<span style="font-family: "menlo";">
<span style="color: #009695;"> if</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #333333;">agent</span><span style="color: #333333;">.</span><span style="color: #333333;">hasPath</span><span style="color: #333333;">)</span><span style="color: #333333;"> </span><span style="color: #333333;">{</span><br />
<span style="color: #333333;"> </span><span style="color: #009695;">if</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #333333;">agent</span><span style="color: #333333;">.</span><span style="color: #333333;">remainingDistance</span><span style="color: #333333;"> </span><span style="color: #333333;"><</span><span style="color: #333333;"> </span><span style="color: #333333;">.</span><span style="color: #f57d00;">5f</span><span style="color: #333333;">)</span><span style="color: #333333;"> </span><span style="color: #333333;">{</span><br />
<span style="color: #333333;"> </span><span style="color: #009695;">if</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #333333;">waypointIteration</span><span style="color: #333333;"> </span><span style="color: #333333;"><</span><span style="color: #333333;"> </span><span style="color: #333333;">waypointCount</span><span style="color: #333333;">)</span><span style="color: #333333;"> </span><span style="color: #333333;">{</span><span style="color: #333333;"> </span></span><br />
<span style="font-family: "menlo";"><span style="color: #333333;"> agent</span><span style="color: #333333;">.</span><span style="color: #333333;">SetDestination</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span></span><br />
<span style="font-family: "menlo";"><span style="color: #333333;"> </span><span style="color: #333333;">waypoints</span><span style="color: #333333;"> </span><span style="color: #333333;">[</span><span style="color: #333333;">waypointIteration</span><span style="color: #333333;">]</span><span style="color: #333333;">.</span><span style="color: #333333;">position</span><span style="color: #333333;">)</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">waypointIteration</span><span style="color: #333333;">++;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">}</span><span style="color: #333333;"> </span><span style="color: #009695;">else</span><span style="color: #333333;"> </span><span style="color: #333333;">{</span><br />
<span style="color: #333333;"> </span><span style="color: #009695;">if</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #333333;">loop</span><span style="color: #333333;">)</span><span style="color: #333333;"> </span><span style="color: #333333;">{</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">waypointIteration</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #f57d00;">0</span><span style="color: #333333;">;</span></span><br />
<span style="font-family: "menlo";"><span style="color: #333333;"> </span><span style="color: #333333;">}</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">}</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">}</span></span><br />
<br /></div>
<br />
First
we check if the agent has any path calculate currently (meaning its
destination is set). Then we check if we reached the destination. You
can play with the value here but for my purposes I found 0.5 works well.
If yes then we check if we have any more waypoints to travel to. If no
more is found, just set the iteration to 0 and the next update will send
the NPC to the first waypoint.<br />
<br />
<br />
Head back to the editor and drag the waypoints to the array on the component.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhh5dC9g5WtDgTViQYiMwTvSoDtF1ra33LB3NKwAzBSUexd7rw2y8AGW4hns-gdqXR3Hf12CmS3NajxIFRgpT629qeZaUF2mbYwZU1EI5HxqCvHJ09_q2EekXaF-Hy7XingukHksYrbmoLq/s1600/arraywaypoints.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhh5dC9g5WtDgTViQYiMwTvSoDtF1ra33LB3NKwAzBSUexd7rw2y8AGW4hns-gdqXR3Hf12CmS3NajxIFRgpT629qeZaUF2mbYwZU1EI5HxqCvHJ09_q2EekXaF-Hy7XingukHksYrbmoLq/s1600/arraywaypoints.png" /></a></div>
<br />
Hit play and witness your patrolling NPC.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVajPO7SPP1ku66gstAXu16lJjzrMTMhDdyi171v6Q4VZkXHVuybH9NqdZR8nWgjOy07nYvDA_tUH_eSdJc4TkfC76v0rgk7oLyWCbvfvKm-zKtOjZHH2c-_cxEh-Iy2qjpf6bu9zp1uIo/s1600/waypoint_unity.gif" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="193" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVajPO7SPP1ku66gstAXu16lJjzrMTMhDdyi171v6Q4VZkXHVuybH9NqdZR8nWgjOy07nYvDA_tUH_eSdJc4TkfC76v0rgk7oLyWCbvfvKm-zKtOjZHH2c-_cxEh-Iy2qjpf6bu9zp1uIo/s320/waypoint_unity.gif" width="320" /></a></div>
<br />
<br />
Whole script:<br />
<br />
<div style="background-color: white; padding: 5px;">
<span style="font-family: "menlo";">
<span style="color: #009695;">using</span><span style="color: #333333;"> UnityEngine</span><span style="color: #333333;">;</span><br />
<span style="color: #009695;">using</span><span style="color: #333333;"> System</span><span style="color: #333333;">.</span><span style="color: #333333;">Collections</span><span style="color: #333333;">;</span><br />
<br />
<span style="color: #009695;">public</span><span style="color: #333333;"> </span><span style="color: #009695;">class</span><span style="color: #333333;"> </span><span style="color: #3364a4;">NPCWalkToWaypoint</span><span style="color: #333333;"> </span><span style="color: #333333;">:</span><span style="color: #333333;"> </span><span style="color: #3364a4;">MonoBehaviour</span><br />
<span style="color: #333333;">{</span><br />
<br />
<span style="color: #333333;"> </span><span style="color: #009695;">public</span><span style="color: #333333;"> </span><span style="color: #3364a4;">Transform</span><span style="color: #333333;">[]</span><span style="color: #333333;"> </span><span style="color: #333333;">waypoints</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #009695;">public</span><span style="color: #333333;"> </span><span style="color: #009695;">bool</span><span style="color: #333333;"> </span><span style="color: #333333;">loop</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #009695;">false</span><span style="color: #333333;">;</span><br />
<br />
<span style="color: #333333;"> </span><span style="color: #009695;">private</span><span style="color: #333333;"> </span><span style="color: #3364a4;">NavMeshAgent</span><span style="color: #333333;"> </span><span style="color: #333333;">agent</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #009695;">private</span><span style="color: #333333;"> </span><span style="color: #009695;">int</span><span style="color: #333333;"> </span><span style="color: #333333;">waypointCount</span><span style="color: #333333;">,</span><span style="color: #333333;"> </span><span style="color: #333333;">waypointIteration</span><span style="color: #333333;">;</span><br />
<br />
<span style="color: #333333;"> </span><span style="color: #009695;">void</span><span style="color: #333333;"> </span><span style="color: #333333;">Start</span><span style="color: #333333;"> </span><span style="color: #333333;">()</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">{</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">agent</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">GetComponent</span><span style="color: #333333;"><</span><span style="color: #3364a4;">NavMeshAgent</span><span style="color: #333333;">></span><span style="color: #333333;"> </span><span style="color: #333333;">()</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">agent</span><span style="color: #333333;">.</span><span style="color: #333333;">SetDestination</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #333333;">waypoints</span><span style="color: #333333;"> </span><span style="color: #333333;">[</span><span style="color: #f57d00;">0</span><span style="color: #333333;">]</span><span style="color: #333333;">.</span><span style="color: #333333;">position</span><span style="color: #333333;">)</span><span style="color: #333333;">;</span><br />
<br />
<span style="color: #333333;"> </span><span style="color: #333333;">waypointCount</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">waypoints</span><span style="color: #333333;">.</span><span style="color: #333333;">Length</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">waypointIteration</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #f57d00;">0</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">}</span><br />
<br />
<span style="color: #333333;"> </span><span style="color: #009695;">void</span><span style="color: #333333;"> </span><span style="color: #333333;">Update</span><span style="color: #333333;"> </span><span style="color: #333333;">()</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">{</span><br />
<span style="color: #333333;"> </span><span style="color: #009695;">if</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #333333;">agent</span><span style="color: #333333;">.</span><span style="color: #333333;">hasPath</span><span style="color: #333333;">)</span><span style="color: #333333;"> </span><span style="color: #333333;">{</span><br />
<span style="color: #333333;"> </span><span style="color: #009695;">if</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #333333;">agent</span><span style="color: #333333;">.</span><span style="color: #333333;">remainingDistance</span><span style="color: #333333;"> </span><span style="color: #333333;"><</span><span style="color: #333333;"> </span><span style="color: #333333;">.</span><span style="color: #f57d00;">5f</span><span style="color: #333333;">)</span><span style="color: #333333;"> </span><span style="color: #333333;">{</span><br />
<span style="color: #333333;"> </span><span style="color: #009695;">if</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #333333;">waypointIteration</span><span style="color: #333333;"> </span><span style="color: #333333;"><</span><span style="color: #333333;"> </span><span style="color: #333333;">waypointCount</span><span style="color: #333333;">)</span><span style="color: #333333;"> </span><span style="color: #333333;">{</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">agent</span><span style="color: #333333;">.</span><span style="color: #333333;">SetDestination</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #333333;">waypoints</span><span style="color: #333333;"> </span><span style="color: #333333;">[</span><span style="color: #333333;">waypointIteration</span><span style="color: #333333;">]</span><span style="color: #333333;">.</span><span style="color: #333333;">position</span><span style="color: #333333;">)</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">waypointIteration</span><span style="color: #333333;">++;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">}</span><span style="color: #333333;"> </span><span style="color: #009695;">else</span><span style="color: #333333;"> </span><span style="color: #333333;">{</span><br />
<span style="color: #333333;"> </span><span style="color: #009695;">if</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #333333;">loop</span><span style="color: #333333;">)</span><span style="color: #333333;"> </span><span style="color: #333333;">{</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">waypointIteration</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #f57d00;">0</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">}</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">}</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">}</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">}</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">}</span><br />
<span style="color: #333333;">}</span></span></div>
</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-5263394476951581519.post-55396445191206112352015-08-20T15:21:00.001+03:002015-08-20T15:21:47.499+03:00Game Audio JamAfter playing some games in the GameBoy Jam 4, I wanted to try organizing my own jam. Since sites like <a href="http://gamejolt.com/" target="_blank">GameJolt</a> and <a href="http://itch.io/">itch.io</a> provide the framework for that, I thought I'd go for it.<br />
<br />
I chose to do it on GameJolt for no particular reason other than I'm more familiar with the site. Starting the game jam is really easy. You just pick a name and corresponding hashtag and start writing rules, adding pages and resources.<br />
<br />
I picked Game Audio as the topic because I haven't seen a jam that explicitly focuses on sounds and music. It is interesting to see what kind of cool audio experiences people can create.<br />
<br />
The challenge in the beginning is to find people to join. The link has been shared on Twitter and Reddit during the first 2 days since creation and shows promise, people seem interested in the topic. Another challenge is that I picked a time possibly too close to bigger jams. People might have exhausted their creativity in Ludum Dare, which starts this weekend. To compensate that, I gave participants 3 weeks time to finish the game and started promoting the jam a week ahead of starting time.<br />
<br />
The jam starts 26th of August 2015. Anyone can join and if your sound skills are rusty or non-existent, use the jam to learn more.<br />
<br />
See the rules here: <a href="http://jams.gamejolt.io/gameaudiojam">http://jams.gamejolt.io/gameaudiojam</a>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-5263394476951581519.post-39977198083280760052015-05-09T00:56:00.002+03:002015-05-09T00:58:21.835+03:00What's going on?It's been a long time since I posted anything. My blog seems to get visitors every day and I guess a lot of you are looking for continued tutorial for the RPG/Roguelike. I am not sure if the next part will ever come but it looks like the Unity team has created their own tutorial for this.<br />
<br />
<a href="http://www.unity3d.com/learn/tutorials/projects/2d-roguelike" target="_blank">http://www.unity3d.com/learn/tutorials/projects/2d-roguelike</a><br />
<br />
I know some of you don't like video tutorials but this looks pretty decent and straightforward to me, and more professional anyway. ;)<br />
<br />
Thanks for reading my tutorials, perhaps I will continue with something else. For now, those vids could be the best thing for you if you're looking for making a 2D roguelike with Unity.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-5263394476951581519.post-2318848525717948202014-09-21T14:40:00.001+03:002014-09-21T14:43:05.241+03:00Post delaysThanks for checking this blog, if you're here for the Unity RPG tutorial, I apologize for the delay of the coming post. I have written some of it but have been busy elsewhere so it has been delayed.<br />
<br />
What's coming?<br />
<br />
- Refactoring / rewriting some of the tutorial parts to make them more clear<br />
- Collision detection<br />
- Free movement as an alternative to turn based<br />
<br />
- A case study of quickly creating a game with GameMaker and posting it to Google Play (much later)Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-5263394476951581519.post-49136479801926207652014-08-20T20:04:00.000+03:002014-08-23T16:05:11.052+03:00Turn based RPG with Unity 2D - Part 4: Enemy/NPC AI (moving)<div style="text-align: justify;">
<a href="http://atsiitech.blogspot.com/2014/06/turn-based-rpg-with-unity-2d-part-1.html">Part 1: Grid movement</a><br />
<a href="http://atsiitech.blogspot.com/2014/06/turn-based-rpg-with-unity-2d-part-2.html">Part 2: Camera control</a><br />
<a href="http://atsiitech.blogspot.com/2014/08/turn-based-rpg-with-unity-2d-part-3.html">Part 3: Lighting</a><br />
Part 4: NPC AI<br />
<br />
--- <br />
<a href="http://atsiitech.blogspot.com/2014/08/turn-based-rpg-with-unity-2d-part-3.html" target="_blank"></a><br />
<br />
<b>Unity version:</b> 4.5<br />
<b>Language used:</b> C# </div>
<div style="text-align: justify;">
<br /></div>
<h2>
Making the NPC</h2>
<br />
For the purpose of this tutorial, let's copy the player sprite and just change the tint to something else. Like red. This will be our NPC.<br />
<br />
Drag the player sprite to your hierarchy and name the new GameObject as First NPC. Or anything you like. Now, select the object and change its tint from the inspector:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqrylvjeWb9bbsu6xiALvWNx_LO-dhQWFz6L4NBsYLoPj7a73POrlHnCeBZ1eYBpGMRN71jYMxcGnzW2JbUelD-6BKgtvE5ZlXLYcL4V9Ayn56OmcpoF_EOCD_cFaeZum9_DugcLSGo8No/s1600/change_color_tint.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqrylvjeWb9bbsu6xiALvWNx_LO-dhQWFz6L4NBsYLoPj7a73POrlHnCeBZ1eYBpGMRN71jYMxcGnzW2JbUelD-6BKgtvE5ZlXLYcL4V9Ayn56OmcpoF_EOCD_cFaeZum9_DugcLSGo8No/s1600/change_color_tint.png" height="106" width="320" /></a></div>
<br />
Now we need to give the NPC a tag. In the top of the inspector click the box that says Tag and add a new tag called "npc":<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzeoDMmwvmHKS2p6aqVz6SQTJH22VOexsIt09LE-Q36o48sdZG_I6Kkw-dBD282xXzeuPPVcn6uouv66bC6UDYpeYXHDIeT6OUTr7IqffdgjYodGzu0Ybuz3Cq5hJ05mSqtaxQ0Cp9iqaG/s1600/add_tag2.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzeoDMmwvmHKS2p6aqVz6SQTJH22VOexsIt09LE-Q36o48sdZG_I6Kkw-dBD282xXzeuPPVcn6uouv66bC6UDYpeYXHDIeT6OUTr7IqffdgjYodGzu0Ybuz3Cq5hJ05mSqtaxQ0Cp9iqaG/s1600/add_tag2.png" height="159" width="320" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh22tbcAj5J4SudicdXfR1z2C0Sdex7WJjAMrqrcEUX2HvglmvDMOYqRe3zBOvg-yswaZab78AiarJMnWeLRwrQzOwHTFn_s6fyfrgkIOBXUpoI6uw6tPuX03-2egbbJ4lVHPUkADItB5RJ/s1600/add_tag.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh22tbcAj5J4SudicdXfR1z2C0Sdex7WJjAMrqrcEUX2HvglmvDMOYqRe3zBOvg-yswaZab78AiarJMnWeLRwrQzOwHTFn_s6fyfrgkIOBXUpoI6uw6tPuX03-2egbbJ4lVHPUkADItB5RJ/s1600/add_tag.png" /></a></div>
<br />
<br />
Don't forget to select your npc GameObject again and assign that tag to it. <br />
<br />
<h2>
Scripting the NPC</h2>
<br />
Next create a new interface called NPCinterface (just create a new C# script and remove everything in it, then write the interface):<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;">1
2
3</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: #66d9ef;">public</span> <span style="color: #66d9ef;">interface</span> <span style="color: #f8f8f2;">NPCinterface</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #66d9ef;">void</span> <span style="color: #a6e22e;">ExecuteAI</span><span style="color: #f8f8f2;">();</span>
<span style="color: #f8f8f2;">}</span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
This is where you can define methods for the NPC that can be used from other scripts. Next create another script and call it NPCController. This will be our abstract class that all NPC inherit from. We can define common methods in this class:<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;">1
2
3
4
5
6
7
8
9</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: #66d9ef;">using</span> <span style="color: #f8f8f2;">UnityEngine;</span>
<span style="color: #66d9ef;">using</span> <span style="color: #f8f8f2;">System.Collections;</span>
<span style="color: #66d9ef;">abstract</span> <span style="color: #66d9ef;">public</span> <span style="color: #66d9ef;">class</span> <span style="color: #a6e22e;">NPCController</span> <span style="color: #f8f8f2;">:</span> <span style="color: #f8f8f2;">MonoBehaviour,</span> <span style="color: #f8f8f2;">NPCinterface</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #66d9ef;">public</span> <span style="color: #66d9ef;">void</span> <span style="color: #a6e22e;">ExecuteAI</span><span style="color: #f8f8f2;">()</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #f8f8f2;">}</span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
<br />
Notice the keyword <b>abstract </b>and also the <b>NPCinterface </b>reference. This means we implement NPCinterface and must define the contents of <b>ExecuteAI( ) </b>method here.<br />
<br />
Select the NPC from your hierarchy window and from the inspector, select Add component / new script. Name this script FirstNPC. Hit Create and Add. Open the script and change it like so:<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: #66d9ef;">using</span> <span style="color: #f8f8f2;">UnityEngine;</span>
<span style="color: #66d9ef;">using</span> <span style="color: #f8f8f2;">System.Collections;</span>
<span style="color: #66d9ef;">public</span> <span style="color: #66d9ef;">class</span> <span style="color: #a6e22e;">FirstNPC</span> <span style="color: #f8f8f2;">:</span> <span style="color: #f8f8f2;">NPCController</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #66d9ef;">void</span> <span style="color: #a6e22e;">Start</span> <span style="color: #f8f8f2;">()</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">pos</span> <span style="color: #f8f8f2;">=</span> <span style="color: #f8f8f2;">transform.position;</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #66d9ef;">void</span> <span style="color: #a6e22e;">Update</span> <span style="color: #f8f8f2;">()</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #66d9ef;">if</span> <span style="color: #f8f8f2;">(moving)</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">transform.position</span> <span style="color: #f8f8f2;">=</span> <span style="color: #f8f8f2;">pos;</span>
<span style="color: #f8f8f2;">moving</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">false</span><span style="color: #f8f8f2;">;</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #f8f8f2;">}</span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
<br />
You will get some errors because <b>pos </b>and <b>moving </b>are not defined but we will do that next. Notice that we added NPCController here instead of MonoBehaviour (because MonoBehaviour is implemented in NPCController already).<br />
<br />
Go back to your NPCController script and add these properties:<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #66d9ef;">protected</span> <span style="color: #f8f8f2;">Vector2</span> <span style="color: #f8f8f2;">pos;</span>
<span style="color: #66d9ef;">protected</span> <span style="color: #66d9ef;">bool</span> <span style="color: #f8f8f2;">moving</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">false</span><span style="color: #f8f8f2;">;</span>
</pre>
</div>
<br />
<br />
Protected means these properties will be accessible to the child objects (in this case our FirstNPC script). Next add this piece of code to the ExecuteAI -method:<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #66d9ef;">int</span> <span style="color: #f8f8f2;">direction</span> <span style="color: #f8f8f2;">=</span> <span style="color: #f8f8f2;">Random.Range</span> <span style="color: #f8f8f2;">(</span><span style="color: #ae81ff;">1</span><span style="color: #f8f8f2;">,</span> <span style="color: #ae81ff;">5</span><span style="color: #f8f8f2;">);</span>
<span style="color: #66d9ef;">if</span> <span style="color: #f8f8f2;">(direction</span> <span style="color: #f8f8f2;">==</span> <span style="color: #ae81ff;">1</span><span style="color: #f8f8f2;">)</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">pos</span> <span style="color: #f8f8f2;">+=</span> <span style="color: #f8f8f2;">Vector2.up;</span>
<span style="color: #f8f8f2;">moving</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">true</span><span style="color: #f8f8f2;">;</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #66d9ef;">else</span> <span style="color: #a6e22e;">if</span> <span style="color: #f8f8f2;">(direction</span> <span style="color: #f8f8f2;">==</span> <span style="color: #ae81ff;">2</span><span style="color: #f8f8f2;">)</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">pos</span> <span style="color: #f8f8f2;">+=</span> <span style="color: #f8f8f2;">Vector2.right;</span>
<span style="color: #f8f8f2;">moving</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">true</span><span style="color: #f8f8f2;">;</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #66d9ef;">else</span> <span style="color: #a6e22e;">if</span> <span style="color: #f8f8f2;">(direction</span> <span style="color: #f8f8f2;">==</span> <span style="color: #ae81ff;">3</span><span style="color: #f8f8f2;">)</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">pos</span> <span style="color: #f8f8f2;">-=</span> <span style="color: #f8f8f2;">Vector2.up;</span>
<span style="color: #f8f8f2;">moving</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">true</span><span style="color: #f8f8f2;">;</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #66d9ef;">else</span> <span style="color: #a6e22e;">if</span> <span style="color: #f8f8f2;">(direction</span> <span style="color: #f8f8f2;">==</span> <span style="color: #ae81ff;">4</span><span style="color: #f8f8f2;">)</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">pos</span> <span style="color: #f8f8f2;">-=</span> <span style="color: #f8f8f2;">Vector2.right;</span>
<span style="color: #f8f8f2;">moving</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">true</span><span style="color: #f8f8f2;">;</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #66d9ef;">else</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">;</span> <span style="color: #75715e;">// do nothing</span>
<span style="color: #f8f8f2;">}</span>
</pre>
</div>
<br />
<br />
In this script, first we get a random direction. We have 4 directions so the range starts from 1 and goes up to 5 (the range starts from 0 so the fifth element is actually 4) . We then set the position depending on this random direction. The Update -method in our FirstNPC class will handle the actual moving.<br />
<br />
So... how do we call the ExecuteAI? Our player object is the center of attention in this type of game, the turns are pretty much dependent on what the player does. So let's open up our PlayerController -script and do some changes.<br />
<br />
OK, our game only has 1 NPC but let's look to the future and determine that there will be more. Add these properties to the PlayerController -script:<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #66d9ef;">private</span> <span style="color: #f8f8f2;">GameObject[]</span> <span style="color: #f8f8f2;">npcObjects;</span>
<span style="color: #66d9ef;">private</span> <span style="color: #f8f8f2;">NPCController[]</span> <span style="color: #f8f8f2;">npcControllers;</span>
</pre>
</div>
<br />
<br />
In the Start() -method, add these lines:<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #75715e;">// Find all NPCs with the tag "npc":</span>
<span style="color: #f8f8f2;">npcObjects</span> <span style="color: #f8f8f2;">=</span> <span style="color: #f8f8f2;">GameObject.FindGameObjectsWithTag</span> <span style="color: #f8f8f2;">(</span><span style="color: #e6db74;">"npc"</span><span style="color: #f8f8f2;">);</span>
<span style="color: #f8f8f2;">npcControllers</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">new</span> <span style="color: #f8f8f2;">NPCController[npcObjects.Length];</span>
<span style="color: #75715e;">// Iterate through them and store their NPCController to</span>
<span style="color: #75715e;">// npcControllers array:</span>
<span style="color: #66d9ef;">for</span><span style="color: #f8f8f2;">(</span><span style="color: #66d9ef;">int</span> <span style="color: #f8f8f2;">i</span> <span style="color: #f8f8f2;">=</span> <span style="color: #ae81ff;">0</span><span style="color: #f8f8f2;">;</span> <span style="color: #f8f8f2;">i</span> <span style="color: #f8f8f2;"><</span> <span style="color: #f8f8f2;">npcObjects.Length;</span> <span style="color: #f8f8f2;">i++)</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">npcControllers[i]</span> <span style="color: #f8f8f2;">=</span> <span style="color: #f8f8f2;">(NPCController)</span> <span style="color: #f8f8f2;">npcObjects[i]</span>
<span style="color: #f8f8f2;">.GetComponent(</span><span style="color: #66d9ef;">typeof</span><span style="color: #f8f8f2;">(NPCController));</span>
<span style="color: #f8f8f2;">}</span>
</pre>
</div>
<br />
<br />
The code comments describe what this code snippet does. Next let's do a convenience method called ExecuteNPCAI where we iterate through the npcController array and execute the AI for each NPC:<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #66d9ef;">private</span> <span style="color: #66d9ef;">void</span> <span style="color: #a6e22e;">ExecuteNPCAI</span><span style="color: #f8f8f2;">()</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #66d9ef;">foreach</span><span style="color: #f8f8f2;">(NPCController</span> <span style="color: #f8f8f2;">npc</span> <span style="color: #66d9ef;">in</span> <span style="color: #f8f8f2;">npcControllers)</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">npc.ExecuteAI();</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #f8f8f2;">}</span>
</pre>
</div>
<br />
<br />
Now call this method from the CheckInput -method in each keystroke check like so:<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #66d9ef;">if</span> <span style="color: #f8f8f2;">(Input.GetKeyDown(KeyCode.D)</span> <span style="color: #f8f8f2;">||</span> <span style="color: #f8f8f2;">Input.GetKeyDown(KeyCode.RightArrow))</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">pos</span> <span style="color: #f8f8f2;">+=</span> <span style="color: #f8f8f2;">Vector2.right;</span>
<span style="color: #f8f8f2;">moving</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">true</span><span style="color: #f8f8f2;">;</span>
<span style="color: #f8f8f2;">ExecuteNPCAI();</span>
<span style="color: #f8f8f2;">}</span>
</pre>
</div>
<br />
<br />
Now test your game, the NPC should move randomly whenever you move the player character. Of course there's no collision detection yet so the character might go under the player or off the grid.<br />
<br />
GIF of the movement:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnCCrjKHqfGp6azXMTCSdsRCAzzzfeeoqPqSEqblhvJaWZxfMLSLrEaabcqNaGLSXaTWfRpyPXuueR6tFXc4KhzLaE8xed3Sbk8GjAhlEy2LK61MSAfc1X4__Qrqb3FwxyJEwlvoLp0oxP/s1600/movement.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnCCrjKHqfGp6azXMTCSdsRCAzzzfeeoqPqSEqblhvJaWZxfMLSLrEaabcqNaGLSXaTWfRpyPXuueR6tFXc4KhzLaE8xed3Sbk8GjAhlEy2LK61MSAfc1X4__Qrqb3FwxyJEwlvoLp0oxP/s1600/movement.gif" height="211" width="320" /></a></div>
<br />
<br />
Stay tuned for more tutorials.<br />
<br />
All of the scripts as a whole:<br />
<br />
<b>NPCinterface:</b><br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;">1
2
3</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: #66d9ef;">public</span> <span style="color: #66d9ef;">interface</span> <span style="color: #f8f8f2;">NPCinterface</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #66d9ef;">void</span> <span style="color: #a6e22e;">ExecuteAI</span><span style="color: #f8f8f2;">();</span>
<span style="color: #f8f8f2;">}</span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
<br />
<b>NPCController:</b><br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: #66d9ef;">using</span> <span style="color: #f8f8f2;">UnityEngine;</span>
<span style="color: #66d9ef;">using</span> <span style="color: #f8f8f2;">System.Collections;</span>
<span style="color: #66d9ef;">abstract</span> <span style="color: #66d9ef;">public</span> <span style="color: #66d9ef;">class</span> <span style="color: #a6e22e;">NPCController</span> <span style="color: #f8f8f2;">:</span> <span style="color: #f8f8f2;">MonoBehaviour,</span> <span style="color: #f8f8f2;">NPCinterface</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #66d9ef;">protected</span> <span style="color: #f8f8f2;">Vector2</span> <span style="color: #f8f8f2;">pos;</span>
<span style="color: #66d9ef;">protected</span> <span style="color: #66d9ef;">bool</span> <span style="color: #f8f8f2;">moving</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">false</span><span style="color: #f8f8f2;">;</span>
<span style="color: #66d9ef;">public</span> <span style="color: #66d9ef;">void</span> <span style="color: #a6e22e;">ExecuteAI</span><span style="color: #f8f8f2;">()</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #66d9ef;">int</span> <span style="color: #f8f8f2;">direction</span> <span style="color: #f8f8f2;">=</span> <span style="color: #f8f8f2;">Random.Range</span> <span style="color: #f8f8f2;">(</span><span style="color: #ae81ff;">1</span><span style="color: #f8f8f2;">,</span> <span style="color: #ae81ff;">5</span><span style="color: #f8f8f2;">);</span>
<span style="color: #66d9ef;">if</span> <span style="color: #f8f8f2;">(direction</span> <span style="color: #f8f8f2;">==</span> <span style="color: #ae81ff;">1</span><span style="color: #f8f8f2;">)</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">pos</span> <span style="color: #f8f8f2;">+=</span> <span style="color: #f8f8f2;">Vector2.up;</span>
<span style="color: #f8f8f2;">moving</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">true</span><span style="color: #f8f8f2;">;</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #66d9ef;">else</span> <span style="color: #a6e22e;">if</span> <span style="color: #f8f8f2;">(direction</span> <span style="color: #f8f8f2;">==</span> <span style="color: #ae81ff;">2</span><span style="color: #f8f8f2;">)</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">pos</span> <span style="color: #f8f8f2;">+=</span> <span style="color: #f8f8f2;">Vector2.right;</span>
<span style="color: #f8f8f2;">moving</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">true</span><span style="color: #f8f8f2;">;</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #66d9ef;">else</span> <span style="color: #a6e22e;">if</span> <span style="color: #f8f8f2;">(direction</span> <span style="color: #f8f8f2;">==</span> <span style="color: #ae81ff;">3</span><span style="color: #f8f8f2;">)</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">pos</span> <span style="color: #f8f8f2;">-=</span> <span style="color: #f8f8f2;">Vector2.up;</span>
<span style="color: #f8f8f2;">moving</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">true</span><span style="color: #f8f8f2;">;</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #66d9ef;">else</span> <span style="color: #a6e22e;">if</span> <span style="color: #f8f8f2;">(direction</span> <span style="color: #f8f8f2;">==</span> <span style="color: #ae81ff;">4</span><span style="color: #f8f8f2;">)</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">pos</span> <span style="color: #f8f8f2;">-=</span> <span style="color: #f8f8f2;">Vector2.right;</span>
<span style="color: #f8f8f2;">moving</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">true</span><span style="color: #f8f8f2;">;</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #66d9ef;">else</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">;</span> <span style="color: #75715e;">// do nothing</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #f8f8f2;">}</span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
<br />
<b>FirstNPC:</b><br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: #66d9ef;">using</span> <span style="color: #f8f8f2;">UnityEngine;</span>
<span style="color: #66d9ef;">using</span> <span style="color: #f8f8f2;">System.Collections;</span>
<span style="color: #66d9ef;">public</span> <span style="color: #66d9ef;">class</span> <span style="color: #a6e22e;">FirstNPC</span> <span style="color: #f8f8f2;">:</span> <span style="color: #f8f8f2;">NPCController</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #66d9ef;">void</span> <span style="color: #a6e22e;">Start</span> <span style="color: #f8f8f2;">()</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">pos</span> <span style="color: #f8f8f2;">=</span> <span style="color: #f8f8f2;">transform.position;</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #66d9ef;">void</span> <span style="color: #a6e22e;">Update</span> <span style="color: #f8f8f2;">()</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #66d9ef;">if</span> <span style="color: #f8f8f2;">(moving)</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">transform.position</span> <span style="color: #f8f8f2;">=</span> <span style="color: #f8f8f2;">pos;</span>
<span style="color: #f8f8f2;">moving</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">false</span><span style="color: #f8f8f2;">;</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #f8f8f2;">}</span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
<br />
<b>PlayerController:</b><br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: #66d9ef;">using</span> <span style="color: #f8f8f2;">UnityEngine;</span>
<span style="color: #66d9ef;">using</span> <span style="color: #f8f8f2;">System.Collections;</span>
<span style="color: #66d9ef;">public</span> <span style="color: #66d9ef;">class</span> <span style="color: #a6e22e;">PlayerController</span> <span style="color: #f8f8f2;">:</span> <span style="color: #f8f8f2;">MonoBehaviour</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #66d9ef;">private</span> <span style="color: #f8f8f2;">Vector2</span> <span style="color: #f8f8f2;">pos;</span>
<span style="color: #66d9ef;">private</span> <span style="color: #f8f8f2;">GameObject[]</span> <span style="color: #f8f8f2;">npcObjects;</span>
<span style="color: #66d9ef;">private</span> <span style="color: #f8f8f2;">NPCController[]</span> <span style="color: #f8f8f2;">npcControllers;</span>
<span style="color: #66d9ef;">private</span> <span style="color: #66d9ef;">bool</span> <span style="color: #f8f8f2;">moving</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">false</span><span style="color: #f8f8f2;">;</span>
<span style="color: #66d9ef;">void</span> <span style="color: #a6e22e;">Start</span> <span style="color: #f8f8f2;">()</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #75715e;">// First store our current position when the</span>
<span style="color: #75715e;">// script is initialized.</span>
<span style="color: #f8f8f2;">pos</span> <span style="color: #f8f8f2;">=</span> <span style="color: #f8f8f2;">transform.position;</span>
<span style="color: #75715e;">// Find all NPCs with the tag "npc":</span>
<span style="color: #f8f8f2;">npcObjects</span> <span style="color: #f8f8f2;">=</span> <span style="color: #f8f8f2;">GameObject.FindGameObjectsWithTag</span> <span style="color: #f8f8f2;">(</span><span style="color: #e6db74;">"npc"</span><span style="color: #f8f8f2;">);</span>
<span style="color: #f8f8f2;">npcControllers</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">new</span> <span style="color: #f8f8f2;">NPCController[npcObjects.Length];</span>
<span style="color: #75715e;">// Iterate through them and store their NPCController to</span>
<span style="color: #75715e;">// npcControllers array:</span>
<span style="color: #66d9ef;">for</span><span style="color: #f8f8f2;">(</span><span style="color: #66d9ef;">int</span> <span style="color: #f8f8f2;">i</span> <span style="color: #f8f8f2;">=</span> <span style="color: #ae81ff;">0</span><span style="color: #f8f8f2;">;</span> <span style="color: #f8f8f2;">i</span> <span style="color: #f8f8f2;"><</span> <span style="color: #f8f8f2;">npcObjects.Length;</span> <span style="color: #f8f8f2;">i++)</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">npcControllers[i]</span> <span style="color: #f8f8f2;">=</span> <span style="color: #f8f8f2;">(NPCController)</span> <span style="color: #f8f8f2;">npcObjects[i]</span>
<span style="color: #f8f8f2;">.GetComponent(</span><span style="color: #66d9ef;">typeof</span><span style="color: #f8f8f2;">(NPCController));</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #66d9ef;">void</span> <span style="color: #a6e22e;">Update</span> <span style="color: #f8f8f2;">()</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">CheckInput();</span>
<span style="color: #66d9ef;">if</span><span style="color: #f8f8f2;">(moving)</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">transform.position</span> <span style="color: #f8f8f2;">=</span> <span style="color: #f8f8f2;">pos;</span>
<span style="color: #f8f8f2;">moving</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">false</span><span style="color: #f8f8f2;">;</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #66d9ef;">private</span> <span style="color: #66d9ef;">void</span> <span style="color: #a6e22e;">CheckInput</span><span style="color: #f8f8f2;">()</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #75715e;">// WASD control</span>
<span style="color: #75715e;">// We add the direction to our position,</span>
<span style="color: #75715e;">// this moves the character 1 unit (32 pixels)</span>
<span style="color: #66d9ef;">if</span> <span style="color: #f8f8f2;">(Input.GetKeyDown(KeyCode.D)</span> <span style="color: #f8f8f2;">||</span> <span style="color: #f8f8f2;">Input.GetKeyDown(KeyCode.RightArrow))</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">pos</span> <span style="color: #f8f8f2;">+=</span> <span style="color: #f8f8f2;">Vector2.right;</span>
<span style="color: #f8f8f2;">moving</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">true</span><span style="color: #f8f8f2;">;</span>
<span style="color: #f8f8f2;">ExecuteNPCAI();</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #75715e;">// For left, we have to substract the direction</span>
<span style="color: #66d9ef;">else</span> <span style="color: #a6e22e;">if</span> <span style="color: #f8f8f2;">(Input.GetKeyDown(KeyCode.A)</span> <span style="color: #f8f8f2;">||</span> <span style="color: #f8f8f2;">Input.GetKeyDown(KeyCode.LeftArrow))</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">pos</span> <span style="color: #f8f8f2;">-=</span> <span style="color: #f8f8f2;">Vector2.right;</span>
<span style="color: #f8f8f2;">moving</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">true</span><span style="color: #f8f8f2;">;</span>
<span style="color: #f8f8f2;">ExecuteNPCAI();</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #66d9ef;">else</span> <span style="color: #a6e22e;">if</span> <span style="color: #f8f8f2;">(Input.GetKeyDown(KeyCode.W)</span> <span style="color: #f8f8f2;">||</span> <span style="color: #f8f8f2;">Input.GetKeyDown(KeyCode.UpArrow))</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">pos</span> <span style="color: #f8f8f2;">+=</span> <span style="color: #f8f8f2;">Vector2.up;</span>
<span style="color: #f8f8f2;">moving</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">true</span><span style="color: #f8f8f2;">;</span>
<span style="color: #f8f8f2;">ExecuteNPCAI();</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #75715e;">// Same as for the left, substraction for down</span>
<span style="color: #66d9ef;">else</span> <span style="color: #a6e22e;">if</span> <span style="color: #f8f8f2;">(Input.GetKeyDown(KeyCode.S)</span> <span style="color: #f8f8f2;">||</span> <span style="color: #f8f8f2;">Input.GetKeyDown(KeyCode.DownArrow))</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">pos</span> <span style="color: #f8f8f2;">-=</span> <span style="color: #f8f8f2;">Vector2.up;</span>
<span style="color: #f8f8f2;">moving</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">true</span><span style="color: #f8f8f2;">;</span>
<span style="color: #f8f8f2;">ExecuteNPCAI();</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #75715e;">// Then change the transform to the new position with</span>
<span style="color: #75715e;">// the given speed:</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #66d9ef;">private</span> <span style="color: #66d9ef;">void</span> <span style="color: #a6e22e;">ExecuteNPCAI</span><span style="color: #f8f8f2;">()</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #66d9ef;">foreach</span><span style="color: #f8f8f2;">(NPCController</span> <span style="color: #f8f8f2;">npc</span> <span style="color: #66d9ef;">in</span> <span style="color: #f8f8f2;">npcControllers)</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">npc.ExecuteAI();</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #f8f8f2;">}</span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
<br />
---<br />
<a href="http://atsiitech.blogspot.com/2014/06/turn-based-rpg-with-unity-2d-part-1.html">Part 1: Grid movement</a><br />
<a href="http://atsiitech.blogspot.com/2014/06/turn-based-rpg-with-unity-2d-part-2.html">Part 2: Camera control</a><br />
<a href="http://atsiitech.blogspot.com/2014/08/turn-based-rpg-with-unity-2d-part-3.html">Part 3: Lighting</a><br />
Part 4: NPC AI<br />
<br />
Code is highlighted with <a href="http://hilite.me/" target="_blank">hilite.me</a>Unknownnoreply@blogger.com6tag:blogger.com,1999:blog-5263394476951581519.post-47378923315138789992014-08-18T19:45:00.003+03:002014-08-18T19:50:22.022+03:00Changing the default Mouse Cursor in Unity (hardware acceleration)Unity version: 4.5<br />
Language used: C#<br />
<br />
<div style="text-align: justify;">
I checked some outdated tutorials how to change the default system mouse cursor in Unity but it lagged considerably. So I searched the <a href="http://docs.unity3d.com/ScriptReference/Cursor.SetCursor.html" target="_blank">Unity manual</a> (now why didn't I check there first?). However, I couldn't get this working right away and wondered what was wrong, until I took another look at the inspector. When you're importing your cursor, select the Cursor from the Texture type in the inspector:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIrfi2GV0_ZNyEJqcQiTbIJ3jdiMmPETkbCIn4dxOKSmA1a5TiHE2n8zz8HD7dlsFAV7Q0EUGxtawPhQR6uq3bcvRy_VJoKHM9k2eF9xVXfCdCgZgHLapywFw8dwaqKZmrV8xkhbFRHb9X/s1600/Texture_type_Cursor.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIrfi2GV0_ZNyEJqcQiTbIJ3jdiMmPETkbCIn4dxOKSmA1a5TiHE2n8zz8HD7dlsFAV7Q0EUGxtawPhQR6uq3bcvRy_VJoKHM9k2eF9xVXfCdCgZgHLapywFw8dwaqKZmrV8xkhbFRHb9X/s1600/Texture_type_Cursor.png" height="320" width="307" /></a></div>
<br />
<br />
Then in your main GameObject (or your camera script) add these lines:<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #f8f8f2;">.</span>
<span style="color: #f8f8f2;">.</span>
<span style="color: #f8f8f2;">.</span>
<span style="color: #66d9ef;">public</span> <span style="color: #f8f8f2;">Texture2D</span> <span style="color: #f8f8f2;">cursorTexture;</span>
<span style="color: #66d9ef;">private</span> <span style="color: #f8f8f2;">Vector2</span> <span style="color: #f8f8f2;">hotSpot</span> <span style="color: #f8f8f2;">=</span> <span style="color: #f8f8f2;">Vector2.zero;</span>
<span style="color: #66d9ef;">void</span> <span style="color: #a6e22e;">Start</span><span style="color: #f8f8f2;">()</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">Cursor.SetCursor(cursorTexture,</span> <span style="color: #f8f8f2;">hotSpot,</span> <span style="color: #f8f8f2;">CursorMode.Auto);</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #f8f8f2;">.</span>
<span style="color: #f8f8f2;">.</span>
<span style="color: #f8f8f2;">.</span>
</pre>
</div>
<br />
<br />
CursorMode.Auto means the hardware mouse acceleration will be used on platforms that support it. The hotspot is like the offset location of the cursor. In this case the tip (at 0,0) is the effective part of the cursor.<br />
<br />
Next, drag the cursor texture from the Assets to the Cursor Texture field in the object's script:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKTl0GtYuqXT5LkDzY85xmU65iGqGyPEmQE6letwwrZo3R62-JCC5BIkOtHgeKni71OZLyb2I7m6nKAAZSKC0mJQ82Bp2UL07EjFph3L81_scXiLf4RD9rmEDAe2Nx6Z_JoPwZmvsY_VWV/s1600/drag_cursor_texture_to_object.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKTl0GtYuqXT5LkDzY85xmU65iGqGyPEmQE6letwwrZo3R62-JCC5BIkOtHgeKni71OZLyb2I7m6nKAAZSKC0mJQ82Bp2UL07EjFph3L81_scXiLf4RD9rmEDAe2Nx6Z_JoPwZmvsY_VWV/s1600/drag_cursor_texture_to_object.png" height="163" width="320" /></a></div>
<br />
<br />
On Mac, I couldn't get the cursor showing in the editor while testing. Building and running worked fine though.<br />
<br />
That's it, thanks for reading. :) <br />
<br />
--------------------------------------<br />
Code highlighted with <a href="http://hilite.me/" target="_blank">hilite.me</a>Unknownnoreply@blogger.com5tag:blogger.com,1999:blog-5263394476951581519.post-20824583944611901132014-08-12T21:30:00.000+03:002014-08-23T16:05:44.524+03:00Turn based RPG with Unity 2D - Part 3: Lighting The Map and Pixel Perfect Camera<div style="text-align: justify;">
<br />
<a href="http://atsiitech.blogspot.com/2014/06/turn-based-rpg-with-unity-2d-part-1.html">Part 1: Grid movement</a><br />
<a href="http://atsiitech.blogspot.com/2014/06/turn-based-rpg-with-unity-2d-part-2.html">Part 2: Camera control</a><br />
Part 3: Lighting<br />
<a href="http://atsiitech.blogspot.com/2014/08/turn-based-rpg-with-unity-2d-part-4.html">Part 4: NPC AI</a><br />
<br />
--- </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
First, let's do some changes to our script and make the sprites look crisp whatever the resolution (provided that the aspect ratio stays the same in fullscreen mode).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Open the CamController script and add this line to the Start method:</div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #f8f8f2;">Camera.main.orthographicSize</span> <span style="color: #f8f8f2;">=</span> <span style="color: #f8f8f2;">Screen.height</span> <span style="color: #f8f8f2;">/</span> <span style="color: #ae81ff;">2</span> <span style="color: #f8f8f2;">*</span> <span style="color: #ae81ff;">1</span> <span style="color: #f8f8f2;">/</span> <span style="color: #ae81ff;">32</span><span style="color: #f8f8f2;">;</span>
</pre>
</div>
<br />
Basically we just apply the <a href="http://atsiitech.blogspot.fi/2014/06/turn-based-rpg-with-unity-2d-part-2.html" target="_blank">math from the last post</a> to the camera's size variable. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8cdcbszF6eAUJqTgf7sHVs1FkV6YSfxHePay7TRiXCaMCIdngBsaIvKhWY1-yKg4tbSIEq9K-zzVaJgk3UUoelo-yEldksh5lIbNltpmc3R5zK_srk7D5vGTm47nfpNPKl7rP7yjrG6bC/s1600/before_after.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8cdcbszF6eAUJqTgf7sHVs1FkV6YSfxHePay7TRiXCaMCIdngBsaIvKhWY1-yKg4tbSIEq9K-zzVaJgk3UUoelo-yEldksh5lIbNltpmc3R5zK_srk7D5vGTm47nfpNPKl7rP7yjrG6bC/s1600/before_after.png" /></a></div>
<br />
You'll notice the difference in higher resolutions in fullscreen mode.<br />
<br />
Also, if you didn't do it before, select the player sprite from your assets and in the inspector, change the <b>Filter Mode</b> to <b>Point </b>and hit Apply. This will make the sprite look like it's meant to look:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixo4jT7tjyXoilEA-HkCEzq9wLxNyDFgGbqQcTfyTPYUS54AmIhA4t2D2YD1z6E61cW6LiTdvjuXyDBWmLcchSaTU6xwWP1EI_JUFMKtb1Dg5QGOdB3aDSD1tAO-L5IReISJXnf8WF77L_/s1600/filter_point.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixo4jT7tjyXoilEA-HkCEzq9wLxNyDFgGbqQcTfyTPYUS54AmIhA4t2D2YD1z6E61cW6LiTdvjuXyDBWmLcchSaTU6xwWP1EI_JUFMKtb1Dg5QGOdB3aDSD1tAO-L5IReISJXnf8WF77L_/s1600/filter_point.png" height="263" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<br />
<br />
<h1>
Lighting the map</h1>
<br />
To add some dynamic lighting to our map, create a new <b>material</b> in the assets. Like so:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYT4BZDC8E_pnVeZPsP6FvWuxFoA5Y3YZLIWRSsB2g0rozNSM-z88eYd8zN2K2kSC25vmuq1pMB9g1faUQDBPsr3Ex5IdXIz6RW50yOR8y3EbdPav96al-nC5ETgYH6rLwXkJa_HWhKFsK/s1600/assets_create_material.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYT4BZDC8E_pnVeZPsP6FvWuxFoA5Y3YZLIWRSsB2g0rozNSM-z88eYd8zN2K2kSC25vmuq1pMB9g1faUQDBPsr3Ex5IdXIz6RW50yOR8y3EbdPav96al-nC5ETgYH6rLwXkJa_HWhKFsK/s1600/assets_create_material.png" height="296" width="320" /></a></div>
<br />
In the inspector, change the shader to Sprites/Diffuse:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFCoHYshyphenhyphensPHlD8ZIm1lrlr9Jm6J2wm6SMZ-vmkM5yZUrx-AO54MgQNGsuQaUfbOeLCjGixRjSZGbMOuQbkLwxZd7DEg7DSreIPJzNL32IXZClh5DlwUcYVCfsiiLsWFfS6UmDeM3YB3g7/s1600/shader_sprites_diffuse.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFCoHYshyphenhyphensPHlD8ZIm1lrlr9Jm6J2wm6SMZ-vmkM5yZUrx-AO54MgQNGsuQaUfbOeLCjGixRjSZGbMOuQbkLwxZd7DEg7DSreIPJzNL32IXZClh5DlwUcYVCfsiiLsWFfS6UmDeM3YB3g7/s1600/shader_sprites_diffuse.png" height="320" width="198" /></a></div>
<br />
<div style="text-align: justify;">
Now select the map from the hierarchy (the object with grass grid) and in the inspector, change its material to this new material:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEig5vbGO1hxrSIgyEJEhLag1FWw31iQfeM5vJjKkNp-mJskiIdAosOHO6G6bteJaKibMsNHm4PX7hVIi47f95oqGHwb_sTq-2d3C3riIrOQy5-5xbs8n1LHGpJHWxR5T2L9yr-TrasnFg7k/s1600/select_new_material.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEig5vbGO1hxrSIgyEJEhLag1FWw31iQfeM5vJjKkNp-mJskiIdAosOHO6G6bteJaKibMsNHm4PX7hVIi47f95oqGHwb_sTq-2d3C3riIrOQy5-5xbs8n1LHGpJHWxR5T2L9yr-TrasnFg7k/s1600/select_new_material.png" height="69" width="320" /></a></div>
<br />
<div style="text-align: justify;">
You can add the material to anything you want to be affected by light but let's leave the player sprite alone for now because he's always illuminated. The player sprite might disappear after you add the material, so bring him up by adjusting the <b>Order in Layer</b> (or adding another sorting layer for the player altogether):<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPdSW-8Jl3MnHIYHwTeOKQCbCrKb6MvnShBELeNcgQeh_T5zqzjCg_HCoLFdlFVYZ80kPaIBD0uBqNKZBr9h4Q4cxP_nWFhABnO4ZUfHUoHfJoLBKv3y_e0HfWcUaRFYqXbMaGDymFqhdA/s1600/order_in_layer.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPdSW-8Jl3MnHIYHwTeOKQCbCrKb6MvnShBELeNcgQeh_T5zqzjCg_HCoLFdlFVYZ80kPaIBD0uBqNKZBr9h4Q4cxP_nWFhABnO4ZUfHUoHfJoLBKv3y_e0HfWcUaRFYqXbMaGDymFqhdA/s1600/order_in_layer.png" height="106" width="320" /></a></div>
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Next, add a new <b>point light</b> from the GameObject / Create Other menu:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh62nB-RZ7mr0jKW0Jpr70a7MXX3ViKUTTotn91FkdVo1mUiskLkyWMaR4986R9KYyk7Z9od6VqA5-ijkHkR6Z25BFN_iJ6WPNzTEuwjx7cy7koFQZCXq7sVAAEulGqyLSJc2zhqd1f6htY/s1600/create_point_light.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh62nB-RZ7mr0jKW0Jpr70a7MXX3ViKUTTotn91FkdVo1mUiskLkyWMaR4986R9KYyk7Z9od6VqA5-ijkHkR6Z25BFN_iJ6WPNzTEuwjx7cy7koFQZCXq7sVAAEulGqyLSJc2zhqd1f6htY/s1600/create_point_light.png" height="164" width="320" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
You must adjust the light so it shows on the scene. In the hierarchy window, drop the light object to the player object (this will make it the player object's child and it will follow the player). Also use the arrows on the light object to move it to the center of the player object:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgH1gFaeShL9GdF5_oIA1S-5eBA5MboLqnTVvsWHeaDjoF-l18fRdmIm_tTai1_lKXuST9CaOxNhDuQECo5zTWZll0SO-fGxkLZTRrcfGYyQ7c-Zl_EtapOhQ7uemxZvY6iiYEksKKDWaNE/s1600/drag_light_under_player.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgH1gFaeShL9GdF5_oIA1S-5eBA5MboLqnTVvsWHeaDjoF-l18fRdmIm_tTai1_lKXuST9CaOxNhDuQECo5zTWZll0SO-fGxkLZTRrcfGYyQ7c-Zl_EtapOhQ7uemxZvY6iiYEksKKDWaNE/s1600/drag_light_under_player.png" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1ohbe2HSlKYGO8Xo9KhQuyvoPV0aqEQYLjz7zTZ6PZxAS7Wbp8ZhYsZkbDmbZ-qVICULWE4FhxiHjK4ovvsg1eR19S59cVTeupksga7UpOI_ZtbANETG6S9U5Bj4TaviriSrWWkonYhhf/s1600/move_light_to_player.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1ohbe2HSlKYGO8Xo9KhQuyvoPV0aqEQYLjz7zTZ6PZxAS7Wbp8ZhYsZkbDmbZ-qVICULWE4FhxiHjK4ovvsg1eR19S59cVTeupksga7UpOI_ZtbANETG6S9U5Bj4TaviriSrWWkonYhhf/s1600/move_light_to_player.png" /></a></div>
</div>
<div style="text-align: justify;">
<br />
Change the light object's Z-value to something negative to make it show on the map. The higher the number (to negative), the farther the light goes from the player. Set it to -1.5 for now. You can experiment with it for better results.<br />
<br />
You can also move the light in the Z-axis in 3D mode. Just click the little 2D button on top of your scene window to toggle the mode. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGXdh1xx3sWdSaW_RY9sMTHcvE0AnyyAW_QcI1lxYzy8qu2DELkqDT0DhunIEp6VdGlWLLwKoS9XqYBHHwjmcPUnhsSh3glDToTIJxdlRrC1_2uzlJAd-qtB4sa8trGB9-OSgpk2pvMRfp/s1600/move_light_z_axis.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGXdh1xx3sWdSaW_RY9sMTHcvE0AnyyAW_QcI1lxYzy8qu2DELkqDT0DhunIEp6VdGlWLLwKoS9XqYBHHwjmcPUnhsSh3glDToTIJxdlRrC1_2uzlJAd-qtB4sa8trGB9-OSgpk2pvMRfp/s1600/move_light_z_axis.png" height="274" width="320" /></a></div>
<br />
To make it really dark, like night time, change the ambient lighting from Edit / Render Settings:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYxYEiOXXAAEtzbjxV8Hs0kDflLYB3-vZzx3AY-QwrIONfwQROjgmuanCYyvTb0A6lpUzOwr3EgnydX1-Z3jX_8Way7lyW8X_hRSECuQ5IIgb9FIOWBWd64vybnlSm5NCZqD4L_zslj7Fy/s1600/change_ambient_light.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYxYEiOXXAAEtzbjxV8Hs0kDflLYB3-vZzx3AY-QwrIONfwQROjgmuanCYyvTb0A6lpUzOwr3EgnydX1-Z3jX_8Way7lyW8X_hRSECuQ5IIgb9FIOWBWd64vybnlSm5NCZqD4L_zslj7Fy/s1600/change_ambient_light.png" height="296" width="320" /></a></div>
<br />
<br />
The result:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi42Otyie1G_dczyexLGnItxievnx15RV2t-5wLsDhgqQJGpD6VpcpAOHSIjzPUv0DuIqezFBCrMB0QC5Q2o4wvgFxB4WtnRo_KFnZnLQWqOTl118jF5m668juXjvSTu_R-HjIP0wnXvO-O/s1600/result.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi42Otyie1G_dczyexLGnItxievnx15RV2t-5wLsDhgqQJGpD6VpcpAOHSIjzPUv0DuIqezFBCrMB0QC5Q2o4wvgFxB4WtnRo_KFnZnLQWqOTl118jF5m668juXjvSTu_R-HjIP0wnXvO-O/s1600/result.png" /></a></div>
</div>
<div style="text-align: justify;">
<br />
<br />
Thanks for reading! More tutorials coming up.<br />
<br />
---<br />
<br />
<a href="http://atsiitech.blogspot.com/2014/06/turn-based-rpg-with-unity-2d-part-1.html">Part 1: Grid movement</a><br />
<a href="http://atsiitech.blogspot.com/2014/06/turn-based-rpg-with-unity-2d-part-2.html">Part 2: Camera control</a><br />
Part 3: Lighting<br />
<a href="http://atsiitech.blogspot.com/2014/08/turn-based-rpg-with-unity-2d-part-4.html">Part 4: NPC AI</a><br />
<br />
Code highlighted with: <a href="http://hilite.me/" target="_blank">hilite.me</a></div>
Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-5263394476951581519.post-14353621821290873782014-06-04T23:03:00.001+03:002014-11-12T18:08:05.843+02:00Turn based RPG with Unity 2D - Part 2: Camera control<div style="text-align: justify;">
<a href="http://atsiitech.blogspot.com/2014/06/turn-based-rpg-with-unity-2d-part-1.html">Part 1: Grid movement</a><br />
Part 2: Camera control<br />
<a href="http://atsiitech.blogspot.com/2014/08/turn-based-rpg-with-unity-2d-part-3.html">Part 3: Lighting</a><br />
<a href="http://atsiitech.blogspot.com/2014/08/turn-based-rpg-with-unity-2d-part-4.html">Part 4: NPC AI</a><br />
<br />
--- <br />
<a href="http://atsiitech.blogspot.com/2014/06/turn-based-rpg-with-unity-2d-part-1.html" target="_blank"></a></div>
<div style="text-align: justify;">
<br />
<br /></div>
<div style="text-align: justify;">
So now our player character can move around in the grid but the camera is still. If we want the camera to follow, we need to add some script.</div>
<div style="text-align: justify;">
<br />
<i>(Edited 28. June 2014 for better camera scale</i>)</div>
<div style="text-align: justify;">
First, let's adjust the camera size. You probably have a preference how big everything looks on the screen but I like it in the scale 1 to 1. Let's do some math:<br />
<br />
We have 1 unit which is 32 pixels. Let's say our screen height is 768 pixels. All we have to do is count the camera size with this formula:<br />
<br />
<div style="text-align: center;">
<span style="font-family: "Courier New",Courier,monospace;">screen_height / 2 * 1 / unit_size</span></div>
<div style="text-align: center;">
<span style="font-family: "Courier New",Courier,monospace;">=</span></div>
<div style="text-align: center;">
<span style="font-family: "Courier New",Courier,monospace;">768/2 * 1/ 32</span></div>
<div style="text-align: center;">
<br /></div>
<div style="text-align: left;">
The answer is 12. This is your camera size.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7YgBZ7z6H6c_poUl4albfazoBmEaQ7jy00k67n-aPR4C6ep7cdXBII_VHuR-h9XKGjhwUAiOyTXsA8oLp6mp9JT0z568vpUrWUjGT8O0vw5z7gr399FJ8VPBWxoBtns75pNZ8p2DpmvCd/s1600/camera_size_unity.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7YgBZ7z6H6c_poUl4albfazoBmEaQ7jy00k67n-aPR4C6ep7cdXBII_VHuR-h9XKGjhwUAiOyTXsA8oLp6mp9JT0z568vpUrWUjGT8O0vw5z7gr399FJ8VPBWxoBtns75pNZ8p2DpmvCd/s1600/camera_size_unity.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Now, create another script in the assets and call it CamController:</div>
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: #66d9ef;">using</span> <span style="color: #f8f8f2;">UnityEngine;</span>
<span style="color: #66d9ef;">using</span> <span style="color: #f8f8f2;">System.Collections;</span>
<span style="color: #66d9ef;">public</span> <span style="color: #66d9ef;">class</span> <span style="color: #a6e22e;">CamController</span> <span style="color: #f8f8f2;">:</span> <span style="color: #f8f8f2;">MonoBehaviour</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #66d9ef;">public</span> <span style="color: #f8f8f2;">GameObject</span> <span style="color: #f8f8f2;">target;</span> <span style="color: #75715e;">// The player</span>
<span style="color: #66d9ef;">private</span> <span style="color: #f8f8f2;">Vector3</span> <span style="color: #f8f8f2;">offset;</span>
<span style="color: #66d9ef;">void</span> <span style="color: #a6e22e;">Start</span> <span style="color: #f8f8f2;">()</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #75715e;">// Change the z value of the offset</span>
<span style="color: #75715e;">// to something below the sprites.</span>
<span style="color: #75715e;">// Otherwise you can't see anything:</span>
<span style="color: #f8f8f2;">offset</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">new</span> <span style="color: #f8f8f2;">Vector3(</span><span style="color: #ae81ff;">0f</span><span style="color: #f8f8f2;">,</span> <span style="color: #ae81ff;">0f</span><span style="color: #f8f8f2;">,</span> <span style="color: #f8f8f2;">-</span><span style="color: #ae81ff;">10f</span><span style="color: #f8f8f2;">);</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #66d9ef;">void</span> <span style="color: #a6e22e;">Update</span> <span style="color: #f8f8f2;">()</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #75715e;">// Let's put the movement in LateUpdate (called after Update function)</span>
<span style="color: #66d9ef;">void</span> <span style="color: #a6e22e;">LateUpdate</span><span style="color: #f8f8f2;">()</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #75715e;">// Change camera's position to the same as the player (with the z-value of -10)</span>
<span style="color: #f8f8f2;">transform.position</span> <span style="color: #f8f8f2;">=</span> <span style="color: #f8f8f2;">target.transform.position</span> <span style="color: #f8f8f2;">+</span> <span style="color: #f8f8f2;">offset;</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #f8f8f2;">}</span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Now drag the script to the <i>Main Camera</i> -object in the hierarchy view. In the inspector, scroll down to <i>Cam Controller (Script)</i> component and set the target by clicking the small circle:</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCRZ0nzIv2ZAip0uMzM-q3YHtkgRwP04KuMq3hoCjudVKKbKwxmMWYpZBflxnk5kj0qqiT33EXPSddulRQpkIOqsm977eVMicthswBTTmjkUEC2OzjKEpDDXcM3w0WOX9W3OTq2VcnXxR8/s1600/camera_controller_script.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCRZ0nzIv2ZAip0uMzM-q3YHtkgRwP04KuMq3hoCjudVKKbKwxmMWYpZBflxnk5kj0qqiT33EXPSddulRQpkIOqsm977eVMicthswBTTmjkUEC2OzjKEpDDXcM3w0WOX9W3OTq2VcnXxR8/s1600/camera_controller_script.png" height="127" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">CamController in Main Camera object</td></tr>
</tbody></table>
<br />
<div style="text-align: justify;">
Go back to PlayerController script and change the speed to something higher, like 50 to make the movement snappier.<br />
<br />
---<br />
<br />
<br />
<a href="http://atsiitech.blogspot.com/2014/06/turn-based-rpg-with-unity-2d-part-1.html">Part 1: Grid movement</a><br />
Part 2: Camera control<br />
<a href="http://atsiitech.blogspot.com/2014/08/turn-based-rpg-with-unity-2d-part-3.html">Part 3: Lighting</a><br />
<a href="http://atsiitech.blogspot.com/2014/08/turn-based-rpg-with-unity-2d-part-4.html">Part 4: NPC AI</a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Code highlighted with <a href="http://hilite.me/" target="_blank">hilite.me</a> </div>
Unknownnoreply@blogger.com4tag:blogger.com,1999:blog-5263394476951581519.post-68405864259287219552014-06-04T20:13:00.001+03:002014-08-23T16:03:42.450+03:00Turn based RPG with Unity 2D - Part 1: Grid movement (tutorial)<b>DISCLAIMER:</b> This is my tutorial of making a really simple RPG or roguelike with Unity in 2D mode. I'm not a professional Unity developer (just picked it up) and I'm prototyping as I go. Feel free to comment some good practices.<br />
<br />
---<br />
Part 1: Grid movement<br />
<a href="http://atsiitech.blogspot.com/2014/06/turn-based-rpg-with-unity-2d-part-2.html">Part 2: Camera control</a><br />
<a href="http://atsiitech.blogspot.com/2014/08/turn-based-rpg-with-unity-2d-part-3.html">Part 3: Lighting</a><br />
<a href="http://atsiitech.blogspot.com/2014/08/turn-based-rpg-with-unity-2d-part-4.html">Part 4: NPC AI</a><br />
<br />
<h2>
Setting up the project</h2>
<h3>
</h3>
First, let's decide our cell size in the grid:<br />
<br />
32 x 32 pixels - done.<br />
<br />
Then start your new project normally (in 2D mode), let's call it RPGTutorial. Now I made a really simple 32 x 32 pixel square character for this purpose and imported it to Unity:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihysgh8aGL89cUHuPd48Gs_oLQKUC34tB-cycXre8krjkNf0GG51k6YosCCKqQgFajLnuA-XCuZPDGHwcr1tQVvHlHD6XAFtqMJuXEge-ESN0EHDaWUX-leWJaIUoV9qor_aowq-oGNOGx/s1600/player.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihysgh8aGL89cUHuPd48Gs_oLQKUC34tB-cycXre8krjkNf0GG51k6YosCCKqQgFajLnuA-XCuZPDGHwcr1tQVvHlHD6XAFtqMJuXEge-ESN0EHDaWUX-leWJaIUoV9qor_aowq-oGNOGx/s1600/player.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The character</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgF4ZdRtMuItNhB7zTPxJOm13C-Vvcamy21uW608FqX1QEFYCL72eafw7ILvBVt0SIWsoKN4INdZZmvO_1N781H5tb6YTgFfYp1UMyWjlHviyrCcyCqu2kfLmnyhjQrfCMgzBMNbq5-2Dh4/s1600/unity_import_asset.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgF4ZdRtMuItNhB7zTPxJOm13C-Vvcamy21uW608FqX1QEFYCL72eafw7ILvBVt0SIWsoKN4INdZZmvO_1N781H5tb6YTgFfYp1UMyWjlHviyrCcyCqu2kfLmnyhjQrfCMgzBMNbq5-2Dh4/s1600/unity_import_asset.png" height="122" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Drag the character to Assets in Unity project</td></tr>
</tbody></table>
<br />
Then use the inspector (click the player sprite) and change the <i>pixels to units</i> to 32 and hit apply:<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnHWadBoWEVkImZulefImrs34BtoSR7tWjj_LxLPfQ0XhpPRNFKeHQuBPMmdZ4StE8Ycl1Vs738zQq2vU06KpzkUKDUFfcWoIm5-qo5P5_GEhN5hRcFnEKwJRN6NPTSchcvO0NqcD4T3sf/s1600/unity_change_pixels_to_units.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnHWadBoWEVkImZulefImrs34BtoSR7tWjj_LxLPfQ0XhpPRNFKeHQuBPMmdZ4StE8Ycl1Vs738zQq2vU06KpzkUKDUFfcWoIm5-qo5P5_GEhN5hRcFnEKwJRN6NPTSchcvO0NqcD4T3sf/s1600/unity_change_pixels_to_units.png" height="265" width="320" /></a></div>
<br />
<br />
Then, for prototyping purposes I made a grid background (you will probably make the level with a tile based editor but for this purpose, I just quickly whipped up a single image and imported it to Unity):<br />
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIYwCxFQLKSKBBlJ6T04IworJEhrEB4tsGP_dgsgOBVJe-iyqNkQdcmYAPdTkHakjW2NioE3NvkEKi-Dc7dZP6fp2d6XclMf9KJUkrDfkkI1GG2I7U3cTI6mFNVpeR-13gAxnDfVfd7lb_/s1600/the_grid.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIYwCxFQLKSKBBlJ6T04IworJEhrEB4tsGP_dgsgOBVJe-iyqNkQdcmYAPdTkHakjW2NioE3NvkEKi-Dc7dZP6fp2d6XclMf9KJUkrDfkkI1GG2I7U3cTI6mFNVpeR-13gAxnDfVfd7lb_/s1600/the_grid.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Background</td></tr>
</tbody></table>
<br />
Also change the pixels to units to 32 for this asset, then drag it to the scene. Also drag the player sprite on top of the grid like so:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgS40ExgegINHlkT-LIZpfvZjrhrbekOYgDWaYThi0YfN_3ljHMjWKpECRzRSGcpLMKbubz8-lA3DeWfMFN9d5iyCZGsup5cL4nW302FLuy28ZT98n2Nuye3kvKvkif8yS2j8wndxs2Vz9/s1600/scene_view.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgS40ExgegINHlkT-LIZpfvZjrhrbekOYgDWaYThi0YfN_3ljHMjWKpECRzRSGcpLMKbubz8-lA3DeWfMFN9d5iyCZGsup5cL4nW302FLuy28ZT98n2Nuye3kvKvkif8yS2j8wndxs2Vz9/s1600/scene_view.png" height="256" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Scene view</td></tr>
</tbody></table>
<br />
Change the <i>transform X</i> and <i>Y</i> in the inspector to 0 (zero) for the grid to center it. For the player change the X and Y to -3.5 to put it in the corner.<br />
<br />
<h2>
Scripting</h2>
<br />
Create a new C# script in the assets and name it PlayerController. Edit the file like so:<br />
<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: #66d9ef;">using</span> <span style="color: #f8f8f2;">UnityEngine;</span>
<span style="color: #66d9ef;">using</span> <span style="color: #f8f8f2;">System.Collections;</span>
<span style="color: #66d9ef;">public</span> <span style="color: #66d9ef;">class</span> <span style="color: #a6e22e;">PlayerController</span> <span style="color: #f8f8f2;">:</span> <span style="color: #f8f8f2;">MonoBehaviour</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #66d9ef;">private</span> <span style="color: #f8f8f2;">Vector2</span> <span style="color: #f8f8f2;">pos;</span>
<span style="color: #66d9ef;">private</span> <span style="color: #66d9ef;">bool</span> <span style="color: #f8f8f2;">moving</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">false</span><span style="color: #f8f8f2;">;</span>
<span style="color: #66d9ef;">void</span> <span style="color: #a6e22e;">Start</span> <span style="color: #f8f8f2;">()</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #75715e;">// First store our current position when the</span>
<span style="color: #75715e;">// script is initialized.</span>
<span style="color: #f8f8f2;">pos</span> <span style="color: #f8f8f2;">=</span> <span style="color: #f8f8f2;">transform.position;</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #66d9ef;">void</span> <span style="color: #a6e22e;">Update</span> <span style="color: #f8f8f2;">()</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">CheckInput();</span>
<span style="color: #66d9ef;">if</span><span style="color: #f8f8f2;">(moving)</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #75715e;">// pos is changed when there's input from the player</span>
<span style="color: #f8f8f2;">transform.position</span> <span style="color: #f8f8f2;">=</span> <span style="color: #f8f8f2;">pos;</span>
<span style="color: #f8f8f2;">moving</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">false</span><span style="color: #f8f8f2;">;</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #66d9ef;">private</span> <span style="color: #66d9ef;">void</span> <span style="color: #a6e22e;">CheckInput</span><span style="color: #f8f8f2;">()</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #75715e;">// WASD control</span>
<span style="color: #75715e;">// We add the direction to our position,</span>
<span style="color: #75715e;">// this moves the character 1 unit (32 pixels)</span>
<span style="color: #66d9ef;">if</span> <span style="color: #f8f8f2;">(Input.GetKeyDown(KeyCode.D)</span> <span style="color: #f8f8f2;">||</span> <span style="color: #f8f8f2;">Input.GetKeyDown(KeyCode.RightArrow))</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">pos</span> <span style="color: #f8f8f2;">+=</span> <span style="color: #f8f8f2;">Vector2.right;</span>
<span style="color: #f8f8f2;">moving</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">true</span><span style="color: #f8f8f2;">;</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #75715e;">// For left, we have to subtract the direction</span>
<span style="color: #66d9ef;">else</span> <span style="color: #a6e22e;">if</span> <span style="color: #f8f8f2;">(Input.GetKeyDown(KeyCode.A)</span> <span style="color: #f8f8f2;">||</span> <span style="color: #f8f8f2;">Input.GetKeyDown(KeyCode.LeftArrow))</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">pos</span> <span style="color: #f8f8f2;">-=</span> <span style="color: #f8f8f2;">Vector2.right;</span>
<span style="color: #f8f8f2;">moving</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">true</span><span style="color: #f8f8f2;">;</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #66d9ef;">else</span> <span style="color: #a6e22e;">if</span> <span style="color: #f8f8f2;">(Input.GetKeyDown(KeyCode.W)</span> <span style="color: #f8f8f2;">||</span> <span style="color: #f8f8f2;">Input.GetKeyDown(KeyCode.UpArrow))</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">pos</span> <span style="color: #f8f8f2;">+=</span> <span style="color: #f8f8f2;">Vector2.up;</span>
<span style="color: #f8f8f2;">moving</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">true</span><span style="color: #f8f8f2;">;</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #75715e;">// Same as for the left, subtraction for down</span>
<span style="color: #66d9ef;">else</span> <span style="color: #a6e22e;">if</span> <span style="color: #f8f8f2;">(Input.GetKeyDown(KeyCode.S)</span> <span style="color: #f8f8f2;">||</span> <span style="color: #f8f8f2;">Input.GetKeyDown(KeyCode.DownArrow))</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">pos</span> <span style="color: #f8f8f2;">-=</span> <span style="color: #f8f8f2;">Vector2.up;</span>
<span style="color: #f8f8f2;">moving</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">true</span><span style="color: #f8f8f2;">;</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #f8f8f2;">}</span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
Save the script and drag it from the assets to the player object in the Hierarchy view. Hit play and test the movement with WASD keys.<br />
<br />
---<br />
<br />
<br />
Part 1: Grid movement<br />
<a href="http://atsiitech.blogspot.com/2014/06/turn-based-rpg-with-unity-2d-part-2.html">Part 2: Camera control</a><br />
<a href="http://atsiitech.blogspot.com/2014/08/turn-based-rpg-with-unity-2d-part-3.html">Part 3: Lighting</a><br />
<a href="http://atsiitech.blogspot.com/2014/08/turn-based-rpg-with-unity-2d-part-4.html">Part 4: NPC AI</a><br />
<br />
Code highlighted with <a href="http://hilite.me/" target="_blank">hilite.me</a> Unknownnoreply@blogger.com8tag:blogger.com,1999:blog-5263394476951581519.post-10791438999470827332014-03-02T14:41:00.002+02:002014-03-02T14:41:44.236+02:00Year In Gamedev's Life (YIGL) - February summaryThis is the February post of <a href="http://atsiitech.blogspot.fi/2013/11/year-in-gamedevs-life-or-yigl.html" target="_blank">YIGL</a>. Previous post: <a href="http://atsiitech.blogspot.fi/2014/01/year-in-gamedevs-life-yigl-january.html" target="_blank">January summary</a>.<br />
<br />
<div style="text-align: justify;">
First things first, <a href="http://zunyrook.com/" target="_blank">Zunyrook the Sci-Fi RPG</a> is doing well. I have developed a dialogue system which is still quite naive but we're getting there. I also experimented with <a href="http://yoyogames.com/" target="_blank">GameMaker Studio</a> on how it could improve my productivity. I cooked up the same basis for the game in a week so it promises well. However, optimizing the game can get tricky the more areas I add so I must now make pros and cons and choose whether I want to continue with LibGDX or GameMaker. I kinda like them both but from a different perspective.</div>
<br />
<div style="text-align: justify;">
During February I also published my first game. I made it while I was learning the GameMaker interface so it's really simple and a clone of millions of similar games. The idea was to test the publishing process, advertisement, feedback, etc.</div>
<div style="text-align: justify;">
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeEICX2r0Nl6bHbOya1X_CsCv-ZOrrUWT28C29n_PR_k2c361hO0U3LMy6EfJ86Y4bM1ue8Pht5ExoJk6UlqC6peYHZ6wPNYuLuUSraf1wZNMCqDNO4h2LrE5hHs3PaI-cPfdmhkaxJgmj/s1600/stellaralley_logo_huge.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeEICX2r0Nl6bHbOya1X_CsCv-ZOrrUWT28C29n_PR_k2c361hO0U3LMy6EfJ86Y4bM1ue8Pht5ExoJk6UlqC6peYHZ6wPNYuLuUSraf1wZNMCqDNO4h2LrE5hHs3PaI-cPfdmhkaxJgmj/s1600/stellaralley_logo_huge.png" height="320" width="320" /></a></div>
<br />
<div style="text-align: justify;">
I will write a more detailed blog post of that process later. You can <a href="https://play.google.com/store/apps/details?id=com.atsiitech.stellaralley" target="_blank">download Stellar Alley from the Google Play store</a>. The background on the logo is an excerpt of a photo of the <a href="http://en.wikipedia.org/wiki/File:Small_magellanic_cloud.jpg" target="_blank">Magellanic Clouds</a>.</div>
<br />
<div style="text-align: justify;">
Game development continues with Zunyrook RPG and a couple of other games I have in mind. Hopefully I'll have more screenshots in the March post. Thanks for reading!</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-5263394476951581519.post-73125835122679812272014-02-09T02:47:00.000+02:002014-02-09T02:47:53.396+02:00Programming a Role Playing Game - Part 2: Quests and JournalThis series started with the <span style="font-family: "Courier New",Courier,monospace;">Player</span> class:<br />
<br />
<a href="http://atsiitech.blogspot.com/2014/02/programming-role-playing-game-part-1.html" target="_blank">Programming a Role Playing Game - Part 1: The Player</a><br />
<br />
In the first part we created a Journal object. Now we need to implement the class.<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #f92672;">package</span> <span style="color: #f8f8f2;">com</span><span style="color: #f92672;">.</span><span style="color: #a6e22e;">atsiitech</span><span style="color: #f92672;">.</span><span style="color: #a6e22e;">rpg</span><span style="color: #f92672;">.</span><span style="color: #a6e22e;">models</span><span style="color: #f92672;">.</span><span style="color: #a6e22e;">journal</span><span style="color: #f92672;">;</span>
<span style="color: #f92672;">import</span> <span style="color: #f8f8f2;">com.badlogic.gdx.utils.Array</span><span style="color: #f92672;">;</span>
<span style="color: #66d9ef;">public</span> <span style="color: #66d9ef;">class</span> <span style="color: #a6e22e;">Journal</span> <span style="color: #f92672;">{</span>
<span style="color: #66d9ef;">private</span> <span style="color: #f8f8f2;">Array</span><span style="color: #f92672;"><</span><span style="color: #f8f8f2;">Quest</span><span style="color: #f92672;">></span> <span style="color: #f8f8f2;">quests</span><span style="color: #f92672;">;</span>
<span style="color: #66d9ef;">public</span> <span style="color: #a6e22e;">Journal</span><span style="color: #f92672;">()</span> <span style="color: #f92672;">{</span>
<span style="color: #f8f8f2;">quests</span> <span style="color: #f92672;">=</span> <span style="color: #66d9ef;">new</span> <span style="color: #f8f8f2;">Array</span><span style="color: #f92672;"><</span><span style="color: #f8f8f2;">Quest</span><span style="color: #f92672;">>();</span>
<span style="color: #f92672;">}</span>
<span style="color: #66d9ef;">public</span> <span style="color: #f8f8f2;">Array</span><span style="color: #f92672;"><</span><span style="color: #f8f8f2;">Quest</span><span style="color: #f92672;">></span> <span style="color: #a6e22e;">getQuests</span><span style="color: #f92672;">()</span> <span style="color: #f92672;">{</span> <span style="color: #66d9ef;">return</span> <span style="color: #f8f8f2;">quests</span><span style="color: #f92672;">;</span> <span style="color: #f92672;">}</span>
<span style="color: #66d9ef;">public</span> <span style="color: #66d9ef;">void</span> <span style="color: #a6e22e;">addQuest</span><span style="color: #f92672;">(</span><span style="color: #f8f8f2;">Quest</span> <span style="color: #f8f8f2;">quest</span><span style="color: #f92672;">)</span> <span style="color: #f92672;">{</span>
<span style="color: #f8f8f2;">quests</span><span style="color: #f92672;">.</span><span style="color: #a6e22e;">add</span><span style="color: #f92672;">(</span><span style="color: #f8f8f2;">quest</span><span style="color: #f92672;">);</span>
<span style="color: #f92672;">}</span>
<span style="color: #f92672;">}</span>
</pre>
</div>
<br />
<br />
<div style="text-align: justify;">
I put it in the <span style="font-family: "Courier New",Courier,monospace;">models.journal</span> package to keep everything organized. The journal at this stage is pretty simple, we will deal with the UI in another class. Here we will make an <span style="font-family: "Courier New",Courier,monospace;">Array</span> of the <span style="font-family: "Courier New",Courier,monospace;">Quest</span> class. You could add a <span style="font-family: "Courier New",Courier,monospace;">Quest</span> to the array by calling <span style="font-family: "Courier New",Courier,monospace;">getQuests().add()</span> but I made a convenience method for readability.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
And now we have to create the <span style="font-family: "Courier New",Courier,monospace;">Quest</span> class.<br />
<br /></div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #f92672;">package</span> <span style="color: #f8f8f2;">com</span><span style="color: #f92672;">.</span><span style="color: #a6e22e;">atsiitech</span><span style="color: #f92672;">.</span><span style="color: #a6e22e;">rpg</span><span style="color: #f92672;">.</span><span style="color: #a6e22e;">models</span><span style="color: #f92672;">.</span><span style="color: #a6e22e;">journal</span><span style="color: #f92672;">;</span>
<span style="color: #66d9ef;">public</span> <span style="color: #66d9ef;">class</span> <span style="color: #a6e22e;">Quest</span> <span style="color: #f92672;">{</span>
<span style="color: #66d9ef;">private</span> <span style="color: #f8f8f2;">String</span> <span style="color: #f8f8f2;">title</span><span style="color: #f92672;">;</span>
<span style="color: #66d9ef;">private</span> <span style="color: #f8f8f2;">String</span> <span style="color: #f8f8f2;">description</span><span style="color: #f92672;">;</span>
<span style="color: #66d9ef;">private</span> <span style="color: #66d9ef;">int</span> <span style="color: #f8f8f2;">priority</span><span style="color: #f92672;">;</span>
<span style="color: #66d9ef;">private</span> <span style="color: #66d9ef;">boolean</span> <span style="color: #f8f8f2;">finished</span><span style="color: #f92672;">;</span>
<span style="color: #66d9ef;">public</span> <span style="color: #a6e22e;">Quest</span><span style="color: #f92672;">(</span><span style="color: #f8f8f2;">String</span> <span style="color: #f8f8f2;">title</span><span style="color: #f92672;">,</span> <span style="color: #f8f8f2;">String</span> <span style="color: #f8f8f2;">description</span><span style="color: #f92672;">,</span> <span style="color: #66d9ef;">int</span> <span style="color: #f8f8f2;">priority</span><span style="color: #f92672;">)</span> <span style="color: #f92672;">{</span>
<span style="color: #66d9ef;">this</span><span style="color: #f92672;">.</span><span style="color: #a6e22e;">title</span> <span style="color: #f92672;">=</span> <span style="color: #f8f8f2;">title</span><span style="color: #f92672;">;</span>
<span style="color: #66d9ef;">this</span><span style="color: #f92672;">.</span><span style="color: #a6e22e;">description</span> <span style="color: #f92672;">=</span> <span style="color: #f8f8f2;">description</span><span style="color: #f92672;">;</span>
<span style="color: #66d9ef;">this</span><span style="color: #f92672;">.</span><span style="color: #a6e22e;">priority</span> <span style="color: #f92672;">=</span> <span style="color: #f8f8f2;">priority</span><span style="color: #f92672;">;</span>
<span style="color: #f8f8f2;">finished</span> <span style="color: #f92672;">=</span> <span style="color: #66d9ef;">false</span><span style="color: #f92672;">;</span>
<span style="color: #f92672;">}</span>
<span style="color: #66d9ef;">public</span> <span style="color: #f8f8f2;">String</span> <span style="color: #a6e22e;">getTitle</span><span style="color: #f92672;">()</span> <span style="color: #f92672;">{</span> <span style="color: #66d9ef;">return</span> <span style="color: #f8f8f2;">title</span><span style="color: #f92672;">;</span> <span style="color: #f92672;">}</span>
<span style="color: #66d9ef;">public</span> <span style="color: #f8f8f2;">String</span> <span style="color: #a6e22e;">getDescription</span><span style="color: #f92672;">()</span> <span style="color: #f92672;">{</span> <span style="color: #66d9ef;">return</span> <span style="color: #f8f8f2;">description</span><span style="color: #f92672;">;</span> <span style="color: #f92672;">}</span>
<span style="color: #66d9ef;">public</span> <span style="color: #66d9ef;">int</span> <span style="color: #a6e22e;">getPriority</span><span style="color: #f92672;">()</span> <span style="color: #f92672;">{</span> <span style="color: #66d9ef;">return</span> <span style="color: #f8f8f2;">priority</span><span style="color: #f92672;">;</span> <span style="color: #f92672;">}</span>
<span style="color: #66d9ef;">public</span> <span style="color: #66d9ef;">void</span> <span style="color: #a6e22e;">setPriority</span><span style="color: #f92672;">(</span><span style="color: #66d9ef;">int</span> <span style="color: #f8f8f2;">priority</span><span style="color: #f92672;">)</span> <span style="color: #f92672;">{</span> <span style="color: #66d9ef;">this</span><span style="color: #f92672;">.</span><span style="color: #a6e22e;">priority</span> <span style="color: #f92672;">=</span> <span style="color: #f8f8f2;">priority</span><span style="color: #f92672;">;</span> <span style="color: #f92672;">}</span>
<span style="color: #66d9ef;">public</span> <span style="color: #66d9ef;">boolean</span> <span style="color: #a6e22e;">isFinished</span><span style="color: #f92672;">()</span> <span style="color: #f92672;">{</span> <span style="color: #66d9ef;">return</span> <span style="color: #f8f8f2;">finished</span><span style="color: #f92672;">;</span> <span style="color: #f92672;">}</span>
<span style="color: #66d9ef;">public</span> <span style="color: #66d9ef;">void</span> <span style="color: #a6e22e;">finish</span><span style="color: #f92672;">()</span> <span style="color: #f92672;">{</span> <span style="color: #f8f8f2;">finished</span> <span style="color: #f92672;">=</span> <span style="color: #66d9ef;">true</span><span style="color: #f92672;">;</span> <span style="color: #f92672;">}</span>
<span style="color: #f92672;">}</span>
</pre>
</div>
<br />
<br />
<div style="text-align: justify;">
The class is pretty self explanatory if you know Java or other object-oriented languages already. The attribute <span style="font-family: "Courier New",Courier,monospace;">priority</span> is used in sorting. And attribute <span style="font-family: "Courier New",Courier,monospace;">finished</span> is also used to move the quest to the "Done Quests" -tab in the UI.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
We can now add some test quests to the <span style="font-family: "Courier New",Courier,monospace;">Journal</span> from the <span style="font-family: "Courier New",Courier,monospace;">Player</span> class.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #f8f8f2;">Player</span><span style="color: #f92672;">.</span><span style="color: #a6e22e;">journal</span><span style="color: #f92672;">.</span><span style="color: #a6e22e;">addQuest</span><span style="color: #f92672;">(</span>
<span style="color: #66d9ef;">new</span> <span style="color: #a6e22e;">Quest</span><span style="color: #f92672;">(</span>
<span style="color: #e6db74;">"Clear the basement"</span><span style="color: #f92672;">,</span>
<span style="color: #e6db74;">"The basement is filled with rats, you must clear them or this is not considered RPG"</span><span style="color: #f92672;">,</span>
<span style="color: #ae81ff;">1</span>
<span style="color: #f92672;">)</span>
<span style="color: #f92672;">);</span>
</pre>
</div>
<br />
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Since the journal in the <span style="font-family: "Courier New",Courier,monospace;">Player</span> class is static, we must access it like that. This would be the initial quest that shows in the player's journal, with title, description and the 1st priority.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
That's all for now, more to come. Thanks for reading!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Code formatted with <a href="http://hilite.me/" target="_blank">hilite.me</a></div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-5263394476951581519.post-52697041331840190472014-02-08T20:42:00.000+02:002014-02-09T03:05:48.022+02:00Programming a Role Playing Game - Part 1: The Player<div style="text-align: justify;">
This case study is much like a personal journal I'm writing while
programming the engine for a turn based role playing game. It is <u>not a tutorial</u> but I hope you will find it useful nonetheless.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I'm using <a href="http://libgdx.badlogicgames.com/" target="_blank">LibGDX</a> as the framework (programmed with Java), <a href="http://mapeditor.org/" target="_blank">Tiled</a> as the map editor and some placeholder graphics I made. The project loosely follows MVC pattern as explained in <a href="http://obviam.net/index.php/the-mvc-pattern-tutorial-building-games/" target="_blank">The MVC pattern tutorial</a> by Tamas Jano.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Code is formatted with <a href="http://hilite.me/" target="_blank">hilite.me</a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b>DISCLAIMER: I'm prototyping as I go so some design choices and practices are not the best ones. Feel free to comment. :)</b></div>
<br />
<br />
<h4>
Where to start </h4>
<br />
<div style="text-align: justify;">
Building a turn based role playing
game is as complex as you make it. That's why I keep it simple for now. I
start with the <span style="font-family: "Courier New",Courier,monospace;">Player</span> class that will grow with these articles. To
follow the MVC pattern, I place it in the <span style="font-family: "Courier New",Courier,monospace;">models</span> package.</div>
<br />
<br />
<h4>
Stats</h4>
<h4>
</h4>
<div style="text-align: justify;">
RPG characters must have stats; hit points, attack, etc. so let's give them to our Player:</div>
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #f92672;">package</span> <span style="color: #f8f8f2;">com</span><span style="color: #f92672;">.</span><span style="color: #a6e22e;">atsiitech</span><span style="color: #f92672;">.</span><span style="color: #a6e22e;">rpg</span><span style="color: #f92672;">.</span><span style="color: #a6e22e;">models</span><span style="color: #f92672;">;</span>
<span style="color: #66d9ef;">public</span> <span style="color: #66d9ef;">class</span> <span style="color: #a6e22e;">Player</span> <span style="color: #f92672;">{</span>
<span style="color: #66d9ef;">private</span> <span style="color: #f8f8f2;">String</span> <span style="color: #f8f8f2;">name</span><span style="color: #f92672;">;</span>
<span style="color: #66d9ef;">private</span> <span style="color: #66d9ef;">int</span> <span style="color: #f8f8f2;">hpMax</span><span style="color: #f92672;">;</span> <span style="color: #75715e;">// Maximum amount of hitpoints</span>
<span style="color: #66d9ef;">private</span> <span style="color: #66d9ef;">int</span> <span style="color: #f8f8f2;">hitpoints</span><span style="color: #f92672;">;</span> <span style="color: #75715e;">// Current amount of hitpoints</span>
<span style="color: #66d9ef;">private</span> <span style="color: #66d9ef;">int</span> <span style="color: #f8f8f2;">attack</span><span style="color: #f92672;">;</span> <span style="color: #75715e;">// Could be also damage, base attack </span>
<span style="color: #f92672;">}</span>
</pre>
</div>
<br />
<br />
<div style="text-align: justify;">
I'm omitting the other stats for now because this is a prototype. You should initialize them in the constructor.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
RPG characters usually have an inventory and journal as well so let's create instances of those and implement them later.</div>
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #f92672;">...</span>
<span style="color: #66d9ef;">public</span> <span style="color: #66d9ef;">static</span> <span style="color: #66d9ef;">final</span> <span style="color: #f8f8f2;">Inventory</span> <span style="color: #f8f8f2;">inventory</span> <span style="color: #f92672;">=</span> <span style="color: #66d9ef;">new</span> <span style="color: #f8f8f2;">Inventory</span><span style="color: #f92672;">();</span>
<span style="color: #66d9ef;">public</span> <span style="color: #66d9ef;">static</span> <span style="color: #66d9ef;">final</span> <span style="color: #f8f8f2;">Journal</span> <span style="color: #f8f8f2;">journal</span> <span style="color: #f92672;">=</span> <span style="color: #66d9ef;">new</span> <span style="color: #f8f8f2;">Journal</span><span style="color: #f92672;">();</span>
<span style="color: #f92672;">...</span>
</pre>
</div>
<br />
<br />
I made them static so they are accessible to the game engine. That way we avoid passing the player as a reference back and forth. It's an issue to debate about but after a lot of spaghetti code I decided to do it like this.<br />
<br />
<br />
<h4>
Sprite</h4>
<h4>
</h4>
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #66d9ef;">private</span> <span style="color: #f8f8f2;">Sprite</span> <span style="color: #f8f8f2;">sprite</span><span style="color: #f92672;">;</span>
<span style="color: #f92672;">...</span>
<span style="color: #66d9ef;">public</span> <span style="color: #a6e22e;">Player</span><span style="color: #f92672;">()</span> <span style="color: #f92672;">{</span>
<span style="color: #f92672;">...</span>
<span style="color: #f8f8f2;">sprite</span> <span style="color: #f92672;">=</span> <span style="color: #66d9ef;">new</span> <span style="color: #f8f8f2;">Sprite</span><span style="color: #f92672;">(</span>
<span style="color: #66d9ef;">new</span> <span style="color: #a6e22e;">Texture</span><span style="color: #f92672;">(</span>
<span style="color: #f8f8f2;">Gdx</span><span style="color: #f92672;">.</span><span style="color: #a6e22e;">files</span><span style="color: #f92672;">.</span><span style="color: #a6e22e;">internal</span><span style="color: #f92672;">(</span><span style="color: #e6db74;">"data/player_texture.png"</span><span style="color: #f92672;">)</span>
<span style="color: #f92672;">)</span>
<span style="color: #f92672;">);</span>
<span style="color: #f92672;">...</span>
<span style="color: #f92672;">}</span>
</pre>
</div>
<br />
<div style="text-align: justify;">
Nothing new here if you already know what it is. We just instantiate a new <span style="font-family: "Courier New",Courier,monospace;">Sprite</span> with a texture found in the <span style="font-family: "Courier New",Courier,monospace;">assets/data</span> folder in the Android project of LibGDX. We'll change this into an animation later on but it could be a static image too if that is what you fancy.<br />
<br />
<br /></div>
<h4>
Positions</h4>
<h4>
</h4>
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #f92672;">...</span>
<span style="color: #66d9ef;">private</span> <span style="color: #f8f8f2;">Vector2</span> <span style="color: #f8f8f2;">position</span><span style="color: #f92672;">;</span>
<span style="color: #66d9ef;">private</span> <span style="color: #f8f8f2;">Vector2</span> <span style="color: #f8f8f2;">locationOnMap</span><span style="color: #f92672;">;</span>
<span style="color: #66d9ef;">private</span> <span style="color: #f8f8f2;">Facing</span> <span style="color: #f8f8f2;">facing</span><span style="color: #f92672;">;</span>
<span style="color: #f92672;">...</span>
</pre>
</div>
<br />
<br />
<br />
<div style="text-align: justify;">
The <span style="font-family: "Courier New",Courier,monospace;">position</span> -attribute is the one that we use to draw our sprite on the screen and <span style="font-family: "Courier New",Courier,monospace;">locationOnMap</span> is used for calculating collisions and other map-related data. <span style="font-family: "Courier New",Courier,monospace;">Facing</span> is an enumerator that we will implement next. It basically just tells what way our character is facing.</div>
<br />
<br />
<h4>
Enums</h4>
<br />
<div style="text-align: justify;">
For the <span style="font-family: "Courier New",Courier,monospace;">facing</span> we will create <span style="font-family: "Courier New",Courier,monospace;">Facing.java</span> file. I like to keep them in the <span style="font-family: "Courier New",Courier,monospace;">models.enums</span> package like so:</div>
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #f92672;">package</span> <span style="color: #f8f8f2;">com</span><span style="color: #f92672;">.</span><span style="color: #a6e22e;">atsiitech</span><span style="color: #f92672;">.</span><span style="color: #a6e22e;">rpg</span><span style="color: #f92672;">.</span><span style="color: #a6e22e;">models</span><span style="color: #f92672;">.</span><span style="color: #a6e22e;">enums</span><span style="color: #f92672;">;</span>
<span style="color: #66d9ef;">public</span> <span style="color: #66d9ef;">enum</span> <span style="color: #f8f8f2;">Facing</span> <span style="color: #f92672;">{</span>
<span style="color: #f8f8f2;">UP</span><span style="color: #f92672;">,</span>
<span style="color: #f8f8f2;">DOWN</span><span style="color: #f92672;">,</span>
<span style="color: #f8f8f2;">LEFT</span><span style="color: #f92672;">,</span>
<span style="color: #f8f8f2;">RIGHT</span>
<span style="color: #f92672;">}</span>
</pre>
</div>
<br />
<br />
<div style="text-align: justify;">
Enums are a really convenient way to tell the state of objects, the game and modes so we'll have a lot of those.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
That's all for now. I will write more on the <span style="font-family: "Courier New",Courier,monospace;">Player</span> class later with rendering, animation, inventory, journal, etc. Thanks for reading. :)<br />
<br />
Edit: <a href="http://atsiitech.blogspot.com/2014/02/programming-role-playing-game-part-2.html" target="_blank">Part 2 - Journal and Quests </a></div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-5263394476951581519.post-65494160643431646212013-11-20T20:36:00.005+02:002013-11-23T17:16:31.846+02:00Creating pixel graphics (programmer art) - in four weeks<div style="text-align: justify;">
I haven't done much pixel graphics and wanted to have a go so I took part in an event called Pixelshit Wednesday, overseed by <a href="http://www.prisonscape.com/" target="_blank">Prisonscape</a>.</div>
<br />
<br />
<h3>
Week one</h3>
<br />
<div style="text-align: justify;">
The first challenge was to simply create a character with limitations to color and size. I didn't pay enough attention, I just started clicking pixels and this is what I got:</div>
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="http://i.imgur.com/1OZ44nG.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://i.imgur.com/1OZ44nG.png" style="cursor: move;" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Fatty Cyborg</td></tr>
</tbody></table>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I called it "Fatty Cyborg" because that's what I thought it looks like. Why I made those long hands? No idea. It could be good for a humorous fast paced platformer or the final boss in a cheesy RPG. Not so happy with this one but it's a start.</div>
<br />
<br />
<h3>
Week two</h3>
<br />
<div style="text-align: justify;">
The next challenge came with a Nightmare theme. It was around Halloween, after all.</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://i.imgur.com/mWF1zU5.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://i.imgur.com/mWF1zU5.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Sad Octopus is sad.</td></tr>
</tbody></table>
<br />
<div style="text-align: justify;">
I started to work on a ghost with a shouting face. Somehow the painting by <a href="http://en.wikipedia.org/wiki/The_Scream" target="_blank">Edvard Munch</a>
came to my mind. I couldn't make my ghost so nightmarish so it evolved
into this squid-like creature. Would probably look better if animated.</div>
<br />
<br />
<h3>
Week three </h3>
<br />
<div style="text-align: justify;">
The next challenge was a bit bigger, making a tileset. Restrictions: 16 colors, tile size: 16x16 to 32x32 pixels.</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://i.imgur.com/rqzy47b.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="http://i.imgur.com/rqzy47b.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The "Cellar"</td></tr>
</tbody></table>
<br />
<div style="text-align: justify;">
I have no idea what's in those barrels but it looks biohazardish. Making this actually inspired an area and a story in a game I'm making so it wasn't a total fail. But I suck at shading, gotta work on that.</div>
<br />
<br />
<h3>
Week four</h3>
<br />
<div style="text-align: justify;">
The fourth challenge was to draw a character that fits into the tileset environment. I wanted to make a mad scientist to go with those tubs of green goo. Started with the beard, the glasses and the rest of the head and worked down from there:</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUEKydyccmeQb7sYUECsZLmWzt9yGtCS6PZ7QxjJnfBEogtSlqc65VbllCMGTJIXvGo0qJIS3ePwBBNZg56OfE3WWvaUNGCXmrHQmhqyHNW5H2Ra4b_BO_cHniSyC8D8BFI1-zNWTdUoub/s1600/pixelshit4_tileset.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUEKydyccmeQb7sYUECsZLmWzt9yGtCS6PZ7QxjJnfBEogtSlqc65VbllCMGTJIXvGo0qJIS3ePwBBNZg56OfE3WWvaUNGCXmrHQmhqyHNW5H2Ra4b_BO_cHniSyC8D8BFI1-zNWTdUoub/s320/pixelshit4_tileset.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">"I'm a doctor and I want my sausages!"</td></tr>
</tbody></table>
<br />
<br />
<div style="text-align: center;">
Bonus:</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYOo0IrkPKgBygj7nAY7HPk1DVKDzlyFU_S_dbfnWIX7a2q1bi-roT-olU1ebfkiLy4DYn5e9wejtDPkZrUJ-qdoEngALds81EqqkXucl2Rn4Sgs_bbEAU9xP4Nvm946Ca6U-juyos-ivj/s1600/tub.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYOo0IrkPKgBygj7nAY7HPk1DVKDzlyFU_S_dbfnWIX7a2q1bi-roT-olU1ebfkiLy4DYn5e9wejtDPkZrUJ-qdoEngALds81EqqkXucl2Rn4Sgs_bbEAU9xP4Nvm946Ca6U-juyos-ivj/s1600/tub.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">"Ahhh..."</td></tr>
</tbody></table>
<br />
<br />
<div style="text-align: justify;">
I had a lot of fun participating in this event. It didn't turn me into an artist but it certainly improved my pixel skills, inspired new ideas and introduced me to some awesome developers. Thanks!<br />
<br />
Off to make next week's challenge... </div>
<br />
<br />
<h3>
Check the submissions here:</h3>
<br />
Week 1: <a href="http://www.prisonscape.com/?p=429" target="_blank">http://www.prisonscape.com/?p=429</a><br />
Week 2: <a href="http://www.prisonscape.com/?p=479" target="_blank">http://www.prisonscape.com/?p=479</a><br />
Week 3: <a href="http://www.prisonscape.com/?p=495" target="_blank">http://www.prisonscape.com/?p=495</a><br />
Week 4: <a href="http://www.prisonscape.com/?p=500">http://www.prisonscape.com/?p=500</a>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-5263394476951581519.post-75738876105224099162013-09-03T17:09:00.001+03:002013-09-07T01:51:12.494+03:00Adding 15-second timer to your game's splash screen (libgdx)<style type="text/css">
div.code {
background-color: OldLace;
padding: 10px;
border-radius: 3px;
box-shadow: 3px 3px 3px #333;
}
</style>Adding a timer to your game is quite simple.<br />
<br />
Here we call the <i>schedule() </i>method<i> </i>of the Timer object and pass it a new Task object and delay parameter (15 seconds in this case). The <i>run()</i> method will fire after the 15 seconds and inside it you define what to do. In this case we just call another method that handles the change to another screen.<br />
<br />
We also set touch event because usually the player doesn't want to hang on the splash screen: <br />
<br />
<div class="code">
<span style="color: #351c75;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #0b5394;">private boolean</span> timerIsOn = <span style="color: #0b5394;">false</span><i>;</i></span></span><br />
<br />
<span style="color: #351c75;"><span style="color: #3d85c6;"><span style="font-family: "Courier New",Courier,monospace;">@Override</span></span><span style="font-family: "Courier New",Courier,monospace;"> </span></span><br />
<span style="color: #351c75;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #0b5394;">public void</span> render() {</span></span><br />
<span style="color: #351c75;"><span style="font-family: "Courier New",Courier,monospace;"> Gdx.gl.glClearColor(0, 0, 0, 1);<br /> Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); </span></span><br />
<span style="color: #351c75;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><br />
<span style="color: #351c75;"><span style="font-family: "Courier New",Courier,monospace;"> <span style="color: #0b5394;">if</span>(!timerIsOn) {</span></span><br />
<span style="color: #351c75;"><span style="font-family: "Courier New",Courier,monospace;"> timerIsOn = <span style="color: #0b5394;">true</span>;</span></span><br />
<span style="color: #351c75;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><br />
<span style="color: #351c75;"><span style="font-family: "Courier New",Courier,monospace;"> Timer.schedule(<span style="color: #0b5394;">new</span> Task() {</span></span><br />
<span style="color: #351c75;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><br />
<span style="color: #351c75;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #3d85c6;"> @Override</span></span></span><br />
<span style="color: #351c75;"><span style="font-family: "Courier New",Courier,monospace;"> <span style="color: #0b5394;">public void</span> run() {</span></span><br />
<span style="color: #351c75;"><span style="font-family: "Courier New",Courier,monospace;"> changeScreen();</span></span><br />
<span style="color: #351c75;"><span style="font-family: "Courier New",Courier,monospace;"> }</span></span><br />
<br />
<span style="color: #351c75;"><span style="font-family: "Courier New",Courier,monospace;"> }, 15);</span></span><br />
<span style="color: #351c75;"><span style="font-family: "Courier New",Courier,monospace;"> </span><span style="font-family: "Courier New",Courier,monospace;"> </span></span><br />
<span style="color: #351c75;"><span style="font-family: "Courier New",Courier,monospace;"> } <span style="color: #0b5394;">else if</span>(Gdx.input.isTouched()) {</span></span><br />
<span style="color: #351c75;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #351c75;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #351c75;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #38761d;">// Remove the task so we don't call changeScreen twice:</span></span></span> </span></span><br />
<span style="color: #351c75;"><span style="font-family: "Courier New",Courier,monospace;"> Timer.instance().clear();<span style="color: #38761d;"> </span></span></span><br />
<span style="color: #351c75;"><span style="font-family: "Courier New",Courier,monospace;"> changeScreen();</span></span><br />
<span style="color: #351c75;"><span style="font-family: "Courier New",Courier,monospace;"> }</span></span><br />
<span style="color: #351c75;"><span style="font-family: "Courier New",Courier,monospace;">}</span></span></div>
<br />
<br />
Check also the <a href="http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/utils/Timer.html" target="_blank">Timer class javadoc</a> for more information and methods.<br />
<br />
<br />Unknownnoreply@blogger.com0