Creators – Week 11

This week we worked on our gem detector. We want a signal that behaves like this:

  1. The signal strength should increase dramatically as we’re closer to a gem
  2. The signal should be strongest when we’re pointing directly at a gem
  3. The signal should be zero when the gem is behind us

Setting Up a Test Scene

To develop the sensor, we created a new test scene. It consists of a flat plane, a tall and narrow cube to represent our target (signal source) and the prefab containing the first person character controller.

We also added a new script ProximitySensor.cs to our Scripts folder and attached it to an empty object in our new scene as “Proximity Sensor”.

Adding UI Elements to the Scene

We added a few Text – TextMeshPro objects to our scene. Adding the first one automatically added a Canvas object as well. In the scene view. the UI elements look enormous, but in the game view, they just overlay the game image.

Calculating Distance

All of our positions in Unity are stored as Vector3 objects. If you subtract one Vector3 from another the result is also a Vector3 that contains the differences between the two positions. Unity can give us the length of this (or any) Vector3 through it’s magnitude property. The code below shows this calculation and us setting the value of the UI Text element so we can see it:

float distance = (Player.position - Target.position).magnitude;
DistanceTxt.text = "Distance: " + distance.ToString();

Calculating Base Signal Strength

We want a scheme were by the signal falls off quickly with distance. We start with a nominal strongest signal value of 100. If we divide this by distance it falls off, but not that strongly, as shown in the blue line below. If instead we divide it by distance squared (meaning the distance multiplied by itself) the impact of distance is much more dramatic and the value falls off to a small value much more quickly. This is the red line.

The problem with this scheme is that once distance goes less than 1, the resulting value is greater than 100 and when we get to zero, the value hits infinity (anything divided by zero is infinity).

We can simply solve this infinity problem by adding one to d2. This means that the smallest value it can have is 1, not zero and the highest value the signal strength can get to is 100.

This seems perfect, but actually in testing its clear we can never practically get to zero distance, so we never get to full signal strength. The final modification is not to add one to d2 but to add something a bit smaller. We’re going to use 0.9. Now the signal strength will go as high as 100/0.9 = 111.11 so we just use logic that says if it’s greater than 100, then make it 100. Here’s what that looks like (noting the flat section at the start):

Here’s what the code matching this looks like:

float signalStrength = MaxSignalStrength / ((distance * distance) + 0.9f);
signalStrength = Mathf.Min(signalStrength, MaxSignalStrength);
SignalStrengthTxt.text = "Signal Strength: " + signalStrength.ToString();

Unit Vectors/Normalised

A Vector3 that has a length of one is called a “unit vector”. Vector3.normalised gives us back a version of that Vector3 that points in the same direction as the original by always has a length of one.

Pointing In The Same Direction

If we have two Vector3s that have a length of one, we can use the Vector3.Dot() function to determine to what degree they’re pointing in the same direction. Vector3.Dot() also called a Dot Product. When we pass Vector3.Dot() two unit vectors it will return a value between -1 and 1. If the two vectors are pointing in the exact same direction, it will be 1 and if they’re pointing in opposite directions it will be -1. If it’s zero it means that they are perpendicular to each other and don’t point in the same direction at all. Any positive value in-between means they’re pointing in the same direction somewhat.

We can work out the Vector3 from the Player to the Target and the Player’s Forward vector and compare them using Vector3.Dot(). We will make it so that all negative values go to zero. The resulting value is one that gets close to 1 when the player is pointing directly at the target. Here’s the code:

Vector3 playerToTarget = (Target.position - Player.position).normalized;
float pointingTowards = Vector3.Dot(playerToTarget, Player.forward);
pointingTowards = Mathf.Max(pointingTowards, 0.0f);

Combining Distance and Direction

To combine these calculations, we just multiply them. Now we have a measure that reacts to both distance and direction. Here’s that code:

float adjustedSignalStrength = signalStrength * pointingTowards;

Code Download

The code for this week’s project is on our GitHub, as always. 

Modellers – Week 11

Hi Folks. Minimal notes this week as we spent the session working with the sculpting tools in Blender; something you really just need to try for yourself.

To start a new sculpting session, just choose File > New > Sculpting to be presented with a  high-resolution quad sphere and an array of sculpting tools.

Of these tools there are three I find most useful:

  1. Draw: Normally pulls out the mesh, but will create depressions when CTRL is held
  2. Crease: Makes fine creases in the mesh. Great for adding detail
  3. Smooth: Great for when the mesh has become a little rough or uneven

You should experiment with the others to see which you like best!

Finally, here’s a little rough and unflattering 10min self-portrait I knocked up at the end of the session, just for laughs:

sculpt

When sculpting, it a good idea to remesh from time-to-time where you’ve significantly deformed the mesh. Remeshing evens the mesh spacing automatically, avoiding places where individual polygons are overstretched, but it’s only available in Blender 2.81. Some people had this version already installed, while others installed it during the session. If you haven’t got it yet and would like to install it you can get it here.

Finally, here’s little personal project you might like to see. I sculpted and painted my cat Noodle’s head. I used a couple of reference photos and a technique called stencil painting to generate the texture:

 

Explorers Week 11 Christmas Scene

Thank you so much to Eoin you led the session on Saturday, I think you all enjoyed it. I think you will agree that our two Black Belt Mentors did really well leading their first session. So thank you Ruaidhrí and Eoin

Eoin did a Christmas Scene with you. Here a some screenshots of the code.

See you all on Saturday and Remember bring your own drinks!

Martha

Iseult, Julie, Ruaidhrí and Eoin

Explorers Week 11 – Pacman

For the last week we worked on a Pacman type game. We tried to put in all the code we have learned over this year and all the games were brilliant and all so different.

This week is our very important week, our last week but the week we award our belts for all your great work during the year. There also might be some Pizza and the odd sausage.

Remember if you haven’t been in the last couple of weeks that doesn’t matter, come along we would love to see everyone.

 

Here are the notes in PDF CDA-S8 Week_11-PACMA.PDF

See u Saturday

Martha

Julie, Ruaidhrí and Eoin

Creators: Spirograph

This week in the Creators group we looked at emulating the classic toy, the Spirograph.

spirograph3

The Spirograph consists of geared plastic discs. One disc is fixed in place over a sheet of paper and the other, with a pencil tracing the path, is allowed to spin around it. The result is a complex and beautiful design on the paper.

Screen Shot 2018-01-30 at 17.04.14

This diagram should help explain in conjunction with the photo. The centre of the black disc spins around the centre of the red disc, which itself doesn’t move. So the centre of the black disc rotates around in a circle. Pretty simple?

Now, the pencil itself rotates around the centre of the black disc. Shouldn’t that make a circle too? Well it would if the black disc wasn’t moving. Thankfully though, it is and that’s what makes this interesting.

Finding the Location of the “Pencil”

So how do we find the location of the pencil? Let’s look at our diagram again, but with things re-labeled a bit:

Screen Shot 2018-01-30 at 17.33.58

  • Centre: Formerly “centre of red disc”. It’s the fixed centre of our spirograph
  • Centre2: Formerly “centre of black disk”
  • Point: The point on our curve. This is where the pencil would be in a physical spirograph.
  • Radius0: Distance from Centre to Centre2
  • Radius1:Distance from Centre2 to Point
  • Angle0: The current angle of the line between Centre and Centre2
  • Speed0: The amount that angle0 increases every time we draw
  • Angle1: The current angle of the line between Centre2 and Point
  • Speed1: The amount that angle1 increases each time we draw

So at any time the location of our point is:

Point = Centre + [Centre2 relative to Centre] + [Point relative to Centre2]

So know where Centre is and if we can calculate where Centre2 is relative to Centre and similarly where Point is relative to Centre2, we can just add them all together!

Given an angle and a distance, can we get a location?

The answer to this is a resounding “yes”! Look at the diagram:

Screen Shot 2018-01-30 at 17.56.34

given an angle and a radius, we can calculate the X and Y position of any point around a circle. The magic is the COS and SIN (pronounced “kos” and “sign”) functions. These functions exist in almost all programming languages and JavaScript’s no exception.

Using p5.Vector

The last big concept we tackled thus week was using P5js’s built-in vector class to store (x, y) points and make our code tidier. To make a vector we just use createVector(x, y). We can then use functions to add them together, etc. We would get the same result working with the X and Y values separately but the code is a lot neater and shorter.

And in conclusion

This looks pretty cool:

 

Getting this week’s code

As aways, all the code from our Creator group can be found on our GitHub repository.