Skip to main content
Mr. Helland
  • Home
  • Calendar
  • More
English
Deutsch English Español Français Tiếng Việt Русский العربية 简体中文
You are currently using guest access
Log in
Mr. Helland
Home Calendar
Expand all Collapse all
  1. 3D Game Prog (S2)
  2. 1️⃣ Rigidbody Physics
  3. 07: Rude Gold Bug (Part 5)

07: Rude Gold Bug (Part 5)

Completion requirements
Make a submission
Due: Monday, March 2, 2026, 12:00 AM

target.png Learning Target

  • Detect physics events in code
  • Control Rigidbodies through scripts
  • Change the state of objects in response to physics events

 


video.png Resources

  • Rigidbody.AddForce:
    Unity Doc: https://docs.unity3d.com/ScriptReference/Rigidbody.AddForce.html
    Unity Video:
    watch


  • Rigidbody.AddTorque:
    Unity Doc: https://docs.unity3d.com/ScriptReference/Rigidbody.AddTorque.html
    Unity Video:
    watch


  • OnTriggerEnter:
    Unity Doc: https://docs.unity3d.com/ScriptReference/Collider.OnTriggerEnter.html
    Unity Video:
    watch


  • OnCollisionEnter:
    Unity Doc: https://docs.unity3d.com/ScriptReference/Collision.html
    Unity Video:
    watch


  • Rigidbody.isKinematic:
    Unity Doc: https://docs.unity3d.com/ScriptReference/Rigidbody-isKinematic.html

 


pencil.png Instructions

Step 1: Scripting Basics — Triggers and Collisions

So far your machine has used physics components set up entirely in the Inspector. In this part, you'll write C# scripts that react to physics events and change what objects do at runtime.

There are two main ways a script can detect physical contact:

    • Trigger Colliders — A collider with "Is Trigger" checked. Objects pass through it, but the script is notified. Good for invisible zones.
    • Collision Events — Two solid colliders that actually bounce off each other. The script is notified when they first touch.

The relevant Unity event methods are:

     void OnTriggerEnter(Collider other) { } // something entered a trigger zone
     void OnCollisionEnter(Collision col) { } // two solid objects collided



There are quite a few ways you can use collisions and triggers to alter the behavior of a physics simulation in Unity.
Here are 4 different examples:

Example 1: Trigger Applies Force or Torque

When the ball (or any object) enters a trigger zone, the script can push or spin another object by calling AddForce() or AddTorque() on its Rigidbody.

Some ideas: A fan grate that blasts the ball upward when it rolls over it. A pressure plate that launches a boulder sideways. A trip wire that sends a pendulum swinging. A "boost pad" that fires the ball forward.

Store the target object as a public variable so you can assign it in the Inspector without hard-coding names:

using UnityEngine;

public class TriggerForce : MonoBehaviour
{
    public Rigidbody target;          // drag the object here in Inspector
    public Vector3 force  = new Vector3(0, 500, 0);
    public Vector3 torque = new Vector3(0, 0, 200);

    void OnTriggerEnter(Collider other)
    {
        if (target != null)
        {
            target.AddForce(force,  ForceMode.Impulse);
            target.AddTorque(torque, ForceMode.Impulse);
        }
    }
}
Tip: ForceMode.Impulse applies the force all at once (like a kick). ForceMode.Force applies it continuously per physics frame — useful inside OnTriggerStay().

 


Example 2: Trigger Releases a Kinematic Object

A kinematic Rigidbody is frozen in place — gravity and forces have no effect on it. Setting isKinematic = false at runtime "releases" it so it falls or flies away normally.

Some ideas: A boulder balanced on a ledge that falls when the ball rolls past. A gate or drawbridge that drops when triggered. A stack of boxes held up by a peg that gets knocked out. A wrecking ball that is held still until the right moment.
using UnityEngine;

public class ReleaseKinematic : MonoBehaviour
{
    public Rigidbody target;   // the frozen object to release

    void OnTriggerEnter(Collider other)
    {
        if (target != null)
        {
            target.isKinematic = false;  // let gravity take over
        }
    }
}
Tip: You can also go the other direction — set isKinematic = true to freeze a moving object, like catching a ball in a cup or slamming a gate shut.

 


Example 3: Collision Between Two Objects Changes Movement

OnCollisionEnter fires when two non-trigger colliders physically hit each other. You can react to that impact — add extra force, change kinematic state, or anything else.

Some ideas: A bumper that fires the ball back with extra speed when hit. A domino that topples with a big push when struck. An explosive barrel that blasts nearby objects when hit hard enough. A pinball flipper that swings when the ball collides with a sensor.
using UnityEngine;

public class CollisionBumper : MonoBehaviour
{
    public float bounceForce = 800f;

    void OnCollisionEnter(Collision col)
    {
        // Push the incoming object away from this object's center
        Rigidbody rb = col.rigidbody;
        if (rb != null)
        {
            Vector3 direction = col.transform.position - transform.position;
            direction.Normalize();
            rb.AddForce(direction * bounceForce, ForceMode.Impulse);
        }
    }
}
Tip: col.rigidbody gives you the Rigidbody of whichever object hit you. col.relativeVelocity.magnitude tells you how fast the collision was — useful for only reacting to hard hits.

 


Example 4: Trigger Changes Other Object's State

Not every trigger needs to use forces or kinematic. You can change almost anything in your scene from a script — a light's color, a Hinge Joint's motor speed, a spring's strength, an object's material, whether an object is active at all.

Some ideas: A sensor that turns on a spinning motor when the ball passes. A checkpoint that changes the color of a light from red to green. A pressure plate that swaps a bouncy material for a slippery one. A trigger that disables an obstacle, opening a clear path for the ball.
using UnityEngine;

public class TriggerStateChange : MonoBehaviour
{
    public HingeJoint motorJoint;      // drag the hinge here
    public float targetMotorSpeed = 200f;

    void OnTriggerEnter(Collider other)
    {
        if (motorJoint != null)
        {
            JointMotor motor = motorJoint.motor;
            motor.targetVelocity = targetMotorSpeed;
            motor.force          = 100f;
            motorJoint.motor     = motor;
            motorJoint.useMotor  = true;
        }
    }
}
Tip: You can also use gameObject.SetActive(false) to make an obstacle disappear entirely, or GetComponent<Renderer>().material.color = Color.green to change a color.

 

 

Step 2: Add Scripts to Your Scene

Now it's your turn!

Your scripts must include at least two of the four interaction types described above. Each script must actually affect the Rude Gold Bug's journey — it should contribute directly or indirectly to the ball's motion through the machine.

  • Create your scripts in a Scripts subfolder inside your Assets folder
  • Attach each script to the appropriate object in your scene
  • Assign any public variables (like target) by dragging objects into the Inspector
  • Use trigger colliders (Is Trigger = true) where your zone should not block movement
  • Test carefully — make sure each script fires at the right moment

 

 

Step 3: Testing and Debugging

Scripts introduce new ways things can go wrong. Follow this process:

    1. Check the Console window for errors — a red error usually means something is null or misnamed
    2. Use Debug.Log("trigger fired!") inside your event method to confirm it is being called
    3. Check that Is Trigger is checked on your trigger collider (and that the other object has a Rigidbody)
    4. If AddForce seems to do nothing, make sure isKinematic is false on the target
    5. Iterate — adjust force values until the motion feels right

 


abc.png Grading

Criteria Letter Grade

Indie Developer

  • Meet all requirements for Extended
  • The overall user experience and appearance of the game has been polished
  • The scene is "gamified" with scoring and a user interface
A++

Extended

  • Meet all requirements for Exceptional
  • User input is required for all elements in the system to be activated (Note: the ball can still reach the end on its own, but some elements will be skipped or not activated)
A+

Exceptional

  • At least 3 scripts are used, covering at least 3 different interaction types
  • Scripts are well-organized, free of console errors, behave predictably and are clearly commented
  • All scripts contribute directly or indirectly to the ball's motion
  • Public variables are used to connect objects via the Inspector
  • At least one script uses ForceMode thoughtfully (Impulse vs. Force vs. Acceleration)
A

Good

  • At least 2 scripts are used, covering at least 2 different interaction types
  • Scripts run without errors and behave predictably
  • All scripts contribute directly or indirectly to the ball's motion
  • Public variables are used to connect objects via the Inspector
B

Reasonable

  • At least 2 scripts are created and attached to objects
  • Scripts fire at the right times, though it may need tuning
  • At least one script contributes directly or indirectly to the ball's motion
  • At least one public variable is used to connect objects via the Inspector
C

Needs Improvement

  • At least 1 script is present and functional
  • Script may not trigger reliably or may have minor errors
  • Script contributes indirectly to the ball's motion
D

Insufficient

  • Incomplete or lacking effort
  • Scripts are missing, non-functional, or cause console errors
  • Scripts do not contribute meaningfully to the scene
F
Scores may be rounded to the nearest whole number.

 


gears.png Tips for Success

  • Start Simple: Create one script at a time and get it working first!
  • Null Checks Matter: Check if (target != null) before using a public variable — unassigned references crash your game.
  • Debug.Log is Your Friend: Add a log message inside event methods while testing so you know exactly when it fires.
  • Force Modes: ForceMode.Impulse for instant kicks, ForceMode.Force for steady pushes, ForceMode.Acceleration to ignore mass.
  • Triggers Need Rigidbodies: OnTriggerEnter only fires if at least one of the two objects has a Rigidbody component.
  • Keep Scripts Focused: One script should do one thing — it is easier to debug and reuse. However, it is okay to use a script with multiple objects if the behavior is exactly the same.

 


◄ 06: Rude Gold Bug (Part 4)
Unit 01 Practice Test ►
You are currently using guest access (Log in)
Get the mobile app
Powered by Moodle