Skip to main content
Game Physics – Complete Beginner to Advanced Guide
CHAPTER 03 Intermediate

Movement and Motion Systems

Updated: May 16, 2026
20 min read

# CHAPTER 3

Movement and Motion Systems

1. Introduction

A static world is a boring world. The foundation of any interactive game is motion—moving an object from point A to point B smoothly and predictably. However, raw mathematical translation is not enough. If you simply teleport an object 5 pixels every frame, the movement will appear jittery on some monitors and incredibly fast on others. In this chapter, we will master Movement and Motion Systems. We will learn how to apply linear movement using directional vectors, calculate exact speeds, and ensure flawless, buttery-smooth motion across all hardware using Delta Time.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Implement basic linear motion (Kinematics) in code.
  • Combine Input Axes to generate a movement vector.
  • Prevent diagonal speed exploits using Vector Normalization.
  • Understand the critical role of DeltaTime in frame-rate independent motion.
  • Program smooth, interpolated movement transitions.

3. Linear Movement (Kinematics)

The simplest form of physics movement is Kinematic motion. This means we are moving the object using explicit math code, rather than letting a physics engine push it with forces.
  • The formula is always: Position = Position + (Direction * Speed * Time)

4. Constructing the Movement Vector

In a 3D game, you generally read player input to determine direction.
  • Input X (A/D keys) gives a value between -1 and 1.
  • Input Z (W/S keys) gives a value between -1 and 1.
We combine these into a Vector3(x, 0, z).
csharp
12345
float x = Input.GetAxisRaw("Horizontal");
float z = Input.GetAxisRaw("Vertical");

// The Y axis is 0 because we are sliding along the floor, not flying!
Vector3 moveDirection = new Vector3(x, 0, z);

5. The Diagonal Exploit (Normalization)

If the player holds 'W' (Forward: 1) and 'D' (Right: 1), the resulting vector is (1, 0, 1). According to the Pythagorean theorem, the length (magnitude) of this diagonal vector is 1.41.
  • The Bug: This means the player runs 41% faster when running diagonally! This was a famous exploit in early 90s games (like *GoldenEye 007*).
  • The Fix: You must always call moveDirection.Normalize(). This forces the maximum length of the vector to be exactly 1.0, capping diagonal speed.

6. Frame-Rate Independence (Delta Time)

If you run position += direction * speed inside the Game Loop, it happens every frame.
  • At 60 FPS, it runs 60 times.
  • At 144 FPS, it runs 144 times. The player moves more than twice as fast!
Delta Time (Time.deltaTime) is the fraction of a second it took to render the last frame. By multiplying your movement by Delta Time, you convert the math from "pixels per frame" to "meters per real-world second."
csharp
12
// Perfect, frame-rate independent movement
transform.position += moveDirection.normalized * speed * Time.deltaTime;

7. Visual Learning: The Motion Formula

txt
123
  [ Direction ]   *   [ Speed ]   *   [ Delta Time ]  =  [ Actual Movement ]
    (0, 0, 1)     *     5 m/s     *      0.016s       =    Move 0.08 meters
    Forward             Speed           Frame Time         This Frame

8. Best Practices

  • Use GetAxisRaw for Snappy Input: If you use standard GetAxis(), engines usually apply a slight "smoothing" filter to make the input feel like an analog stick, causing a slight delay before reaching top speed. For tight, responsive platformers (like *Celeste*), use GetAxisRaw(), which snaps instantly to 1 or 0.

9. Common Mistakes

  • Multiplying DeltaTime Twice: Beginners sometimes multiply their acceleration by DeltaTime, and then multiply the resulting velocity by DeltaTime again. This creates a quadratic time curve, making the physics simulation behave wildly unpredictably when framerates fluctuate. Only multiply velocity by DeltaTime when adding it to the position!

10. Mini Project: Build a Smooth Kinematic Controller

Objective: Write a complete, optimized character movement script.
csharp
1234567891011121314151617181920212223
class PlayerMovement
{
    public float walkSpeed = 8.0f; // 8 meters per second

    void Update()
    {
        // 1. Get raw input (-1, 0, or 1)
        float h = Input.GetAxisRaw("Horizontal");
        float v = Input.GetAxisRaw("Vertical");

        // 2. Construct the vector
        Vector3 direction = new Vector3(h, 0, v);

        // 3. Prevent diagonal speed boosting!
        if (direction.magnitude > 1f)
        {
            direction.Normalize();
        }

        // 4. Apply frame-rate independent motion
        transform.position += direction * walkSpeed * Time.deltaTime;
    }
}

11. Practice Exercises

  1. 1. Write the core formula for calculating Kinematic movement over time.
  1. 2. Why is it critical to multiply movement speed by the engine's DeltaTime variable?

12. MCQs with Answers

Question 1

In a top-down game, the player holds both the "Up" and "Right" arrow keys simultaneously. If the programmer forgets to normalize the movement vector, what gameplay bug will occur?

Question 2

Multiplying a character's velocity by Time.deltaTime changes the speed calculation from "units per frame" to what standard measurement?

13. Interview Questions

  • Q: Explain the mathematical "Diagonal Exploit" found in early 3D games. How do modern engines prevent this issue using Vector Normalization?
  • Q: Walk me through the concept of frame-rate independence. Why does multiplying velocity by DeltaTime guarantee that a character moves at the exact same speed on both a 30 FPS console and a 144 FPS PC?
  • Q: What is the difference between Kinematic motion (updating transform.position via script) and Dynamic motion (using a physics engine's Rigidbody)? When is it appropriate to use Kinematic motion?

14. FAQs

Q: Can I use Kinematic movement if I have walls in my game? A: If you forcefully update transform.position directly into a wall, the physics engine will glitch, and you might teleport through the wall! For Kinematic characters, you must use special collision-checking functions (like Unity's CharacterController.Move()) to stop the character before they intersect solid geometry.

15. Summary

In Chapter 3, we put our game in motion. We utilized the core Kinematic formula: Direction * Speed * Time. We read player input to construct 3D Vectors, and clamped their magnitude using Normalization to prevent the infamous diagonal speed exploit. Crucially, we decoupled our game speed from the computer's CPU speed by injecting DeltaTime into our math, ensuring flawless, professional-grade movement on any hardware.

16. Next Chapter Recommendation

Our character glides perfectly across the floor, but what happens when they walk off a cliff? Proceed to Chapter 4: Gravity and Falling Systems.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·