Rework interactables into a flatter hierarchy, reenable puzzles as well

This commit is contained in:
Michal Pikulski
2025-09-11 13:00:26 +02:00
parent 3a40d1a151
commit e1ff13db30
32 changed files with 981 additions and 1018 deletions

View File

@@ -1,115 +1,95 @@
using Input;
using UnityEngine;
public class Pickup : MonoBehaviour
namespace Interactions
{
/// <summary>
/// Data for the pickup item (icon, name, etc).
/// </summary>
public PickupItemData itemData;
/// <summary>
/// Renderer for the pickup icon.
/// </summary>
public SpriteRenderer iconRenderer;
private Interactable interactable;
/// <summary>
/// Unity Awake callback. Sets up icon, interactable, and event handlers.
/// </summary>
void Awake()
[RequireComponent(typeof(Interactable))]
public class Pickup : MonoBehaviour
{
if (iconRenderer == null)
iconRenderer = GetComponent<SpriteRenderer>();
interactable = GetComponent<Interactable>();
if (interactable != null)
public PickupItemData itemData;
public SpriteRenderer iconRenderer;
protected Interactable Interactable;
private PlayerTouchController _playerRef;
protected FollowerController FollowerController;
/// <summary>
/// Unity Awake callback. Sets up icon, interactable, and event handlers.
/// </summary>
void Awake()
{
interactable.StartedInteraction += OnStartedInteraction;
interactable.InteractionComplete += OnInteractionComplete;
}
ApplyItemData();
}
if (iconRenderer == null)
iconRenderer = GetComponent<SpriteRenderer>();
Interactable = GetComponent<Interactable>();
if (Interactable != null)
{
Interactable.interactionStarted.AddListener(OnInteractionStarted);
Interactable.characterArrived.AddListener(OnCharacterArrived);
}
/// <summary>
/// Unity OnDestroy callback. Cleans up event handlers.
/// </summary>
void OnDestroy()
{
if (interactable != null)
{
interactable.StartedInteraction -= OnStartedInteraction;
interactable.InteractionComplete -= OnInteractionComplete;
ApplyItemData();
}
/// <summary>
/// Unity OnDestroy callback. Cleans up event handlers.
/// </summary>
void OnDestroy()
{
if (Interactable != null)
{
Interactable.interactionStarted.RemoveListener(OnInteractionStarted);
Interactable.characterArrived.RemoveListener(OnCharacterArrived);
}
}
}
#if UNITY_EDITOR
/// <summary>
/// Unity OnValidate callback. Ensures icon and data are up to date in editor.
/// </summary>
void OnValidate()
{
if (iconRenderer == null)
iconRenderer = GetComponent<SpriteRenderer>();
ApplyItemData();
}
/// <summary>
/// Draws gizmos for pickup interaction range in the editor.
/// </summary>
void OnDrawGizmos()
{
float playerStopDistance;
if (Application.isPlaying)
/// <summary>
/// Unity OnValidate callback. Ensures icon and data are up to date in editor.
/// </summary>
void OnValidate()
{
playerStopDistance = GameManager.Instance.PlayerStopDistance;
if (iconRenderer == null)
iconRenderer = GetComponent<SpriteRenderer>();
ApplyItemData();
}
else
{
// Load settings directly from asset path in editor
var settings = UnityEditor.AssetDatabase.LoadAssetAtPath<GameSettings>("Assets/Data/Settings/DefaultSettings.asset");
playerStopDistance = settings != null ? settings.playerStopDistance : 1.0f;
}
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(transform.position, playerStopDistance);
GameObject playerObj = GameObject.FindGameObjectWithTag("Player");
if (playerObj != null)
{
Vector3 stopPoint = transform.position + (playerObj.transform.position - transform.position).normalized * playerStopDistance;
Gizmos.color = Color.cyan;
Gizmos.DrawSphere(stopPoint, 0.15f);
}
}
#endif
/// <summary>
/// Applies the item data to the pickup (icon, name, etc).
/// </summary>
public void ApplyItemData()
{
if (itemData != null)
/// <summary>
/// Applies the item data to the pickup (icon, name, etc).
/// </summary>
public void ApplyItemData()
{
if (iconRenderer != null && itemData.mapSprite != null)
if (itemData != null)
{
iconRenderer.sprite = itemData.mapSprite;
if (iconRenderer != null && itemData.mapSprite != null)
{
iconRenderer.sprite = itemData.mapSprite;
}
gameObject.name = itemData.itemName;
}
gameObject.name = itemData.itemName;
}
/// <summary>
/// Handles the start of an interaction (for feedback/UI only).
/// </summary>
private void OnInteractionStarted(PlayerTouchController playerRef, FollowerController followerRef)
{
_playerRef = playerRef;
FollowerController = followerRef;
}
protected virtual void OnCharacterArrived()
{
var combinationResult = FollowerController.TryCombineItems(this, out var combinationResultItem);
if (combinationResultItem != null)
{
Interactable.BroadcastInteractionComplete(true);
return;
}
FollowerController?.TryPickupItem(gameObject, itemData);
Interactable.BroadcastInteractionComplete(combinationResult == FollowerController.CombinationResult.NotApplicable);
}
}
/// <summary>
/// Handles the start of an interaction (for feedback/UI only).
/// </summary>
private void OnStartedInteraction()
{
// Optionally, add pickup-specific feedback here (e.g., highlight, sound).
}
/// <summary>
/// Handles completion of the interaction (e.g., after pickup is done).
/// </summary>
/// <param name="success">Whether the interaction was successful.</param>
private void OnInteractionComplete(bool success)
{
if (!success) return;
// Optionally, add logic to disable the pickup or provide feedback
}
}
}