Learning Unity
Unity Model Information
What is Interpolation?
Interpolation in game development refers to the process where the engine adds additional frames to create smooth transitions between animations. For example, if you have an animation transitioning from "A" to "B", but some frames are missing, the Unity engine fills in the gaps. The result is a seamless transition, represented as:
"A" → (added frames) → "B".
This technique ensures smoother animations and enhances the overall visual experience.
Animator Options in Unity
Unity offers several options to control animation behavior, providing flexibility for different game scenarios:
1. Update Modes
These determine how the animator is updated in relation to the game’s timescale:
Normal:
Animations update based on the game's timescale. If the game slows down, the animation also slows down.Animate Physics:
Updates animations every 0.02 seconds, making it ideal for objects affected by physics, ensuring synchronization with the physics engine.Unscaled Time:
Animations run independently of the game's timescale. Perfect for objects that need to animate regardless of time manipulation (e.g., UI elements or special effects).
2. Culling Modes
Culling determines how Unity handles animations when the object is not visible on-screen:
Always Animate:
The animation continues rendering regardless of whether the object is in view. Useful for critical objects whose animations need to persist, like essential gameplay elements.Cull Update Transforms:
The visual animation pauses when the object is off-screen, but Unity continues calculating the object's state. Visuals resume seamlessly when the object comes back into view.Cull Completely:
Both visuals and calculations stop entirely when the object is out of view. This saves performance but may not be suitable for objects that need constant updates.
Helpful Links for Game Assets
Here’s a curated list of resources to help you find or create game assets, both free and paid:
Free & Paid Game Asset Resources
A community-driven platform offering free game assets, including sprites, sound effects, and textures.
A vast marketplace with both free and paid assets for indie game developers.
Free 3D character animations and rigging. Great for quickly animating your custom models.
A comprehensive library of assets tailored for Unity, ranging from 2D sprites to complex 3D environments.
DALL-E 3
Excellent for generating custom images. Pair with image editors for touch-ups to create unique characters or textures.
Creating Your Own Game Assets
A powerful, free tool for 3D modeling, animation, and rendering. Ideal for creating custom game assets.
A free image editing software. Perfect for quick touch-ups, UI design, and texture creation.
These resources and tools cater to all levels of game development, from beginners to seasoned professionals, making it easier to find or create the assets you need for your game projects!
Steps to Create Custom Icons
Generate Icons with DALL-E 3
Use DALL-E 3 to create icon concepts that match your desired style or theme.
Experiment with prompts to fine-tune the design and color scheme.
Refine Icons in GIMP
Crop and Edit: Import the generated image into GIMP, crop it to isolate the icon.
Magic Wand Tool: Use the magic wand tool to select and delete unnecessary portions of the image.
Clean Edges: Zoom in to ensure edges are clean and consistent.
Apply Translucent Effects
Adjust opacity or use blending modes to make the icon subtly blend with the background. This minimizes the clash of different themes and enhances visual harmony.
Final Touches
Experiment with gradients, shadows, or outlines in GIMP to make the icon pop without overwhelming the design.
Export the finished icons in a suitable format (e.g., PNG) for your project.
Who Knew Unity Could Look This Good?
Check out this stunning creation by Sakura Rabbit:
https://www.youtube.com/watch?v=r_ErytGpScQ
Unity’s Capabilities
Unity is an incredibly powerful game engine, capable of producing breathtaking visuals and complex game mechanics. The video above is a perfect example of what Unity can achieve with the High Definition Render Pipeline (HDRP).
Using HDRP for High-Quality Results
While HDRP unlocks the potential for creating visually stunning projects, it comes with a steep learning curve and requires significant effort:
Customization and Tweaks: HDRP offers immense flexibility, but achieving a polished, professional look often involves fine-tuning various settings and features.
Recommended Team Size: To create visuals of this caliber, it’s generally advised to have a team of 5 or more. Collaborating helps manage the workload and allows for specialization in areas like lighting, shaders, textures, and animations.
Final Note
Unity, when used with tools like HDRP, proves it's a top-tier engine for creating AAA-quality visuals. If you’re aiming for this level of quality, be prepared to invest time and resources, but the results are undoubtedly worth it!
Ex. Icons created by Dall-E & modified by Gimp
What is Lerp in Unity?
Lerp (short for "linear interpolation") is a method used to calculate a value between two points based on a specified ratio. It’s a powerful tool in Unity for creating smooth transitions and animations.
How Lerp Works
The formula for Lerp is:
Lerp(Start, End, Time)
Start: The starting value.
End: The ending value.
Time: A ratio from 0 to 1, determining the interpolation point between the start and end.
Ex. Lerp(0, 10, t). Start = 0, End = 10, Time = t
t = 0.25f, Result = 2.5
t = 0.50f, Result = 5
t = 0.75f, Result = 7.5
Example Scenario: Cube Transition
In this example, we use Vector3.Lerp and Color.Lerp to move a cube from point A to point B and change its color from green to red over 3 seconds:
Bezier Curves
Quick information about Bezier Curves by Vivek Tank.
*Consider using SetPositions instead, if setting multiple positions, as it is much faster than making individual function calls for each position
Quadratic Bezier Curve
*Did not use, manual work needed to adjust smoothness
Better solution utilizing Pi, continue below
Quadratic Bezier Curve
Cubic Bezier Curve (detailed)
Cubic Bezier Curve (clean)
Simple quadratic Bezier Curve, using three points to make a smooth curve.
Use Lerp to get the consistent progression from A to B and B to C, (white spheres)
Lerp between our two white sphere, acts as a guide for our smooth curve.
Now we use two quadratic curves, and Lerp between the two quadratics in order to get the full curvature of our 4 points (A, B, C, D).
Code for the Quadratic, Cubic curve above using Lerp.
Pi Health-bars Trigonometry Basics
Objective: Get multiple smooth consistent points for our line renderer.
Back to the basics! Intro to calc.
We can use Cos and Sin to map out consistent points for our line renderer.
Cos and Sin will return numbers ranging between -1 to 1 if the Hypotenuse = 1, remember: a² + b² = c²
c² = b² + a²
Hypotenuse = 1 as "c"
Opposite = Z as "b"
Adjacent = X as "a"
we will use SOH CAH TOA using "t" in radians as our angle.
That sets X as Adjacent and Z as Opposite
P(X, Z)
Cos(t) = X, how we get this in steps below
Cos(t) = Adjacent / Hypotenuse
Cos(t) = Adjacent / 1
Cos(t) = Adjacent
Cos(t) = X
Sin(t) = Z, how we get this in steps below
Sin(t) = Opposite / Hypotenuse
Sin(t) = Opposite / 1
Sin(t) = Opposite
Sin(t) = Z
Ignore our "Y" position.
Y = height of health-bar, number doesn't change.
Focus on "X", we need 1 to -1.
P(1, 0) -> P(0, 1) -> P(-1, 0)
Cos(t) can be looped to get us values, use Lerp!
Cos(0) = 1
Cos(3.14/2) = 0
Cos(3.14) = -1
And "Z" we need 0 to 1 to 0
P(1, 0) -> P(0, 1) -> P(-1, 0)
Sin(t) can be looped to get us values, use Lerp!
Sin(0) = 0
Sin(3.14/2) = 1
Sin(3.14) = 0
Incrementing "t" ranging from 0 -> 3.14, use Lerp, the more loops we do the smoother the health-bar gets, as the points act as a guide for our line renderer.
If t = 3.14 it makes a semicircle.
Point(X, Z) -> Point(Cos(t), Sin(t)).
Where t is constantly changes from 0 to 3.14, more loops means smoother health-bar.
Use a line renderer to map the health-bar from the points you just made.
Finally, rotate the health-bar as necessary with our model.
And if you want a smaller semi-circle, change what t = smaller number, or bigger if you want a bigger semi-circle or a full circle.
Ex. 32 loops
Code to create curved health-bars
Here is the code I used to make our curved health-bars, doesn't look like much, but having to understand, implement took countless tries to make it look right and presentable with the prefabs I have.
For the complete code, take a look at my tower defense GitHub called "CurvedHealthBar."
OOP: Encapsulation with Getter & Setters
Get & Set methods are used when we want to protect our structure of the scripts we built, we control the behaviour and type of data that goes in and out of our scripts.
We are able to control how others use our scripts the way we intended, giving users to read (get method) what we want them to see. Or giving them the option to both read and write (get and set method), again what we decide they can read or change in value.
Great when working with big groups, we protect our variables instead of using global variables.
Global variables can cause lots of problems for everyone once they decide to compile everything together.
Using the Get method
Using the Set method, we are able to set the value to whatever we like, this method is more flexible then relying on just the Get method, as we had to create a function to set the variable of our time.
Iterating through buttons, changing the time
Creating your own Toggles
Needed a group of toggles where only one can be selected out of the three. Only one will be active within that group.
Toggle and toggle group function did not seem to work the way I intended, seemed to break apart when other buttons outside of the group were pressed, ex. toggles would deselected if something outside were pressed. (Also checked Event System "Deselect on Background" on and off)
So I decided to make a simple script, to work the way I intended.
Remember even in a 2D environment, in this case our canvas. There still lies some 3D rendering, orders of rendering matter. Rendering "A" then "B," will have "B" overlapping "A" so only "B" appears.
Used this logic to have whatever is played render a the green symbol overlapping the original.
Easy Text Alignment
Having to align texts box by box?
Don't do this, having to adjust the transformation of each individual object can become tedious if you need to make minor adjustment.
Grouping children GameObjects under a parent will pull the parents world coordinates (transformation) set as its base, then the child transformation will be relative to the parents coordinates.
Bad Example
Good Example
Do this.
Group children into parent Game Object, you only need to adjust the parent object that will automatically apply to all child objects.
In this example, if I were to change the "LeftSide" transformation object say X = +20, all children transformation (*Title) will adjust relative to the parent Game Object, in this case the four Title objects will shift to the right +20.
Do this.
Throw it all under one text-box for one side, then create the second text-box for the other side and adjust spacing as necessary.
Tips & Tricks
"[SerializeField]" is great for editing variables in scripts as it allows us to change private variables on the go for easy access and during game play runtime. This method is apart of OOP.
*SerializeField and public for one variable should not be used together.
Build a naming scheme that is easy to follow for consistency throughout your project.
There isn't a set rule, it depends entirely on the team or yourself if you're an independent developer.
Consistency is key.
Pascal Case (first letter is capitalized)
PascalCase
Camel Case (letters are capitalized except the first)
pascalCase
Snake Case (underscores between words)
pascal_case
Hungarian Notation (first letter represents type)
sPascalCase (string)
arrPascalCase (array)
Uppercase (all uppercase)
PASCAL_CASE
You can also mix them up, ex.
Classes & Scripts & Property
Pascal Case + Snake Case
Pascal_Case
Variable names, capitalize first letter starting with second
Lower Case + Snake Case
pascal_case
Camel Case + Snake Case
pascal_Case
Fields from getting and setters
_characterHealthPoints
Game Managers should be a singleton pattern, load once and never destroy it on a new load.
*Type Mismatch Error
If you encountered a "Type mismatch" for referencing/dropping scripts inside another script, check to see if its a prefab and if the script your dropping is coming from a scene object.
The prefabs cannot reference a scene!