Stash work
This commit is contained in:
9
Assets/Scripts/Minigames/TrashMaze.meta
Normal file
9
Assets/Scripts/Minigames/TrashMaze.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
||||
9
Assets/Scripts/Minigames/TrashMaze/Core.meta
Normal file
9
Assets/Scripts/Minigames/TrashMaze/Core.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
||||
87
Assets/Scripts/Minigames/TrashMaze/Core/PulverController.cs
Normal file
87
Assets/Scripts/Minigames/TrashMaze/Core/PulverController.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
using Core;
|
||||
using UnityEngine;
|
||||
using Input;
|
||||
using AppleHills.Core.Settings;
|
||||
|
||||
namespace Minigames.TrashMaze.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Controls Pulver character movement in the Trash Maze.
|
||||
/// Inherits from BasePlayerMovementController for tap-to-move and hold-to-move.
|
||||
/// Updates global shader properties for vision radius system.
|
||||
/// </summary>
|
||||
public class PulverController : BasePlayerMovementController
|
||||
{
|
||||
public static PulverController Instance { get; private set; }
|
||||
|
||||
[Header("Vision")]
|
||||
[SerializeField] private float visionRadius = 3f;
|
||||
|
||||
// Cached shader property IDs for performance
|
||||
private static readonly int PlayerWorldPosID = Shader.PropertyToID("_PlayerWorldPos");
|
||||
private static readonly int VisionRadiusID = Shader.PropertyToID("_VisionRadius");
|
||||
|
||||
// Public accessors for other systems
|
||||
public static Vector2 PlayerPosition => Instance != null ? Instance.transform.position : Vector2.zero;
|
||||
public static float VisionRadius => Instance != null ? Instance.visionRadius : 3f;
|
||||
|
||||
internal override void OnManagedAwake()
|
||||
{
|
||||
// Singleton pattern
|
||||
if (Instance != null && Instance != this)
|
||||
{
|
||||
Logging.Warning("[PulverController] Duplicate instance detected. Destroying duplicate.");
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
|
||||
Instance = this;
|
||||
|
||||
base.OnManagedAwake();
|
||||
|
||||
Logging.Debug("[PulverController] Initialized");
|
||||
}
|
||||
|
||||
protected override void LoadSettings()
|
||||
{
|
||||
var configs = GameManager.GetSettingsObject<IPlayerMovementConfigs>();
|
||||
_movementSettings = configs.TrashMazeMovement;
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update(); // Call base for movement and animation
|
||||
|
||||
// Update global shader properties for vision system
|
||||
UpdateShaderGlobals();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates global shader properties used by visibility shaders
|
||||
/// </summary>
|
||||
private void UpdateShaderGlobals()
|
||||
{
|
||||
Shader.SetGlobalVector(PlayerWorldPosID, transform.position);
|
||||
Shader.SetGlobalFloat(VisionRadiusID, visionRadius);
|
||||
}
|
||||
|
||||
internal override void OnManagedDestroy()
|
||||
{
|
||||
base.OnManagedDestroy();
|
||||
|
||||
if (Instance == this)
|
||||
{
|
||||
Instance = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set vision radius at runtime
|
||||
/// </summary>
|
||||
public void SetVisionRadius(float radius)
|
||||
{
|
||||
visionRadius = Mathf.Max(0.1f, radius);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
||||
122
Assets/Scripts/Minigames/TrashMaze/Core/TrashMazeController.cs
Normal file
122
Assets/Scripts/Minigames/TrashMaze/Core/TrashMazeController.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
using Core;
|
||||
using Core.Lifecycle;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Minigames.TrashMaze.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Main controller for the Trash Maze minigame.
|
||||
/// Initializes the vision system and manages game flow.
|
||||
/// </summary>
|
||||
public class TrashMazeController : ManagedBehaviour
|
||||
{
|
||||
public static TrashMazeController Instance { get; private set; }
|
||||
|
||||
[Header("Player")]
|
||||
[SerializeField] private PulverController pulverPrefab;
|
||||
[SerializeField] private Transform startPosition;
|
||||
|
||||
[Header("World Settings")]
|
||||
[SerializeField] private Vector2 worldSize = new Vector2(100f, 100f);
|
||||
[SerializeField] private Vector2 worldCenter = Vector2.zero;
|
||||
|
||||
[Header("Exit")]
|
||||
[SerializeField] private Transform exitPosition;
|
||||
|
||||
private PulverController _pulverInstance;
|
||||
private bool _mazeCompleted;
|
||||
|
||||
internal override void OnManagedAwake()
|
||||
{
|
||||
base.OnManagedAwake();
|
||||
|
||||
// Singleton pattern
|
||||
if (Instance != null && Instance != this)
|
||||
{
|
||||
Logging.Warning("[TrashMazeController] Duplicate instance detected. Destroying duplicate.");
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
internal override void OnManagedStart()
|
||||
{
|
||||
base.OnManagedStart();
|
||||
|
||||
Logging.Debug("[TrashMazeController] Initializing Trash Maze");
|
||||
|
||||
InitializeMaze();
|
||||
}
|
||||
|
||||
private void InitializeMaze()
|
||||
{
|
||||
// Set global shader properties for world bounds
|
||||
Shader.SetGlobalVector("_WorldSize", worldSize);
|
||||
Shader.SetGlobalVector("_WorldCenter", worldCenter);
|
||||
|
||||
// Spawn player
|
||||
SpawnPulver();
|
||||
|
||||
Logging.Debug("[TrashMazeController] Trash Maze initialized");
|
||||
}
|
||||
|
||||
private void SpawnPulver()
|
||||
{
|
||||
if (pulverPrefab == null)
|
||||
{
|
||||
Logging.Error("[TrashMazeController] Pulver prefab not assigned!");
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3 spawnPosition = startPosition != null ? startPosition.position : Vector3.zero;
|
||||
_pulverInstance = Instantiate(pulverPrefab, spawnPosition, Quaternion.identity);
|
||||
|
||||
Logging.Debug($"[TrashMazeController] Pulver spawned at {spawnPosition}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when player reaches the maze exit
|
||||
/// </summary>
|
||||
public void OnExitReached()
|
||||
{
|
||||
if (_mazeCompleted)
|
||||
{
|
||||
Logging.Debug("[TrashMazeController] Maze already completed");
|
||||
return;
|
||||
}
|
||||
|
||||
_mazeCompleted = true;
|
||||
|
||||
Logging.Debug("[TrashMazeController] Maze completed! Player reached exit.");
|
||||
|
||||
// TODO: Trigger completion events
|
||||
// - Award booster packs collected
|
||||
// - Open gate for Trafalgar
|
||||
// - Switch control to Trafalgar
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when player collects a booster pack
|
||||
/// </summary>
|
||||
public void OnBoosterPackCollected()
|
||||
{
|
||||
Logging.Debug("[TrashMazeController] Booster pack collected");
|
||||
|
||||
// TODO: Integrate with card album system
|
||||
// CardAlbum.AddBoosterPack();
|
||||
}
|
||||
|
||||
internal override void OnManagedDestroy()
|
||||
{
|
||||
base.OnManagedDestroy();
|
||||
|
||||
if (Instance == this)
|
||||
{
|
||||
Instance = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
||||
9
Assets/Scripts/Minigames/TrashMaze/Objects.meta
Normal file
9
Assets/Scripts/Minigames/TrashMaze/Objects.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
||||
175
Assets/Scripts/Minigames/TrashMaze/Objects/RevealableObject.cs
Normal file
175
Assets/Scripts/Minigames/TrashMaze/Objects/RevealableObject.cs
Normal file
@@ -0,0 +1,175 @@
|
||||
using Core;
|
||||
using Minigames.TrashMaze.Core;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Minigames.TrashMaze.Objects
|
||||
{
|
||||
/// <summary>
|
||||
/// Component for objects that need reveal memory (obstacles, booster packs, treasures).
|
||||
/// Tracks if object has been revealed and updates material properties accordingly.
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(SpriteRenderer))]
|
||||
public class RevealableObject : MonoBehaviour
|
||||
{
|
||||
[Header("Textures")]
|
||||
[SerializeField] private Sprite normalSprite;
|
||||
[SerializeField] private Sprite outlineSprite;
|
||||
|
||||
[Header("Object Type")]
|
||||
[SerializeField] private bool isBoosterPack = false;
|
||||
[SerializeField] private bool isExit = false;
|
||||
|
||||
private SpriteRenderer _spriteRenderer;
|
||||
private Material _instanceMaterial;
|
||||
private bool _hasBeenRevealed = false;
|
||||
private bool _isCollected = false;
|
||||
|
||||
// Material property IDs (cached for performance)
|
||||
private static readonly int IsRevealedID = Shader.PropertyToID("_IsRevealed");
|
||||
private static readonly int IsInVisionID = Shader.PropertyToID("_IsInVision");
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_spriteRenderer = GetComponent<SpriteRenderer>();
|
||||
|
||||
// Create instance material so each object has its own properties
|
||||
if (_spriteRenderer.material != null)
|
||||
{
|
||||
_instanceMaterial = new Material(_spriteRenderer.material);
|
||||
_spriteRenderer.material = _instanceMaterial;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Error($"[RevealableObject] No material assigned to {gameObject.name}");
|
||||
}
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// Initialize material properties
|
||||
if (_instanceMaterial != null)
|
||||
{
|
||||
_instanceMaterial.SetFloat(IsRevealedID, 0f);
|
||||
_instanceMaterial.SetFloat(IsInVisionID, 0f);
|
||||
|
||||
// Set textures if provided
|
||||
if (normalSprite != null)
|
||||
{
|
||||
_instanceMaterial.SetTexture("_MainTex", normalSprite.texture);
|
||||
}
|
||||
if (outlineSprite != null)
|
||||
{
|
||||
_instanceMaterial.SetTexture("_OutlineTex", outlineSprite.texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (_isCollected || _instanceMaterial == null) return;
|
||||
|
||||
// Calculate distance to player
|
||||
float distance = Vector2.Distance(transform.position, PulverController.PlayerPosition);
|
||||
bool isInRadius = distance < PulverController.VisionRadius;
|
||||
|
||||
// Update real-time vision flag
|
||||
_instanceMaterial.SetFloat(IsInVisionID, isInRadius ? 1f : 0f);
|
||||
|
||||
// Set revealed flag (once true, stays true)
|
||||
if (isInRadius && !_hasBeenRevealed)
|
||||
{
|
||||
_hasBeenRevealed = true;
|
||||
_instanceMaterial.SetFloat(IsRevealedID, 1f);
|
||||
|
||||
Logging.Debug($"[RevealableObject] {gameObject.name} revealed!");
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTriggerEnter2D(Collider2D other)
|
||||
{
|
||||
// Check if player is interacting
|
||||
if (other.CompareTag("Player") && _hasBeenRevealed && !_isCollected)
|
||||
{
|
||||
HandleInteraction();
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleInteraction()
|
||||
{
|
||||
if (isBoosterPack)
|
||||
{
|
||||
CollectBoosterPack();
|
||||
}
|
||||
else if (isExit)
|
||||
{
|
||||
ActivateExit();
|
||||
}
|
||||
}
|
||||
|
||||
private void CollectBoosterPack()
|
||||
{
|
||||
_isCollected = true;
|
||||
|
||||
Logging.Debug($"[RevealableObject] Booster pack collected: {gameObject.name}");
|
||||
|
||||
// Notify controller
|
||||
if (TrashMazeController.Instance != null)
|
||||
{
|
||||
TrashMazeController.Instance.OnBoosterPackCollected();
|
||||
}
|
||||
|
||||
// Destroy object
|
||||
Destroy(gameObject);
|
||||
}
|
||||
|
||||
private void ActivateExit()
|
||||
{
|
||||
Logging.Debug($"[RevealableObject] Exit activated: {gameObject.name}");
|
||||
|
||||
// Notify controller
|
||||
if (TrashMazeController.Instance != null)
|
||||
{
|
||||
TrashMazeController.Instance.OnExitReached();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
// Clean up instance material
|
||||
if (_instanceMaterial != null)
|
||||
{
|
||||
Destroy(_instanceMaterial);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if object is currently visible to player
|
||||
/// </summary>
|
||||
public bool IsVisible()
|
||||
{
|
||||
float distance = Vector2.Distance(transform.position, PulverController.PlayerPosition);
|
||||
return distance < PulverController.VisionRadius;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if object has been revealed at any point
|
||||
/// </summary>
|
||||
public bool HasBeenRevealed()
|
||||
{
|
||||
return _hasBeenRevealed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Force reveal the object (for debugging or special cases)
|
||||
/// </summary>
|
||||
public void ForceReveal()
|
||||
{
|
||||
_hasBeenRevealed = true;
|
||||
if (_instanceMaterial != null)
|
||||
{
|
||||
_instanceMaterial.SetFloat(IsRevealedID, 1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
||||
Reference in New Issue
Block a user