using UnityEngine; using UnityEngine.UI; using BrewMonster.Network; using PerfectWorld.Scripts.Managers.BrewMonster.Managers; using PerfectWorld.Scripts.Managers; using CSNetwork.GPDataType; using System.Collections.Generic; using BrewMonster; using TMPro; public class pickupItem : MonoBehaviour { // Singleton instance private static pickupItem _instance; public static pickupItem Instance { get { if (_instance == null) { _instance = FindFirstObjectByType(); if (_instance == null) { // Create a new GameObject with pickupItem component if none exists GameObject pickupManager = new GameObject("PickupManager"); _instance = pickupManager.AddComponent(); DontDestroyOnLoad(pickupManager); } } return _instance; } } // Dictionary to store created cubes with their matter IDs private Dictionary matterCubes = new Dictionary(); // Dictionary to track pending pickups by TID private Dictionary pendingPickups = new Dictionary(); // TID -> MatterID // Set to track items that have been picked up by the player (to prevent respawn) private HashSet pickedUpItems = new HashSet(); // MID of picked up items // Reference to the matter manager private EC_ManMatter matterManager; // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() { // Ensure this is the singleton instance if (_instance == null) { _instance = this; DontDestroyOnLoad(gameObject); } else if (_instance != this) { // If another instance already exists, destroy this one Destroy(gameObject); return; } // Get reference to matter manager if (EC_ManMessageMono.Instance != null) { matterManager = EC_ManMessageMono.Instance.GetECManMatter; } else { Debug.LogError("EC_ManMessageMono.Instance is null - matter manager not available"); } // Subscribe to matter enter world events SubscribeToMatterEvents(); } // Update is called once per frame void Update() { // Check for mouse clicks on cubes if (Input.GetMouseButtonDown(0)) { HandleCubeClick(); } } private void SubscribeToMatterEvents() { // We'll need to hook into the matter manager's events // For now, we'll check for new matters in Update } private void HandleCubeClick() { // Find the main camera Camera mainCamera = Camera.main; if (mainCamera == null) { mainCamera = FindFirstObjectByType(); } if (mainCamera == null) { Debug.LogWarning("No camera found for raycast"); return; } Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if (Physics.Raycast(ray, out hit)) { GameObject clickedObject = hit.collider.gameObject; // Check if the clicked object is one of our matter cubes foreach (var kvp in matterCubes) { if (kvp.Value == clickedObject) { int matterId = kvp.Key; SendPickupCommand(matterId); break; } } } } public void SendPickupCommand(int matterId) { if (matterManager != null) { var matterData = matterManager.GetMatterData(matterId); if (matterData.HasValue) { // Track this pickup request pendingPickups[matterData.Value.tid] = matterId; UnityGameSession.RequestPickupItem(matterData.Value.mid, matterData.Value.tid); Debug.Log($"Pickup request sent for matter - MID: {matterData.Value.mid}, TID: {matterData.Value.tid}"); } else { Debug.LogWarning($"No matter data found for matter ID: {matterId}"); } } else { Debug.LogError("Matter manager is null - cannot send pickup command"); } } public void CreateMatterCube(int matterId) { if (matterManager == null) return; var matterData = matterManager.GetMatterData(matterId); if (!matterData.HasValue) return; // Check if this item was previously picked up by the player if (pickedUpItems.Contains(matterId)) { Debug.Log($"Skipping cube creation for matter {matterId} - item was previously picked up by player"); return; } // Check if cube already exists if (matterCubes.ContainsKey(matterId)) { Debug.Log($"Cube for matter {matterId} already exists"); return; } // Create cube GameObject GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube); cube.name = $"Matter_{matterData.Value.mid}_TID_{matterData.Value.tid}"; cube.transform.localScale = new Vector3(1f, 1f, 1f); // Position the cube based on matter position Vector3 position = new Vector3( matterData.Value.pos.x, matterData.Value.pos.y, matterData.Value.pos.z ); cube.transform.position = position; // Add a collider if it doesn't have one if (cube.GetComponent() == null) { cube.AddComponent(); } // Create text object to display item name above the cube CreateItemNameText(cube, matterData.Value.tid); // Add a script to handle click events MatterCubeClickHandler clickHandler = cube.AddComponent(); clickHandler.Initialize(matterId, this); // Store reference to the cube matterCubes[matterId] = cube; Debug.Log($"Created cube for matter {matterId} at position {position}"); } private void CreateItemNameText(GameObject cube, int tid) { // Create a child GameObject for the text GameObject textObject = new GameObject("ItemNameText"); textObject.transform.SetParent(cube.transform); // Position the text above the cube textObject.transform.localPosition = new Vector3(0, 1.2f, 0); // Above the cube // Add TextMeshPro component TextMeshPro textMesh = textObject.AddComponent(); // Get the item name string itemName = EC_IvtrItem.ResolveItemName(tid); if (string.IsNullOrEmpty(itemName)) { itemName = $"Item {tid}"; } // Configure the text textMesh.text = itemName; textMesh.fontSize = 10f; textMesh.color = Color.white; textMesh.alignment = TextAlignmentOptions.Center; // Make the text face the camera textObject.AddComponent(); // Add a background for better visibility GameObject background = new GameObject("TextBackground"); background.transform.SetParent(textObject.transform); background.transform.localPosition = Vector3.zero; background.transform.localScale = new Vector3(2f, 0.8f, 0.1f); // Add a simple quad renderer for background MeshRenderer bgRenderer = background.AddComponent(); MeshFilter bgFilter = background.AddComponent(); // Create a simple quad mesh for the background Mesh quadMesh = new Mesh(); quadMesh.vertices = new Vector3[] { new Vector3(-0.5f, -0.5f, 0), new Vector3(0.5f, -0.5f, 0), new Vector3(0.5f, 0.5f, 0), new Vector3(-0.5f, 0.5f, 0) }; quadMesh.triangles = new int[] { 0, 1, 2, 0, 2, 3 }; quadMesh.uv = new Vector2[] { new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1) }; quadMesh.RecalculateNormals(); bgFilter.mesh = quadMesh; // Create a simple material for the background Material bgMaterial = new Material(Shader.Find("Standard")); bgMaterial.color = new Color(0, 0, 0, 0.7f); // Semi-transparent black bgRenderer.material = bgMaterial; Debug.Log($"Created item name text for TID {tid}: {itemName}"); } public void RemoveMatterCube(int matterId) { if (matterCubes.ContainsKey(matterId)) { GameObject cube = matterCubes[matterId]; if (cube != null) { Destroy(cube); } matterCubes.Remove(matterId); Debug.Log($"Removed cube for matter {matterId}"); } } public void UpdateMatterCubes() { if (matterManager == null) return; // Get all current matter IDs int[] allMatterIds = matterManager.GetAllMatterIds(); // Create cubes for new matters (but skip items previously picked up by player) foreach (int matterId in allMatterIds) { if (!matterCubes.ContainsKey(matterId) && !pickedUpItems.Contains(matterId)) { CreateMatterCube(matterId); } } // Remove cubes for matters that no longer exist List cubesToRemove = new List(); foreach (var kvp in matterCubes) { if (!matterManager.HasMatterData(kvp.Key)) { cubesToRemove.Add(kvp.Key); } } foreach (int matterId in cubesToRemove) { RemoveMatterCube(matterId); } } /// /// Called when a pickup is successful. Removes the cube for the picked up item. /// /// Template ID of the picked up item public void OnPickupSuccess(int tid) { if (pendingPickups.ContainsKey(tid)) { int matterId = pendingPickups[tid]; // Track this item as picked up by the player pickedUpItems.Add(matterId); // Remove the cube RemoveMatterCube(matterId); // Remove from pending pickups pendingPickups.Remove(tid); Debug.Log($"Successfully picked up item with TID: {tid}, removed cube for matter ID: {matterId}"); } else { Debug.LogWarning($"Received pickup success for TID {tid} but no pending pickup found"); } } /// /// Called when a pickup fails. Removes the pending pickup tracking. /// /// Template ID of the failed pickup public void OnPickupFailed(int tid) { if (pendingPickups.ContainsKey(tid)) { pendingPickups.Remove(tid); Debug.Log($"Pickup failed for TID: {tid}, removed from pending pickups"); } } /// /// Clears the tracking of picked up items. Call this when player changes areas or logs out. /// public void ClearPickedUpItemsTracking() { pickedUpItems.Clear(); Debug.Log("Cleared picked up items tracking"); } /// /// Gets the count of items that have been picked up by the player. /// /// Number of items picked up public int GetPickedUpItemsCount() { return pickedUpItems.Count; } private void OnDestroy() { // Clean up all matter cubes foreach (var kvp in matterCubes) { if (kvp.Value != null) { Destroy(kvp.Value); } } matterCubes.Clear(); // Clean up pending pickups pendingPickups.Clear(); // Clean up picked up items tracking pickedUpItems.Clear(); } } // Helper class to handle click events on matter cubes public class MatterCubeClickHandler : MonoBehaviour { private int matterId; private pickupItem pickupItemScript; public void Initialize(int id, pickupItem script) { matterId = id; pickupItemScript = script; } private void OnMouseDown() { if (pickupItemScript != null) { pickupItemScript.SendPickupCommand(matterId); } } } // Simple Billboard component to make text always face the camera public class Billboard : MonoBehaviour { private Camera mainCamera; void Start() { mainCamera = Camera.main; if (mainCamera == null) { mainCamera = FindFirstObjectByType(); } } void Update() { if (mainCamera != null) { // Make the text face the camera transform.LookAt(mainCamera.transform); transform.Rotate(0, 180, 0); // Flip to face the camera properly } } }