<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: ThatRacingGame Dev</title>
    <description>The latest articles on DEV Community by ThatRacingGame Dev (@thatracinggame).</description>
    <link>https://dev.to/thatracinggame</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F996916%2F93e62ca8-1b8f-48a6-9133-bbd88603bddf.jpg</url>
      <title>DEV Community: ThatRacingGame Dev</title>
      <link>https://dev.to/thatracinggame</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thatracinggame"/>
    <language>en</language>
    <item>
      <title>Learning wheel colliders</title>
      <dc:creator>ThatRacingGame Dev</dc:creator>
      <pubDate>Tue, 27 Dec 2022 21:29:27 +0000</pubDate>
      <link>https://dev.to/thatracinggame/learning-wheel-colliders-3pbb</link>
      <guid>https://dev.to/thatracinggame/learning-wheel-colliders-3pbb</guid>
      <description>&lt;p&gt;Learning to develop a wheel collider in Unity seems rather intimidating at first.  There is an awful lot of physics at play translated into a 3D digital space, and when thinking about the broad range of driving games out there with all the different handling characteristics, it seems that one could spend decades tweaking and perfecting the perfect driving model.&lt;/p&gt;

&lt;p&gt;So in aim of speeding up the development process, in this blog post, I'll go over the basics of using the out of the box tools within Unity for creating a wheel collider, and share my thoughts and feedback on my experience.&lt;/p&gt;

&lt;p&gt;I'm working in a new 3D project in Unity. I already have setup a large plane object to act as the ground for the car to drive on. In your project, you'll want to create a new empty game object and name it "car_root" or something to that effect. This will be the parent object for all of your vehicle's components, including the wheel geometry, colliders etc.&lt;/p&gt;

&lt;p&gt;Next we can create the body of the car as a child of "car_root".  I'm using the ol' aerodynamic brick model of a cube, scaled out to the rough size of a car (3.9m x 1.75m x 1.23m).&lt;/p&gt;

&lt;p&gt;Next, we can create a new empty game object called "wheels" as a child of "car_root".  This will act as our reference container for our wheel assets. You'll want to create four more empty game objects and name them "fronLeft," "frontRight", "rearLeft", and "rearRight". These will be the objects that the wheel colliders will be attached to.  Make sure to adjust the transform position of each wheel to suit the desired geometry of the car. One important thing to note is that the wheel colliders should be positioned so that they are centered on the wheels. If the colliders are not properly aligned, your vehicle may behave strangely or even become uncontrollable.&lt;/p&gt;

&lt;p&gt;Then, to create the wheel colliders themselves, you'll need to add a "Wheel Collider" component to each of the four wheel objects. You can do this by right-clicking on the object and selecting "Add Component" from the context menu.&lt;/p&gt;

&lt;p&gt;Once you've added the wheel collider component to all four wheels, you'll need to adjust the settings to match your vehicle's specifications. This includes things like the radius and width of the wheels, the suspension spring strength, and the mass of the wheels.  For now, I'm sticking with the pure out of the box values.&lt;/p&gt;

&lt;p&gt;At the moment, this just gives us a simple model of a car with a body, and some invisible wheels.  So lets add some wheel geometry in so we can see the actual wheels.  As a child of each wheel collider game object, create a cylinder game object, and adjust the geometry to be a 'wheel like' shape.&lt;/p&gt;

&lt;p&gt;The end result of what I'm working with looks something like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gX4Xazf9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dip2zg14fl7222quc1cw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gX4Xazf9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dip2zg14fl7222quc1cw.png" alt="Image description" width="880" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To control the vehicle, you'll need to add some simple scripts to your vehicle game object. These scripts will handle things like acceleration, braking, steering, and suspension damping. For now, I've just taken the out of the box sample script from one of Unitys tutorials, and made a slight tweak within the &lt;code&gt;ApplyLocalPositionToVisuals&lt;/code&gt; method, to force the wheel geomtery to align correctly over the Y axis.  Depending on how you setup your car and wheel geometry, this may or may not be relevant.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;UnityEngine&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Collections&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Collections.Generic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CarController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;MonoBehaviour&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AxleInfo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;axleInfos&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// the information about each individual axle&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;maxMotorTorque&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// maximum torque the motor can apply to wheel&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;maxSteeringAngle&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// maximum steer angle the wheel can have&lt;/span&gt;

    &lt;span class="c1"&gt;// finds the corresponding visual wheel&lt;/span&gt;
    &lt;span class="c1"&gt;// correctly applies the transform&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ApplyLocalPositionToVisuals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WheelCollider&lt;/span&gt; &lt;span class="n"&gt;collider&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;collider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;childCount&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;Transform&lt;/span&gt; &lt;span class="n"&gt;visualWheel&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;collider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;Vector3&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;Quaternion&lt;/span&gt; &lt;span class="n"&gt;rotation&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;collider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetWorldPose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;rotation&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;rotation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rotation&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;Quaternion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Euler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Vector3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;90&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

        &lt;span class="n"&gt;visualWheel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;visualWheel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rotation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rotation&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;FixedUpdate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;motor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;maxMotorTorque&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAxis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Vertical"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;steering&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;maxSteeringAngle&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAxis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Horizontal"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AxleInfo&lt;/span&gt; &lt;span class="n"&gt;axleInfo&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;axleInfos&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;axleInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;steering&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;axleInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leftWheel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;steerAngle&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;steering&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="n"&gt;axleInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rightWheel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;steerAngle&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;steering&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;axleInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;motor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;axleInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leftWheel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;motorTorque&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;motor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="n"&gt;axleInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rightWheel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;motorTorque&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;motor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="nf"&gt;ApplyLocalPositionToVisuals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;axleInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leftWheel&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nf"&gt;ApplyLocalPositionToVisuals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;axleInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rightWheel&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Serializable&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AxleInfo&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;WheelCollider&lt;/span&gt; &lt;span class="n"&gt;leftWheel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;WheelCollider&lt;/span&gt; &lt;span class="n"&gt;rightWheel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;motor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// is this wheel attached to motor?&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;steering&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// does this wheel apply steer angle?&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add this script onto the main "car_root" gameobject, and viola.  You can hit play, and test out the car model.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oLiaAhpz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xe7ydmdz8gqo2oiu5k2s.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oLiaAhpz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xe7ydmdz8gqo2oiu5k2s.gif" alt="Image description" width="640" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using Unity to develop a wheel collider with the out of the box tools certainly is a very fast and straight forward process.  A lot of the initial perceived complexity is completely removed with the wheel collider game object, and some simple tunable parameters. However, as anticipated, getting the right balance of mass, center of gravity, friction etc will all take some time and experimentation to get a result with a good driving dynamic feeling to suit the style of game your building.&lt;/p&gt;

&lt;p&gt;In my next iteration of learning, I'll continue expanding on tuning and experimenting with these settings and parameters and exploring other possible configurations to yield effects like braking forces, limited slip diffs, front-wheel vs rear-wheel drive and more.&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>unity3d</category>
    </item>
    <item>
      <title>Starting ThatRacingGame</title>
      <dc:creator>ThatRacingGame Dev</dc:creator>
      <pubDate>Tue, 27 Dec 2022 05:04:32 +0000</pubDate>
      <link>https://dev.to/thatracinggame/starting-thatracinggame-59pc</link>
      <guid>https://dev.to/thatracinggame/starting-thatracinggame-59pc</guid>
      <description>&lt;p&gt;Hello fellow game developers and sim racing fans!&lt;/p&gt;

&lt;p&gt;I'm excited to announce the kick off of development on a new sim racing game titled 'That Racing Game'. It's been a long-time dream of mine to create somewhat of a realistic and immersive racing experience for players that's mixes elements of an MMO with full blown racing sim.&lt;/p&gt;

&lt;p&gt;Now, let me preface this with a couple of warnings.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I have never made a MMO game before&lt;/li&gt;
&lt;li&gt;I have never made a sim racing game before&lt;/li&gt;
&lt;li&gt;Well... I have never actually developed a game before&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I'm a software developer and systems architect by trade, and a racing enthusiast by nature.  So please, don't expect anything spectacular to be released from me any time soon (or possibly at all!).  But, never the less, I'm keen for a challenge, and keen to learn along the way, and I'm keen to share the highlights and lowlights of my journey.  &lt;/p&gt;

&lt;p&gt;So over the next few months (more likely years), I'll be working hard to bring the my concept of that racing game to life, building out tracks, vehicles, and gameplay, and sim mechanics. I'll also be sharing regular updates on progress, so make sure to follow us for the latest news.&lt;/p&gt;

&lt;p&gt;I'm pumped to embark on this journey and can't wait to see where it leads. Stay tuned for more updates!&lt;/p&gt;

&lt;p&gt;Best regards,&lt;br&gt;
ThatRacingGame Dev&lt;/p&gt;

</description>
      <category>career</category>
      <category>ai</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
