Featured Posts

<< >>

Website Getting an Update

My website that this blog is attached to (codersplayground.net) is getting an update. If you want to see what I am doing with it you can go to the dev section. Be aware that not all the content will be present.

Optimizing For Loops

I am pretty obsessed with getting every little bit of performance I can out of my code, especially when developing for mobile platforms. For loops, believe it or not, can be optimized using some very simple tricks.

Finding Initial Velocity Given Angle and Distance

Projectile physics can be a little complicated, especially if you already know where you want the projectile to go, and just need to figure out the required velocity. This post derives an equation which takes in a destination and launch angle and gives you the velocity you need.

The Thing About Raycasts

Raycasts are expensive, or so we are told, but just how expensive are they? This post, at a basic level, covers what exactly they do, and how are they used regularly.

Unity Android Key Mappings

Android devices have a number of physical or partially physical buttons. These and other inputs actually map to keyboard and mouse events for convenience. Here is a list of the mappings.

Website Getting an Update

My website that this blog is attached to (codersplayground.net) is getting an update. If you want to see what I am doing with it you can go to the dev section. Be aware that not all the content will be present.

Optimizing For Loops

I am pretty obsessed with getting every little bit of performance I can out of my code, especially when developing for mobile platforms. For loops, believe it or not, can be optimized using some very simple tricks. Normally you probably write a for loop like this:

for (int i = 0; i < some.Length; i++) {
    // Code
}

If you know that the length of whatever you're iterating is going to be less than 256 (0-255) you can use byte instead of int, if you aren't completely certain, you can probably get away with ushort (0-65,535). This will free up 24 and 16 bits as compared to int respectively, it's not much, but it can add up. You can also pre-lock the length into a variable to help speed things up. The reason this works is because for loop check their condition (second block) every single iteration. This means that you are accessing the length property every single iteration. Accessing a member of a class is more expensive than accessing a single variable, and thus adds up over many iterations. The performance change might be slight, but it adds up pretty quickly, especially if you are iterating through hundreds of pieces of data every single frame. So, what should the for loop look like? Well, like this:

byte length = some.Length;
for (byte i = 0; i < length; i++) {
    // Code
}

Finding Initial Velocity Given Angle and Distance

Most of the time a physics problem involves using a given angle and velocity to figure out where a projectile lands. This is all well and good, but when working on a game with projectiles you already know where it should land, and what angle it should be launched at. This article shows the process by which I solved the basic physics equations to take in the desired difference in distance, height, and launch angle, and give you the required velocity in return. If you aren't terribly interested in the work, you can just skip to the solution. Without further ado, here's the process by which I solved the equations.

The Standard Equations

\Large{\begin{align*}x\prime\ &=\ x\ +\ tv\cos\theta\\y\prime\ &=\ y\ +\ tv\sin\theta\ -\ \frac{1}{2}gt^2\end{align*}}

Rearranging and Replacing

\Large{\begin{align*}x\prime\ -\ x\ &=\ tv\cos\theta\tag{x.1}\\d\ &=\ tv\cos\theta\label{x.2}\tag{x.2}\end{align*}}


\Large{\begin{align*}0\ &=\ y\ -\ y\prime\ +\ tv\sin\theta\ -\ \frac{1}{2}gt^2\tag{y.1}\\0\ &=\ h\ +\ tv\sin\theta\ -\ \frac{1}{2}gt^2\label{y2}\tag{y.2}\end{align*}}

To make things more obvious, we will replace the differences with a single variable, namely \large{d\ =\ x\prime\ -\ x} (where \large{d} is the intended travel distance), and \large{h\ =\ y\ -\ y\prime} (where \large{h} is how high the projectile starts relative to its ending height).

Eliminating t\!\!\!\; ime

In order for this equation to work, time cannot be a factor. In truth, it really doesn't matter how long the projectile takes to get there, just that we arrive. If you need time later, just divide the range by the \large{x} velocity component. Since the \large{y} equation has a quadratic for time, we'll solve that one.

Using the condensed height equation in \large{\eqref{y2}\!} , we can solve using the quadratic formula (and some basic negation cancellation).

\Large{\begin{align*}t\ =\ \frac{v\sin\theta\ \pm\ \sqrt{v^2\sin^2\theta\ +\ 2gh}}{g}\label{t}\tag{t}\end{align*}}

Since we know that what is coming out of the square root is positive, we can eliminate the possibility of a negative option as being the one we ultimately want. The projectile is supposed to be moving forwards after all.

The Heart of the Matter

Now that we have time eliminated from \large{\eqref{t}\!} , we need to plug it in to the \eqref{x.2} equation.

\Large{\begin{align}d\ &=\ \frac{v\cos\theta}{g}\left[v\sin\theta\ +\ \sqrt{v^2\sin^2\theta\ +\ 2gh}\right]\end{align}}

Then we need to solve that monster for \large{v} . We start by moving \large{g} over, and distributing \large{v\cos\theta} .

\Large{\begin{align}dg\ =&\ v\cos\theta\left[v\sin\theta\ +\ \sqrt{v^2\sin^2\theta\ +\ 2gh}\right]\\\nonumber\\=&\ v^2\sin\theta\cos\theta\ +\ v\cos\theta\sqrt{v^2\sin^2\theta\ +\ 2gh}\\\nonumber\\=&\ v^2\sin\theta\cos\theta\ +\nonumber\\&\ \sqrt{v^4\sin^2\theta\cos^2\theta\ +\ 2ghv^2\cos^2\theta}\end{align}}

We then isolate the square root and square both sides to eliminate it, and consolidate common terms.

\Large{\begin{align}dg\ -\ &v^2\sin\theta\cos\theta\ =\ \nonumber\\\ &\ \sqrt{v^4\sin^2\theta\cos^2\theta\ +\ 2ghv^2\cos^2\theta}\\\nonumber\\d^2g^2\ -\ &2dgv^2\sin\theta\cos\theta\ +\ v^4\sin^2\theta\cos^2\theta\ =\nonumber\\&\ v^4\sin^2\theta\cos^2\theta\ +\ 2ghv^2\cos^2\theta\\\nonumber\\d^2g^2\ -\ &2dgv^2\sin\theta\cos\theta\ =\ 2ghv^2\cos^2\theta\\\nonumber\\d^2g^2\ =&\ \ 2ghv^2\cos^2\theta\ +\ 2dgv^2\sin\theta\cos\theta\end{align}}

We continue to eliminate like terms, extract the velocity component, and re-balance.

\Large{\begin{align}d^2g\ =&\ \ 2hv^2\cos^2\theta\ +\ 2dv^2\sin\theta\cos\theta\\\nonumber\\d^2g\ =&\ v^2\left(2h\cos^2\theta\ +\ 2d\cos\theta\sin\theta\right)\\\nonumber\\v^2\ =&\ \frac{d^2g}{2h\cos^2\theta\ +\ 2d\cos\theta\sin\theta}\end{align}}

Using trig identities we can simplify the equation, and keep like terms.

\Large{\begin{align}v^2\ =&\ \frac{d^2g}{2h\cos^2\theta\ +\ d\sin2\theta}\\\nonumber\\v^2\ =&\ \frac{d^2g}{h\cos2\theta\ +\ h\ +\ d\sin2\theta}\end{align}}

We're pretty much done here, just need to take the square root and integrate it into code. 

Solution

\Large{\begin{align}v\ =\ \sqrt{\frac{d^2g}{h\cos2\theta\ +\ h\ +\ d\sin2\theta}}\end{align}}

Where:

\Large{\begin{align*}g\ &=\ 9.81\ \text{(or whatever your gravity is)}\\h\ &=\ y\ -\ y\prime\\d\ &=\ x\prime\ -\ x\end{align*}\\\arctan(\tfrac{h}{d})\quad<\quad\theta\quad<\quad\frac{\pi}{2}}

Putting it into Code

Coding it is pretty straight forward, below is an example function that I wrote to handle doing the mathematics of finding the velocity.

// This function determines the required velocity to reach the range at the given height and angle
private float DoTheMath(float distance, float height, float doubAngle)
{
    // The lowest angle is a direct shot at an infinite velocity
    float lowestAngle = Mathf.Atan2(height, distance) * 2;
    
    // If the angle doesn't fall within the (lowestPossible, 90) range, there is no solution
    if (doubAngle >= Mathf.PI || doubAngle <= -lowestAngle) {
        return 0;
    }
    
    // I figured this equation out after working through the standard physics equations. See: http://wp.me/p35fKy-4k
    return Mathf.Sqrt((9.81f * distance * distance) / (height * Mathf.Cos(doubAngle) + height + distance * Mathf.Sin(doubAngle)));
}

The Thing About Raycasts

Raycasts are extremely versatile. With raycasts you can see if there is something under the mouse, in the path of a straight shooting object, or just about anything else regarding something being in the path of something else. As far as calculations go, raycasts are probably one of the most expensive (in terms of computational time) things that you can do. But how expensive are they? Well, let's put things into perspective about just how expensive raycasts are. We'll look at the basics of raycasting and how it is used with great frequency in a standard setting.

Raycast Basics

What exactly is a raycast, how does it work, why is it so expensive? A raycast has an origin and a direction, like any vector, and is literally cast, or thrown if you will, into the scene. The process basically involves going through every object, then checking ever vertex, face, and edge, for an intersection. Even with rigorous optimization this can be checking against hundreds of elements, and this is what makes it computationally expensive.

How it's Used

While it is relatively expensive, it is exactly how the scene is rendered. On my desktop that means 1680 x 1050 = 1,764,000 raycasts per frame just to display what is going on. On my tablet it's 1920 x 1200 = 2,304,000 raycasts per frame and 960 x 540 = 518,400 for my phone. So while it is an expensive calculation, remember that it is happening half a million to two million times a frame just to render, so doing it another 30 or so times is no worse than a 6 x 5 grid of extra pixels.

Unity Android Key Mappings

If you are using Unity to develop for Android platforms, you may be wondering what keys the different buttons map to. I happened to find the answer in a location unrelated to Unity, but the information is still valid. In order to make touch devices generally compatible, touch and key inputs are directly mapped to mouse and keyboard buttons respectively. Below is a short table snagged from a Google Group

  • One finger tap = left mouse button
  • Two finger tap = right mouse button
  • Menu key =
    • Middle mouse
    • Windows key
  • Home button = HOME key
  • Back button = ESC key
  • Power button = END key

Note:

After testing with my tablet, I could not confirm any other keys besides the back button. The menu key did not even show up.

The Importance of Humor

Many people say that having a good sense of humor is beneficial. This is the case with coding as well. Having a good sense of humor will make your code more readable as it will provide a little chuckle here and there, as well as keep you in a good mood. Working while happier is a great way to avoid lots of little errors. Not only that but, since you are in a good mood, you will be less tempted to distraction making you more efficient. Who doesn't want to complete "8 hours of work" in 5 or 6? Below is a little snippet of some good humor that I put in my code that may or may not be funny, but is of non-detrimental nature, and gave me a bit of a smile.

Coding Humor

Why yes, public health is important.

Particular Problems with Public Variables in Unity

The Unity documentation it indicates that all public variables are made available in the inspector for direct editing. While this is handy, it is also dangerous. This article will cover a few things regarding public variables, and how to avoid them in Unity.

Read more

Avoiding Long Compile Times

Long compile times are a real chore when it comes to testing things. It is especially cumbersome when all you are doing is making small edits resulting in 2 seconds worth of editing, and 2 minutes waiting for compiling.

Read more

The Importance of Class and Object Oriented Programming

While class is certainly important to have in real life, it is equally important to have while programming. Taking advantage of an Object Oriented Programming method (or OOP method) may very well be one of the most important higher concepts to learn and understand. This article helps cover what OOP is, its benefits, and how to use it.

Read more

Quick Update

I haven't had time to make any posts this week for a number of reasons, but I plan to resume next week with a series on Object Oriented Programming as well as what Aspect Oriented Programming means.