CTIN 289 - Interactive Snippets Library

Powered by 🌱Roam Garden

InteractionManager.cs

This script is an Interaction Manager that handles interactions between the player and nearby objects. It checks if the player is close to any interactable objects and updates their interaction states accordingly. The primary functions of this script are:

Awake(): Initializes references to other components, in this case, the PlayerController.

Update(): Calls the CheckRadius() function every frame to check for interactable objects within the defined interaction radius.

CheckRadius(): Performs several tasks:

Determines the player's position and calculates the interaction sphere's origin.

Resets the interaction state of previously detected interactable objects.

Populates a list of interactable objects within the interaction radius and calculates their distances to the player.

Finds the closest interactable object and updates its interaction state based on its type (e.g., Pickup or Crank).

Updates the PlayerController's nearInteractable property based on the presence of interactable objects within the radius.

OnDrawGizmos(): Draws a wireframe sphere in the Unity editor to visualize the interaction radius, helping developers fine-tune the interaction system during development.

using UnityEngine;
using System.Collections.Generic;

public class InteractionManager : MonoBehaviour
{
    public bool isInteracting = false;
    public float interactionRadiusSize = 1.5f;
    private float height = 2.75f;
    private int interactionLayerNumberInUnityEditor = 6;
    private List<GameObject> previousInteractables = new List<GameObject>();
    private PlayerController playerController;

    // Initialize references to other components
    private void Awake()
    {
        playerController = GetComponent<PlayerController>();
    }

    // Check for interactable objects every frame
    private void Update()
    {
        CheckRadius();
    }

    // Check the interaction radius for interactable objects
    private void CheckRadius()
    {
        Vector3 position = this.transform.position + new Vector3(0, height / 2, 0);

        List<GameObject> interactables = new List<GameObject>();
        List<float> interactableDistances = new List<float>();

        int layerMask = 1 << interactionLayerNumberInUnityEditor;

        Collider[] hitColliders = Physics.OverlapSphere(position, interactionRadiusSize, layerMask);

        // Reset the interaction state of previously detected interactable objects
        foreach (GameObject interactable in previousInteractables)
        {
            Pickup pickupComponent = interactable.GetComponent<Pickup>();
            if (pickupComponent != null)
            {
                pickupComponent.canPickup = false;
            }

            Crank crankComponent = interactable.GetComponent<Crank>();
            if (crankComponent != null)
            {
                crankComponent.canCrank = false;
            }
        }

        previousInteractables.Clear();

        // Populate the list of interactable objects within the interaction radius
        foreach (Collider hit in hitColliders)
        {
            if (hit.gameObject.layer == interactionLayerNumberInUnityEditor)
            {
                float distanceToInteractable = Vector3.Distance(position, hit.transform.position);
                
                interactables.Add(hit.gameObject);
                Debug.Log("Added GameObject to interactables list: " + hit.gameObject.name);

                interactableDistances.Add(distanceToInteractable);

                previousInteractables.Add(hit.gameObject);
            }
        }

        // Determine the closest interactable object and set its interaction state
        if (interactableDistances.Count > 0)
        {
            int minDistanceIndex = 0;
            float minDistance = interactableDistances[0];

            for (int i = 0; i < interactableDistances.Count; i++)
            {
                if (interactableDistances[i] < minDistance)
                {
                    minDistance = interactableDistances[i];
                    minDistanceIndex = i;
                }
            }

            playerController.nearInteractable = true;

            Pickup pickupComponent = interactables[minDistanceIndex].GetComponent<Pickup>();
            if (pickupComponent != null)
            {
                pickupComponent.canPickup = true;
            }

            Crank crankComponent = interactables[minDistanceIndex].GetComponent<Crank>();
            if (crankComponent != null)
            {
                crankComponent.canCrank = true;
            }
        }
        else
        {
            playerController.nearInteractable = false;
        }
    }

    // Draw a wireframe sphere in the Unity editor to visualize the interaction radius
    private void OnDrawGizmos()
    {
        Gizmos.color = Color.red;

        Vector3 position = this.transform.position + new Vector3(0, height / 2, 0);
        Gizmos.DrawWireSphere(position, interactionRadiusSize);
    }
}