As I learned, I had to set several projects aside for different reasons. In retrospect, this idea was simply too ambitious at the time.
Check out this pitch I made about the concept & design on itch.io for a playable demo.
When I started, I was confident programming simple Unity behaviors. I had figured out C#, and was ready to build my game! Unfortunately, Having spent little time considering code design, the project became unmanageable fast.
I learned from it, and tried to make my current project more organized from a programmer’s perspective. A focus on modular design has made my scripts both easier to expand functionally and simpler to maintain should any issue arise.
Lerp() is a common source of confusion for newbies. Many (bad) “tutorials” use it in a careless way and don’t explain its actual function. It’s one of a few things I can claim to fully understand, so here we go.
Let’s just get this out of the way: all Mathf.Lerp() does is return a position half-way between two variables. In game development if you want to move something from a beginning point to an end point what you’re really talking about is applying linear interpolation to find a range of points that can be used for animation.
Interpolation takes a lot more than just a Lerp() method call. Here are the variables I’ll use to interpolate a variable over time:
-A reference to a variable that will animate.
-The value it starts moving from.
-The value it ends at.
-An amount of time it takes to reach the end.
-The amount of time that has passed.
-The position of the interpolation at a given percentage of that time passed..
Here is an academic example. In practice the startPosition would often be copied from a supplied movingFloat at the beginning of such a method.
float startPosition = 0;
float endPosition = 100;
float movingFloat = 0;
float currentPosition = 0;
float percentComplete = 0;
float totalDuration = 5; // 5 seconds
for (float timePassed = 0; timePassed < totalDuration; timePassed += Time.deltaTime)
percentComplete = timePassed / totalDuration;
// percentComplete = percentComplete * percentComplete; // exponential curve
currentPosition = Mathf.Lerp(startPosition, endPosition, percentComplete);
movingFloat = currentPosition;
yield return 0;
Here’s a great article that helped me understand how to correctly write these methods.
I recommend beginners initially write their own interpolation methods. Creating methods like these myself was good practice; and led me to learn more advanced C# concepts as I searched for ways to make them more portable and generic. Ultimately, plugins like DOTween allow us interpolate anything with a choice of curve using one method call.
Challenge: Can you make the interpolation more accurate? (Hint: use a while() loop and one if() statement.)
Before I got serious about 3D modeling and game development, one of my hobbies was making abstract fractal flame art. They’re fun to make because you can spend as much or little time as you’d like on them. I have a decent handle on making deliberate forms, and will probably do some more when my self study of Blender & Unity3D slows down.
Wikipedia has this to say about fractal flames:
Fractal flames are a member of the iterated function system class of fractals created by Scott Draves in 1992. Draves’ open-source code was later ported into Adobe After Effects graphics software and translated into the Apophysis fractal flame editor.
Fractal flames differ from ordinary iterated function systems in three ways:
- Nonlinear functions are iterated in addition to affine transforms.
- Log-density display instead of linear or binary (a form of tone mapping)
- Color by structure (i.e. by the recursive path taken) instead of monochrome or by density.
The tone mapping and coloring are designed to display as much of the detail of the fractal as possible, which generally results in a more aesthetically pleasing image.
A while back before I started pursuing mesh topology for low-poly 3D games, I made this image to teach myself Blender’s internal material and lighting options. In doing so, I learned that multiple materials can be assigned to different faces of a model.
This carries over to Unity, though naturally doing so results in a draw call for each material on an object.
My practice creating low-poly 3D models composed of planar faces continues, with slow but encouraging results. I am becoming more intuitively aware of how translations, rotations, and scaling distorts quads. Doing so has greatly increased my use of the 3D cursor, pivot point modes, and transform orientation options.
Although maintaining planar faces may be a fool’s errand, doing so is clearly increasing my proficiency with Blender and understanding of 3D modeling and mesh topology.
I’ve been busy looking for a better job, so I haven’t had much time to work in Blender. On a personal note I find it difficult to focus on my artwork without the security of a paying job.
I’m getting pretty decent at solid surface low poly modeling. Unfortunately, when I made this model I did not consider that its quads should be planar. It just didn’t look very good when I tested shading it as a result. It may have been possible to adjust the shader, but really these faces are metal panels and shouldn’t have triangle folds at all.
So I adjusted the model to make the body panel quads more planar, and was able to settle on a work flow to achieve that. The problem with doing this is that making each face planar disturbs its neighbors, so one must step through all the faces in a linear fashion manually correcting each.
Unfortunately, these results aren’t quite close enough to a “solve” – or state where all the faces are planar, for Blender’s iterative “Make Planar Faces” function to work. While this model would still be usable, if a model requires planar quads it’s probably best to make each quad planar as you build the model. I have discovered that if you do this, you can produce a perfect result.
I’m still just winging it and should probably read about solid surface modeling, but I’m going to take another whack at this design today with what I have learned in mind.