{"id":1822,"date":"2013-08-18T12:09:06","date_gmt":"2013-08-18T12:09:06","guid":{"rendered":"http:\/\/www.s2powered.com\/?p=1822"},"modified":"2019-05-31T18:47:13","modified_gmt":"2019-05-31T18:47:13","slug":"third-person-control","status":"publish","type":"post","link":"https:\/\/www.s2powered.com\/copiasito\/1822\/third-person-control\/tutorials\/oldtut\/08\/2013\/","title":{"rendered":"Third Person Control"},"content":{"rendered":"<p>Hi guys,<br \/>\nIn this tutorial I&#8217;ll explain the basis for implementing a <strong>Third Person Camera<\/strong> control system.<br \/>\n<!--more--><\/p>\n<p>At the end of this tutorial you will be able to create a new camera object from scratch and write a script that control camera movements around the player character and a script that make player character walking, runing and correctly facing camera just like in games such as Batman, Hitman or SplinterCell.<\/p>\n<p>First we have to create a new scene in which make our experiments. We will create it inside the project provided with the engine installation package.<\/p>\n<p>So open the <strong>SampleProject03<\/strong> project without loading any scene. Click on New icon to create a completely new scene inside the project. We will call it simply myScene.<\/p>\n<p>Now Click on newTerrain icon to create a new terrain in the created scene, give it a name and click on create.<\/p>\n<p>Now we will use the enemy marine character of the FPS demo for our experiments. In the project objects browser goto the characters folder and drag the marine into the scene.<\/p>\n<p><em>NOTE that due to a know terrain BUG when inserting the character into the scene the terrain will disappear: save the scene, close the editor and reload all.<\/em><\/p>\n<p>Now we create a new camera object. Click on create button into class tab, it will remain pressed until you click on it again. When the create button is pressed This mean that editor is in &#8220;<strong><em>Create mode<\/em><\/strong>&#8220;.<\/p>\n<p><a href=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp01.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1901 alignnone\" alt=\"tp01\" src=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp01.jpg\" width=\"404\" height=\"526\" srcset=\"https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp01.jpg 674w, https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp01-600x779.jpg 600w, https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp01-230x300.jpg 230w\" sizes=\"auto, (max-width: 404px) 100vw, 404px\" \/><\/a><\/p>\n<p>Click on the camera class in the class list of the BasePack.dll plugin, the camera class parameters will appear,<\/p>\n<p><a href=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp02.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-1902 alignnone\" alt=\"tp02\" src=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp02.jpg\" width=\"343\" height=\"389\" srcset=\"https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp02.jpg 572w, https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp02-264x300.jpg 264w\" sizes=\"auto, (max-width: 343px) 100vw, 343px\" \/><\/a><\/p>\n<p>click on activable parameter value in order to make parameter value<strong> true.<\/strong><\/p>\n<p><a href=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp03.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-1903 alignnone\" alt=\"tp03\" src=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp03.jpg\" width=\"278\" height=\"178\" srcset=\"https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp03.jpg 347w, https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp03-300x192.jpg 300w\" sizes=\"auto, (max-width: 278px) 100vw, 278px\" \/><\/a><\/p>\n<p>Now click on the terrain inside the scene viewport, you will see the camera icon appearing. \u00a0Click on Create again to exit from &#8220;<strong><em>Create Mode<\/em><\/strong>&#8220;.<\/p>\n<p><a href=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp04.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-1904 alignnone\" alt=\"tp04\" src=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp04.jpg\" width=\"512\" height=\"270\" srcset=\"https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp04.jpg 1218w, https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp04-600x317.jpg 600w, https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp04-300x158.jpg 300w, https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp04-1024x541.jpg 1024w\" sizes=\"auto, (max-width: 512px) 100vw, 512px\" \/><\/a><\/p>\n<p><strong><em>NOTE: If you haven&#8217;t associated a Text editor for scripting open Preferences anc click on the Script editor combobox to choose the executable file the engine must use as script editor. I use NotePad++.<\/em><\/strong><\/p>\n<p><a href=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp10.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1910 alignnone\" alt=\"tp10\" src=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp10.jpg\" width=\"209\" height=\"301\" srcset=\"https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp10.jpg 349w, https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp10-208x300.jpg 208w\" sizes=\"auto, (max-width: 209px) 100vw, 209px\" \/><\/a><a href=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp11.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1897 alignright\" alt=\"tp11\" src=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp11.jpg\" width=\"236\" height=\"253\" srcset=\"https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp11.jpg 394w, https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp11-280x300.jpg 280w\" sizes=\"auto, (max-width: 236px) 100vw, 236px\" \/><\/a><\/p>\n<p>Now we will create a new script file.Select the script browser inside the project browser and choose the <strong>characters<\/strong> folder.<\/p>\n<p><a href=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp05.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-1905 alignnone\" alt=\"tp05\" src=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp05.jpg\" width=\"227\" height=\"373\" srcset=\"https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp05.jpg 379w, https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp05-182x300.jpg 182w\" sizes=\"auto, (max-width: 227px) 100vw, 227px\" \/><\/a><\/p>\n<p>Press Right mouse button on an empty space inside the browser and click on new in the popup menu that will appear.<\/p>\n<p><a href=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp06.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-1906 alignnone\" alt=\"tp06\" src=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp06.jpg\" width=\"265\" height=\"244\" srcset=\"https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp06.jpg 441w, https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp06-300x276.jpg 300w\" sizes=\"auto, (max-width: 265px) 100vw, 265px\" \/><\/a><\/p>\n<p>Name the new script as <strong><em>TPCamera<\/em><\/strong> and press ok: a new script file will be created.<\/p>\n<p><a href=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp07.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1907 alignnone\" alt=\"tp07\" src=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp07.jpg\" width=\"307\" height=\"153\" srcset=\"https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp07.jpg 307w, https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp07-300x149.jpg 300w\" sizes=\"auto, (max-width: 307px) 100vw, 307px\" \/><\/a><\/p>\n<p>Now we have to associate that script to the camera. Select the camera and click on <strong>class<\/strong> tab. Click on the Script parameter and choose the<em><strong> TPCamera.sc2<\/strong><\/em> script.<\/p>\n<p><a href=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp12.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-1898 alignnone\" alt=\"tp12\" src=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp12.jpg\" width=\"200\" height=\"290\" srcset=\"https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp12.jpg 333w, https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp12-206x300.jpg 206w\" sizes=\"auto, (max-width: 200px) 100vw, 200px\" \/><\/a><\/p>\n<p>Now return to the Script browser and again press right mouse button on the script icon and click on <strong>Inspect<\/strong>, the script inspector will appear with the new script start code inside.<\/p>\n<p><a href=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp08.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-1908 alignnone\" alt=\"tp08\" src=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp08.jpg\" width=\"180\" height=\"212\" srcset=\"https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp08.jpg 300w, https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp08-254x300.jpg 254w\" sizes=\"auto, (max-width: 180px) 100vw, 180px\" \/><\/a><\/p>\n<p>Click on <strong>edit&#8230;<\/strong> to edit the script: at this point if you have configured well the script editor path, the editor window will appear with script loaded.<\/p>\n<p><a href=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp09.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1909 alignnone\" alt=\"tp09\" src=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp09.jpg\" width=\"229\" height=\"212\" srcset=\"https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp09.jpg 382w, https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp09-300x278.jpg 300w\" sizes=\"auto, (max-width: 229px) 100vw, 229px\" \/><\/a><\/p>\n<p>Lets start with scripting!<\/p>\n<p>first we want camera rotate around Y axis when moving the mouse from left to right and viceversa, in the <strong><em>Update()<\/em><\/strong> entry function we write:<\/p>\n<p><code>\/* first rotate camera around (0,1,0) axis basing on MOUSEX value *\/<br \/>\nRotate(vec3(0.0,1.0,0.0),\"MOUSEX\",0.1);<\/code><\/p>\n<p>(see <a href=\"http:\/\/www.s2powered.com\/MEDIAWIKI\/mediawiki-1.16.0\/index.php?title=Rotate\">WIKI<\/a> for more info about this function)<\/p>\n<p><strong>MOUSEX<\/strong> is a string that will be parsed by the scripting engine and means &#8220;get Mouse movement on X axis&#8221;.<\/p>\n<p>Now we want camera rotating around Its right axis basing on the Up-Down mouse movement:<\/p>\n<p><code>\/* then rotate camera around its right axis basing on MOUSEY value *\/<br \/>\nRotate(\"rgt\",\"MOUSEY\",0.1);<\/code><\/p>\n<p><strong>Rgt\u00a0<\/strong>is a string that is parsed by scripting engine and it means &#8220;get this object right axis&#8221;<\/p>\n<p>Now that we have camera rotating basing on the mouse movements we can place it at a certain distance from the target character.<\/p>\n<p>Since we want our script can be used indipendently from the target character we can add a parameter to the script that contains the name of the target character. At the beginning of the script code write:<\/p>\n<p><code>#param string target<\/code><\/p>\n<p>This will tell the script engine that the script has a parameter called <strong><em>target<\/em><\/strong>. If you click on the script params object parameter (class tab) you will see a dialog containing the list of the script parameters<\/p>\n<p>Now we can place the camera respect the target character by first placing it at character coords and then traslate it away from character along its forward axis. Again in the <strong><em>Update()<\/em><\/strong> entry function:<\/p>\n<p><code>\/* Now Set camera position from target object position *\/<br \/>\nSetPositionFromObject(target);<\/code><\/p>\n<p><code>\/* place camera 150 points far from target *\/<br \/>\nTraslate2(\"fwd\",-150.0);<\/code><br \/>\n(see <a href=\"http:\/\/www.s2powered.com\/MEDIAWIKI\/mediawiki-1.16.0\/index.php?title=SetPositionFromObject\">SetPositionFromObject()<\/a> spec on the WIKI, see <a href=\"http:\/\/www.s2powered.com\/MEDIAWIKI\/mediawiki-1.16.0\/index.php?title=Traslate2http:\/\/\">Traslate2()<\/a> spec on the WIKI)<\/p>\n<p>Now we set the target parameter with the name of the marine character. Click on <strong>scriptParams<\/strong> camera object parameter.<\/p>\n<p><a href=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp13.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-1899 alignnone\" alt=\"tp13\" src=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp13.jpg\" width=\"200\" height=\"262\" srcset=\"https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp13.jpg 333w, https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/tp13-228x300.jpg 228w\" sizes=\"auto, (max-width: 200px) 100vw, 200px\" \/><\/a><\/p>\n<p>Now set the target parameter as <em><strong>marine010<\/strong><\/em> (the name of the marine character in the scene).<\/p>\n<p><a href=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp15.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-1900 alignnone\" alt=\"tp15\" src=\"http:\/\/www.s2powered.com\/wp-content\/uploads\/2013\/08\/tp15.jpg\" width=\"208\" height=\"227\" \/><\/a><\/p>\n<p>Now if you click on Play you will see the camera pointing the center of the character and, moving the mouse, the camera will move around it.<\/p>\n<p>Now we can adjust the camera position basing on our needs. In this case we place the camera on the top-right corner respect to the player character (just like seen in Batman: Arkham Asylum):<\/p>\n<p><code>\/* Traslate camera 80 units on its right *\/<br \/>\nTraslate2(\"rgt\",80.0);<\/code><\/p>\n<p><code>\/* traslate camera 50 units on Y axis*\/<br \/>\nTraslate(0.0,50.0,0.0);<\/code><\/p>\n<p>(see <a href=\"http:\/\/www.s2powered.com\/MEDIAWIKI\/mediawiki-1.16.0\/index.php?title=Traslate\">Traslate()<\/a> spec on the WIKI)<\/p>\n<p>Now we put it all together. The complete script will look like this:<br \/>\n<code><br \/>\n#param string target<\/code><\/p>\n<p><code>function void Init()<br \/>\n{<br \/>\n}<\/code><br \/>\n<code><br \/>\nfunction void Update()<br \/>\n{<\/code><br \/>\n<code>\/* first rotate camera around (0,1,0) axis basing on MOUSEX value *\/<br \/>\nRotate(vec3(0.0,1.0,0.0),\"MOUSEX\",0.1);<\/code><br \/>\n<code><br \/>\n\/* then rotate camera around its right axis basing on MOUSEY value *\/<br \/>\nRotate(\"rgt\",\"MOUSEY\",0.1);<\/code><br \/>\n<code><br \/>\n\/* Now Set camera position from target object position *\/<br \/>\nSetPositionFromObject(target);<br \/>\n<\/code><code><br \/>\n\/* place camera 150 points far from target *\/<br \/>\nTraslate2(\"fwd\",-150.0);<br \/>\n<\/code><code><br \/>\n\/* and then adjust its position as needed *\/<br \/>\nTraslate2(\"rgt\",80.0);<br \/>\nTraslate(0.0,50.0,0.0);<\/code><br \/>\n<code>}<\/code><br \/>\n<code><br \/>\nfunction void Message()<br \/>\n{<br \/>\n}<\/code><\/p>\n<p>A last touch to our code: Lets make camera do not penetrating obstacles. In this case we use a function called <a href=\"http:\/\/www.s2powered.com\/MEDIAWIKI\/mediawiki-1.16.0\/index.php?title=ClipCamera\">ClipCamera()<\/a>.<\/p>\n<p>The final code will be just like this:<\/p>\n<p><code>#param string target<\/code><\/p>\n<p><code>function void Init()<br \/>\n{<br \/>\n}<\/code><br \/>\n<code><br \/>\nfunction void Update()<br \/>\n{<\/code><br \/>\n<code>\/* first rotate camera around (0,1,0) axis basing on MOUSEX value *\/<br \/>\nRotate(vec3(0.0,1.0,0.0),\"MOUSEX\",0.1);<\/code><br \/>\n<code><br \/>\n\/* then rotate camera around its right axis basing on MOUSEY value *\/<br \/>\nRotate(\"rgt\",\"MOUSEY\",0.1);<\/code><br \/>\n<code><br \/>\n\/* Now Set camera position from target object position *\/<br \/>\nSetPositionFromObject(target);<br \/>\n<\/code><code><br \/>\n\/* place camera 150 points far from target *\/<br \/>\nTraslate2(\"fwd\",-150.0);<br \/>\n<\/code><code><br \/>\n\/* and then adjust its position as needed *\/<br \/>\nTraslate2(\"rgt\",80.0);<br \/>\nTraslate(0.0,50.0,0.0);<\/code><br \/>\n<code><br \/>\n\/* clip camera movements against obstacles *\/<br \/>\nClipCamera(target, 50.0, 50.0);<br \/>\n}<\/code><br \/>\n<code><br \/>\nfunction void Message()<br \/>\n{<br \/>\n}<\/code><\/p>\n<p>Lets start with character now.<\/p>\n<p>First we have to create a new script. We do it in the same folder as Camera script. We name it <strong>TPPlayer.<br \/>\n<\/strong>As made with Camera we now assign the new script to the marine character and repeating the same procedure done with <strong>TPCamera<\/strong> script we inspect the <strong>TPPlayer<\/strong> script and edit it.<\/p>\n<p>What we have mainly to do with player character is making it to always be controlled respect to the camera orientation. In other words if, for example, player character is facing the camera and you press &#8220;forward&#8221; button the character turns itself in the direction of the camera &#8220;forward&#8221; and moves, the same thing with right, left and backward directions.<\/p>\n<p>To do this we will use a powerful script function called <em><strong>setDirection<\/strong>\u00a0<\/em>(see <a href=\"http:\/\/www.s2powered.com\/MEDIAWIKI\/mediawiki-1.16.0\/index.php?title=SetDirection\">setDirection()<\/a> on the WIKI).<\/p>\n<p>This function lets you to set the facing direction of an object in many ways. One way to do this is set the direction of the object basing on the current active camera direction, this is what we need to make our character control system.<\/p>\n<p>Lets see the code:<br \/>\n<code><br \/>\nfunction void Update()<br \/>\n{<\/code><code><br \/>\n\/* set direction forward respect the current camera*\/<br \/>\nif( IsKeyPressed(\"w\",0) )<br \/>\n{<br \/>\nSetDirection(\"camfwd\",1.0,0.25);<br \/>\n}<\/code><code><br \/>\n\/* set direction backward respect the current camera*\/<br \/>\nif( IsKeyPressed(\"s\",0) )<br \/>\n{<br \/>\nSetDirection(\"camfwd\",-1.0,0.25);<br \/>\n}<br \/>\n<\/code><code><br \/>\n\/* set direction right respect the current camera*\/<br \/>\nif( IsKeyPressed(\"d\",0) )<br \/>\n{<br \/>\nSetDirection(\"camrgt\",1.0,0.25);<br \/>\n}<br \/>\n<\/code><code><br \/>\n\/* set direction left respect the current camera*\/<br \/>\nif( IsKeyPressed(\"a\",0) )<br \/>\n{<br \/>\nSetDirection(\"camrgt\",-1.0,0.25);<br \/>\n}<br \/>\n<\/code><code><br \/>\n}<\/code><\/p>\n<p>Press play to see this script in action: rotate the camera around the character and then press &#8220;w&#8221;, you will see marine turn in the same direction of the camera.(see <a href=\"http:\/\/www.s2powered.com\/MEDIAWIKI\/mediawiki-1.16.0\/index.php?title=IsKeyPressed\">IsKeyPressed()<\/a> function on the WIKI)<\/p>\n<p>Now we have to animate and move it in order to make it walking and running.<\/p>\n<p>We will use the animation functions of the s2script foundation library. See <a href=\"http:\/\/www.s2powered.com\/MEDIAWIKI\/mediawiki-1.16.0\/index.php?title=Script:Animations\">Animation <\/a>chapter and <a href=\"http:\/\/www.s2powered.com\/MEDIAWIKI\/mediawiki-1.16.0\/index.php?title=Script_Reference_Manual\">Animation Functions<\/a> on the WIKI.<\/p>\n<p>First, in the <strong>update()<\/strong> function, we define a boolean variable that store if the character is in idle or walking state:<br \/>\n<code><br \/>\nvar bool walk;<br \/>\nwalk=false; \/* if nothing happens character is in idle state *\/<br \/>\n<\/code><\/p>\n<p>Now we modify the previous code in order to set the walk state if a key is pressed:<\/p>\n<p><code>function void Update()<br \/>\n{<\/code><br \/>\n<code>var bool walk;<br \/>\nwalk=false;<\/code><br \/>\n<code><br \/>\n\/* set direction forward respect the current camera*\/<br \/>\nif( IsKeyPressed(\"w\",0) )<br \/>\n{<br \/>\nSetDirection(\"camfwd\",1.0,0.25);<br \/>\nwalk=true;<br \/>\n}<\/code><code><br \/>\n\/* set direction backward respect the current camera*\/<br \/>\nif( IsKeyPressed(\"s\",0) )<br \/>\n{<br \/>\nSetDirection(\"camfwd\",-1.0,0.25);<br \/>\nwalk=true;<br \/>\n}<br \/>\n<\/code><code><br \/>\n\/* set direction right respect the current camera*\/<br \/>\nif( IsKeyPressed(\"d\",0) )<br \/>\n{<br \/>\nSetDirection(\"camrgt\",1.0,0.25);<br \/>\nwalk=true;<br \/>\n}<br \/>\n<\/code><code><br \/>\n\/* set direction left respect the current camera*\/<br \/>\nif( IsKeyPressed(\"a\",0) )<br \/>\n{<br \/>\nSetDirection(\"camrgt\",-1.0,0.25);<br \/>\nwalk=true;<br \/>\n}<br \/>\n<\/code><code><br \/>\n}<\/code><\/p>\n<p>Now we tell the engine to play a looping animation on the channel 0, if walk state is set we make &#8220;walk&#8221; animation blend weight be 1.0 and &#8220;standby&#8221; animation weight be 0.0, otherwise we make viceversa. Also, if walk state is set we move, using physics, the character in its <strong>forward<\/strong> direction :<code><\/code><\/p>\n<p><code>\/* play loop animation on channel 0 *\/<br \/>\nPlayAnimation(0,true);<\/code><br \/>\n<code><br \/>\n\/* get character direction *\/<br \/>\nif(walk==true)<br \/>\n{<br \/>\nBlendCurrentAnimation(\"walk\",1.0,0);<br \/>\nBlendCurrentAnimation(\"standby\",0.0,0);<br \/>\nvar vec3 dir;<br \/>\ndir = GetAxis(\"fwd\");<br \/>\nphysicsCharacterMove(dir,150.0);<br \/>\n}<br \/>\nelse<br \/>\n{<br \/>\nBlendCurrentAnimation(\"standby\",1.0,0);<br \/>\nBlendCurrentAnimation(\"walk\",0.0,0);<br \/>\n}<\/code><\/p>\n<p>(see <a href=\"http:\/\/www.s2powered.com\/MEDIAWIKI\/mediawiki-1.16.0\/index.php?title=PlayAnimation\">PlayAnimation()<\/a> , <a href=\"http:\/\/www.s2powered.com\/MEDIAWIKI\/mediawiki-1.16.0\/index.php?title=BlendCurrentAnimation\">BlendCurrentAnimation()<\/a>, <a href=\"http:\/\/www.s2powered.com\/MEDIAWIKI\/mediawiki-1.16.0\/index.php?title=PhysicsCharacterMove\">physicsCharacterMove()<\/a> and <a href=\"http:\/\/www.s2powered.com\/MEDIAWIKI\/mediawiki-1.16.0\/index.php?title=GetAxis\">GetAxis()<\/a> functions spec)<\/p>\n<p>Using the above code we will see that when we press &#8220;w&#8221; the character turn and move along &#8220;camera forward&#8221; direction. We can note that the character animation go from <strong>standby<\/strong> to <strong>walk <\/strong>instantly, without any type of blend. We don&#8217;t want this so we can replace the BlendCurrentAnimation function calls with one call to <strong>AnimationcrossFade()<\/strong> function.<\/p>\n<p>This function smoothly assigns maximum weigth (1.0) to a specified animation and minimum weight (0.0) to all the others of the same specified channel, you can specify how much time must be spent for the transition.<\/p>\n<p>So the previous code become:<\/p>\n<p><code>\/* play loop animation on channel 0 *\/<br \/>\nPlayAnimation(0,true);<\/code><br \/>\n<code><br \/>\n\/* get character direction *\/<br \/>\nif(walk==true)<br \/>\n{<br \/>\nAnimationcrossFade(\"walk\",0,100.0);<br \/>\nvar vec3 dir;<br \/>\ndir = GetAxis(\"fwd\");<br \/>\nphysicsCharacterMove(dir,150.0);<br \/>\n}<br \/>\nelse<br \/>\n{<br \/>\nAnimationcrossFade(\"standby\",0,100.0);<br \/>\n}<\/code><\/p>\n<p>Now we can use another boolean varaible to specify if the character is in <strong>running<\/strong> or <strong>walking<\/strong> state and we can make character go to <strong>running<\/strong> state if <strong><em>shift<\/em> <\/strong>key is pressed. We also cross fade <em>run animation<\/em> and accellerate movement if in <strong>running<\/strong> state.<\/p>\n<p>Putting it all together the code will look like this:<\/p>\n<p><code><br \/>\nfunction void Update()<br \/>\n{<br \/>\nvar bool walk;<br \/>\nvar bool run;<br \/>\nwalk=false;<br \/>\nrun=false;<br \/>\n<\/code><code><br \/>\nif(IsKeyPressed(\"@lshift\",0))<br \/>\n{<br \/>\nrun=true;<br \/>\n}<br \/>\n<\/code><code><br \/>\n\/* set direction forward respect the current camera*\/<br \/>\nif( IsKeyPressed(\"w\",0) )<br \/>\n{<br \/>\nSetDirection(\"camfwd\",1.0,0.25);<br \/>\nwalk=true;<br \/>\n}<br \/>\n<\/code><code><br \/>\n\/* set direction backward respect the current camera*\/<br \/>\nif( IsKeyPressed(\"s\",0) )<br \/>\n{<br \/>\nSetDirection(\"camfwd\",-1.0,0.25);<br \/>\nwalk=true;<br \/>\n}<br \/>\n<\/code><code><br \/>\n\/* set direction right respect the current camera*\/<br \/>\nif( IsKeyPressed(\"d\",0) )<br \/>\n{<br \/>\nSetDirection(\"camrgt\",1.0,0.25);<br \/>\nwalk=true;<br \/>\n}<br \/>\n<\/code><code><br \/>\n\/* set direction left respect the current camera*\/<br \/>\nif( IsKeyPressed(\"a\",0) )<br \/>\n{<br \/>\nSetDirection(\"camrgt\",-1.0,0.25);<br \/>\nwalk=true;<br \/>\n}<br \/>\n<\/code><code><br \/>\n\/* play loop animation on channel 0 *\/<br \/>\nPlayAnimation(0,true);<br \/>\n<\/code><code><br \/>\n\/* get character direction *\/<br \/>\nif(walk==true)<br \/>\n{<br \/>\nvar vec3 dir;<br \/>\ndir = GetAxis(\"fwd\");<br \/>\nif(run)<br \/>\n{<br \/>\nAnimationcrossFade(\"run\",0,100.0);<br \/>\nphysicsCharacterMove(dir,300.0);<br \/>\n}<br \/>\nelse<br \/>\n{<br \/>\nAnimationcrossFade(\"walk\",0,100.0);<br \/>\nphysicsCharacterMove(dir,150.0);<br \/>\n}<br \/>\n}<br \/>\nelse<br \/>\n{<br \/>\nAnimationcrossFade(\"standby\",0,100.0);<br \/>\n}<br \/>\n}<br \/>\n<\/code><\/p>\n<p>&nbsp;<\/p>\n<p>This tutorial is provided with Script source code and a sample scene to copy inside the <strong>sampleProject03<\/strong> project.\u00a0Download the archive and extract its files inside the <strong>sampleproject03<\/strong> project folder.<\/p>\n<p><a href=\"http:\/\/www.s2powered.com\/downloads\/TPTutorial.rar\">DOWNLOAD SCRIPT SOURCES AND ASSETS<\/a><\/p>\n<p><a href=\"http:\/\/www.s2powered.com\/downloads\/TP.pdf\">DOWNLOAD PDF VERSION<\/a><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hi guys, In this tutorial I&#8217;ll explain the basis for implementing a Third Person Camera control system.<\/p>\n","protected":false},"author":1,"featured_media":1956,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[262],"tags":[],"class_list":["post-1822","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldtut"],"jetpack_featured_media_url":"https:\/\/www.s2powered.com\/copiasito\/wp-content\/uploads\/2013\/08\/TPCoverSmall.jpg","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.s2powered.com\/copiasito\/wp-json\/wp\/v2\/posts\/1822","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.s2powered.com\/copiasito\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.s2powered.com\/copiasito\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.s2powered.com\/copiasito\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.s2powered.com\/copiasito\/wp-json\/wp\/v2\/comments?post=1822"}],"version-history":[{"count":105,"href":"https:\/\/www.s2powered.com\/copiasito\/wp-json\/wp\/v2\/posts\/1822\/revisions"}],"predecessor-version":[{"id":2243,"href":"https:\/\/www.s2powered.com\/copiasito\/wp-json\/wp\/v2\/posts\/1822\/revisions\/2243"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.s2powered.com\/copiasito\/wp-json\/wp\/v2\/media\/1956"}],"wp:attachment":[{"href":"https:\/\/www.s2powered.com\/copiasito\/wp-json\/wp\/v2\/media?parent=1822"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.s2powered.com\/copiasito\/wp-json\/wp\/v2\/categories?post=1822"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.s2powered.com\/copiasito\/wp-json\/wp\/v2\/tags?post=1822"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}