Unity3D: Creating a Mechanic to Inspect Objects in World Space
Recently I started coding systems for a “Backrooms”-like horror game about mental health issues. The game is in Unity, and required a system that is all too familiar in these horror games: to be able to pick up any object, and rotate it so you can inspect every inch for clues!
Today we’re going to apply what I’ve learned into a simple, practical example that you will be able to drag into an empty scene in Unity and try yourself!
Let’s outline what we’ll need to accomplish this:
Unity Editor ( v2021.3.9f1 for this example )
An out-of-the-box or custom model that you can place in a scene
A custom script called “Inspector”
Setting up the scene
The first step we’ll take is setting up our scene with an object to interact with.
Opening our scene and dropping in a standard cube is all we’re going to need for this example, but if you are feeling like you want something better to look at feel free to drop in any object you like! It does not matter in this context.
As always, our Unity scene comes shipped with a directional light and a camera so that we can see what we’re doing when we hit play.
Writing the Interactor Script
With the object in place, we’ll need to think about how we want this script to function. Let’s establish some acceptance criteria for our code:
Acceptance Criteria
Uses legacy unity input system ( for ease of use )
Allow editor control of object distance to the camera during inspection
The mouse movement should rotate the object on its global center axis ( x, y, and z coordinates )
Allow edit control of the rotation speed of the object
With our acceptance criteria, now we won’t get lost when creating our script, and if we were in a team environment, this would also serve as a handy list for the QA team!
Let’s first set up our class with the expected variables we want manage-able through the Unity editor:
public class Inspector : MonoBehaviour
{
// The object to be inspected
public GameObject inspectedObject;
// The distance to place the object in front of the camera
public float distance = 2.0f;
// The sensitivity of the mouse rotation
public float sensitivity = 2.0f;
}
First, inspectedObject, will hold a reference in memory to the object in the scene that we want to inspect.
Second, distance will control how close the object is to the camera so we can make sure it fits into the screen.
Lastly, sensitivity will control the speed at which the object rotates based on the Vector3 ( x, y, z ) position of the mouse as it moves around the screen.
These changes satisfy the acceptance criteria partially, allowing the variables we want editable to be visible in the component on the object, for example:
Next, we’ll want to write some code that will capture both the X and Y coordinates of the player’s mouse on the screen so that we can use it in our calculations to rotate our inspectedObject.
The basic idea is that we will rotate the object on its X axis based on the coordinate X of the mouse position, and inversely rotate the object on the Y axes based on coordinate Y.
Let’s set it up!
Finally, we can add our script to our game object in the scene.
Once added, we can start the game and experiment with the component inputs in the editor to change the behavior, like so:
As you can see, it does not take much to start to emulate the behavior we typically see when inspecting objects in our favorite horror games.
Of course, this is a simple example, but I challenge you to expand this yourself!
Have the player check the area for inspectable objects, and select before inspecting
Have inspectable objects highlight with a red outline when player is looking at it
Here is the finalized script in all its glory, drop it in and have fun!!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Inspector : MonoBehaviour
{
// The object to be inspected
public GameObject inspectedObject;
// The distance to place the object in front of the camera
public float distance = 2.0f;
// The sensitivity of the mouse rotation
public float sensitivity = 2.0f;
void Update()
{
// Get the current mouse position
float mouseX = Input.GetAxis("Mouse X");
float mouseY = Input.GetAxis("Mouse Y");
// Rotate the object around its y-axis
inspectedObject.transform.Rotate(new Vector3(0, mouseX * sensitivity, 0));
// Rotate the object around its x-axis
inspectedObject.transform.Rotate(new Vector3(-mouseY * sensitivity, 0, 0));
// Place the object in front of the camera
inspectedObject.transform.position = Camera.main.transform.position + Camera.main.transform.forward * distance;
}
}