Skip to main content

Player Mouse Movement

Written by: Akram Taghavi-Burris | © Copyright 2024
Status

Game objects controlled by player input are often referred to as the player, and their controls are typically managed by a PlayerController class, which handles broader aspects of a game object’s behavior. One example of such a controller is Unity’s ThirdPersonController. The name ThirdPersonController provides a clearer and more specific description of exactly what the controller does and how it functions. Rather than simply PlayerController, ThirdPersonController indicates that the controls will be from a third-person perspective.

In our collectible game, however, we do not need such board controls, only the ability to move the game object along the X-axis in response to the horizontal position of the mouse cursor.

In addition, this functionality could potentially be applied beyond controlling the player. For instance, you might have features where a troupe of pixies follows the player and moves with the mouse.

FollowMouseX Class

Given the varying use cases and the specific nature of this function, a more descriptive class name is appropriate. We have chosen FollowMouseX, which reflects:

  • Clearly Defined Scope: The name FollowMouseX indicates that the class controls movement along the X-axis only, avoiding broader game object management. This helps maintain a focused responsibility.

  • Avoids Ambiguity: FollowMouseX clearly communicates its purpose without suggesting it handles more than X-axis movement related to the mouse position.

  • Enhances Modularity: The specific name supports modular design by indicating that this class is intended for handling movement, which can be integrated with other components. This promotes better separation of concerns and easier integration.

  • Facilitates Reusability: The focus on X-axis movement makes the class easily reusable for any game object requiring this specific interaction, minimizing confusion and additional modifications.

Defining the Class

Just as our classes should be modular so should our methods. Modular methods is a great idea to improve readability and maintainability. Applying SOLID principles and design patterns can help make the class more flexible and easier to extend or modify.

FollowMouseX Functions

As described earlier we want the class to move the game object along the X-axis in response to the horizontal position of the mouse cursor. To do this we need to break down exactly what we need to do.

The mouse position is in 2D space, so we first need to get the input on the mouses's potion, then we need get the Z postion of the camera and convert this 2D point into a 3D world point.

After we get his information we need to update the object's position to this new x position.

We need to check for changes in the mouse position every frame so naturally the fucntions above should be called in the Update() method.

Assets/Scripts/FollowMouseX.cs
public class FollowMouseX : MonoBehaviour
{
// Update is called once per frame
void Update()
{
Vector3 mousePosition = GetMouseWorldPosition();
UpdateObjectPosition(mousePosition.x);
}//end Update()

private Vector3 GetMouseWorldPosition()
{
// Get the current screen position of the mouse
Vector3 mousePos2D = Input.mousePosition;

// Set the z position based on the camera’s position
mousePos2D.z = -Camera.main.transform.position.z;

// Convert from 2D screen space to 3D world space
return Camera.main.ScreenToWorldPoint(mousePos2D);
}//end GetMouseWorldPosition()

private void UpdateObjectPosition(float xPosition)
{
// Update only the x position of the game object
Vector3 pos = transform.position;
pos.x = xPosition;
transform.position = pos;
}//end UpdateObjectPosition()

}

Implementations of Design Patterns

In building the FollowMouseX class, we’ve implemented several key design patterns to ensure the code is robust, maintainable, and adaptable. These patterns, rooted in the SOLID principles of object-oriented design, help us achieve clear separation of concerns, encapsulation, and extendability. Below, we’ll examine the specific design patterns applied in the FollowMouseX class and how they contribute to creating a clean and modular structure.

  • Encapsulation:

    • GetMouseWorldPosition and UpdateObjectPosition are both private methods and as such their logic is encapsulated in the class. This keeps the Update method clean and makes the class easier to maintain or extend.
  • Single Responsibility Principle (SRP):

    • GetMouseWorldPosition method handles the logic of converting the mouse position from screen space to world space. It focuses solely on this conversion.
    • UpdateObjectPosition method updates the game object’s position. It only modifies the X position based on the given value.
  • Open/Closed Principle (OCP):

    • FollowMouseX class is now more open to extension but closed for modification. If you need to change how the object’s position is updated or how the mouse position is converted, you can modify or extend these methods without altering the overall class logic.
  • Liskov Substitution Principle (LSP):

    • Subclasses or derived classes that inherit from FollowMouseX will still function correctly if they override these methods, as long as they maintain the expected input and output behavior.

    Extending Functionality

    While the FollowMouseX is clear and simple it does not lend itself to further extensions. However, if there