ScriptBundle
unknown
plain_text
2 years ago
25 kB
5
Indexable
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public class GameController : MonoBehaviour { public static GameController instance; public GameObject parentGameObject; // You'll set this in the Unity Editor. public Slot[] slots; private List<Slot> sortedSlots; private Vector3 _target; private Item carryingItem; private Dictionary<int, Slot> slotDictionary; public GridGenerator gridGenerator; private Vector3 previousCameraPosition; private Quaternion previousCameraRotation; private float updateThreshold = 1f; // Update the slots if the camera has moved or rotated more than this amount public Vector3 itemOffset = new Vector3(0, 5f, 0); private void Awake() { instance = this; // Utils.InitResources(); } private void Start() { previousCameraPosition = Camera.main.transform.position; previousCameraRotation = Camera.main.transform.rotation; UpdateSlots(); } public void UpdateSlots() { slots = parentGameObject.GetComponentsInChildren<Slot>(); slotDictionary = new Dictionary<int, Slot>(); // Copy the array to a list for easier manipulation sortedSlots = new List<Slot>(); // Get the camera's frustum planes Plane[] planes = GeometryUtility.CalculateFrustumPlanes(Camera.main); foreach (Slot slot in slots) { // Get the renderer component of the slot Renderer renderer = slot.GetComponent<Renderer>(); // Check if the renderer's bounds are in the camera's frustum if (renderer != null && GeometryUtility.TestPlanesAABB(planes, renderer.bounds)) { // If the slot is in the camera's frustum, add it to the sortedSlots list sortedSlots.Add(slot); } } // Get the camera position Vector3 cameraPosition = Camera.main.transform.position; // Sort the slots by their distance from the camera sortedSlots.Sort((slot1, slot2) => { float distance1 = Vector3.Distance(cameraPosition, slot1.transform.position); float distance2 = Vector3.Distance(cameraPosition, slot2.transform.position); return distance1.CompareTo(distance2); }); for (int i = 0; i < sortedSlots.Count; i++) { sortedSlots[i].id = i; slotDictionary.Add(i, sortedSlots[i]); } } public bool IsDraggingItem() { return carryingItem != null; } private bool isDragging = false; // Add this line at the top of the GameController class private Coroutine dragCoroutine; // Add this line at the top of the GameController class private void Update() { if (Vector3.Distance(Camera.main.transform.position, previousCameraPosition) > updateThreshold || Quaternion.Angle(Camera.main.transform.rotation, previousCameraRotation) > updateThreshold) { UpdateSlots(); previousCameraPosition = Camera.main.transform.position; previousCameraRotation = Camera.main.transform.rotation; } if (Input.GetMouseButtonDown(0)) { dragCoroutine = StartCoroutine(DragDelay()); } if (Input.GetMouseButtonUp(0)) { if (dragCoroutine != null) { StopCoroutine(dragCoroutine); dragCoroutine = null; } if (isDragging) // If a drag was detected, reset the flag and don't process the tap { isDragging = false; SendRayCast(); } else { // Process the tap here } } if (isDragging && carryingItem) { OnItemSelected(); } if (Input.GetKeyDown(KeyCode.Space)) { PlaceRandomItem(); } } IEnumerator DragDelay() { yield return new WaitForSeconds(0.075f); // Wait for 150ms before starting the drag isDragging = true; SendRayCast(); } void SendRayCast() { RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero); // We hit something if(hit.collider != null) { // We are grabbing the item in a full slot var slot = hit.transform.GetComponent<Slot>(); if (slot.state == SlotState.Full && carryingItem == null && isDragging) // Only pick up the item if a drag is detected { carryingItem = slot.currentItem; carryingItem.transform.localScale = Vector3.one * 1.3f; slot.currentItem = null; slot.state = SlotState.Empty; } // We are dropping an item to empty slot else if (slot.state == SlotState.Empty && carryingItem != null) { carryingItem.transform.SetParent(slot.transform); carryingItem.transform.position = slot.transform.position + itemOffset; carryingItem.transform.localScale = Vector3.one; slot.currentItem = carryingItem; slot.state = SlotState.Full; carryingItem = null; } // We are dropping to full else if (slot.state == SlotState.Full && carryingItem != null) { // Check item in the slot if (slot.currentItem.id == carryingItem.id && carryingItem.Mergeable) { print("merged"); OnItemMergedWithTarget(slot.id); } else { OnItemCarryFail(); } } } else { if (!carryingItem) { return; } OnItemCarryFail(); } } void OnItemSelected() { _target = Camera.main.ScreenToWorldPoint(Input.mousePosition); _target.z = 0; var delta = 10 * Time.deltaTime; delta *= Vector3.Distance(transform.position, _target); carryingItem.transform.position = Vector3.MoveTowards(carryingItem.transform.position, _target, delta); } void OnItemMergedWithTarget(int targetSlotId) { var slot = GetSlotById(targetSlotId); // Destroy the original item if (slot.currentItem != null) { Destroy(slot.currentItem.gameObject); } // Create the new item slot.CreateItem(carryingItem.id + 1); // Destroy the carrying item if (carryingItem != null) { Destroy(carryingItem.gameObject); } } void OnItemCarryFail() { if (carryingItem != null && carryingItem.parentSlot != null) { StartCoroutine(MoveItemToSlot(carryingItem, carryingItem.parentSlot)); } carryingItem = null; } IEnumerator MoveItemToSlot(Item item, Slot slot) { float duration = 0.25f; // Duration of the movement in seconds float elapsed = 0f; Vector3 startPosition = item.transform.position; Vector3 endPosition = slot.transform.position + itemOffset; while (elapsed < duration) { elapsed += Time.deltaTime; float t = elapsed / duration; item.transform.position = Vector3.Lerp(startPosition, endPosition, t); yield return null; } // Ensure the item is exactly at the end position when the movement is done item.transform.position = endPosition; item.transform.localScale = Vector3.one; slot.currentItem = item; slot.state = SlotState.Full; } IEnumerator RevealOriginalItem() { var slot = GetSlotById(carryingItem.id); float duration = 0.25f; // The duration of the movement float elapsed = 0; Vector3 originalScale = carryingItem.transform.localScale; Vector3 targetScale = Vector3.one; // The original item's scale while (elapsed < duration) { carryingItem.transform.position = Vector3.Lerp(carryingItem.transform.position + itemOffset, slot.transform.position + itemOffset, elapsed / duration); carryingItem.transform.localScale = Vector3.Lerp(originalScale, targetScale, elapsed / duration); elapsed += Time.deltaTime; yield return null; } Destroy(carryingItem.gameObject); slot.ItemReturned(); } void PlaceRandomItem() { if (AllSlotsOccupied()) { Debug.Log("No empty slot available!"); return; } // Get the mouse position in world coordinates Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition); mousePosition.z = 0; // Find the slot closest to the mouse position Slot closestSlot = null; float closestDistance = float.MaxValue; foreach (Slot slot in sortedSlots) { if (slot.state == SlotState.Empty) { float distance = Vector3.Distance(mousePosition, slot.transform.position); if (distance < closestDistance) { closestDistance = distance; closestSlot = slot; } } } // If a closest slot was found, create an item there if (closestSlot != null) { int randomItem = RandomNumberBetween(1, 3, 6); closestSlot.CreateItem(randomItem); } } private int RandomNumberBetween(params int[] numbers) { int randomIndex = UnityEngine.Random.Range(0, numbers.Length); return numbers[randomIndex]; } bool AllSlotsOccupied() { foreach (var slot in slots) { if (slot.state == SlotState.Empty) { //empty slot found return false; } } //no slot empty return true; } Slot GetSlotById(int id) { return slotDictionary[id]; } } using UnityEngine; [System.Serializable] public class Item : MonoBehaviour { public int id; public string Name; public string Description; public string SpriteName; public int ChainID; public Sprite Sprite; public Slot parentSlot; public SpriteRenderer visualRenderer; public bool Mergeable; public bool IsCrafter; public void Init(int id, Slot slot) { this.id = id; this.parentSlot = slot; LoadSprite(); } public void Init(int id) { this.id = id; } private void LoadSprite() { Sprite = Resources.Load<Sprite>("Sprites/" + SpriteName); visualRenderer.sprite = Sprite; } } using System.Collections; using System.Collections.Generic; using UnityEngine; using System.IO; using Newtonsoft.Json; public class Slot : MonoBehaviour { public int id; public Item currentItem; public SlotState state = SlotState.Empty; public Vector3 itemOffset = new Vector3(0, 5f, 0); string LoadJsonFile(string filePath) { string json = ""; try { using (StreamReader reader = new StreamReader(filePath)) { json = reader.ReadToEnd(); } } catch (System.Exception e) { Debug.LogError("Failed to load JSON file: " + filePath + ", Error: " + e.Message); } return json; } public void CreateItem(int itemId) { string json = File.ReadAllText("Assets/Resources/itemDatabase.json"); var wrapper = new { items = new List<Item>() }; var result = JsonConvert.DeserializeAnonymousType(json, wrapper); List<Item> items = result.items; GameObject itemGO = Instantiate(Resources.Load<GameObject>("Item"), transform.position + itemOffset + new Vector3(0, 0.25f, 0), Quaternion.identity, transform); Item item = itemGO.GetComponent<Item>(); if (items != null && items.Count > 0) { foreach (Item itemData in items) { if (itemData.id == itemId) { item.Name = itemData.Name; Debug.Log(item.Name); item.SpriteName = itemData.SpriteName; Debug.Log(item.SpriteName); item.Mergeable = itemData.Mergeable; item.IsCrafter = itemData.IsCrafter; break; } } if (item != null) { if (item != null) { item.Init(itemId, this); item.transform.position = transform.position + itemOffset; item.transform.SetParent(transform); currentItem = item; state = SlotState.Full; // item.Name = itemData.Name; // item.SpriteName = itemData.SpriteName; StartCoroutine(MoveAndScaleItem(item, transform.position + itemOffset)); } else { Debug.LogWarning("Failed to retrieve Item component."); } } else { Debug.LogWarning("Item with ID " + itemId + " not found in the ItemDatabase."); } } else { Debug.LogWarning("Failed to deserialize JSON into Item list."); } } IEnumerator MoveAndScaleItem(Item item, Vector3 endPosition) { float duration = 0.15f; // Duration of the animation in seconds float elapsed = 0f; Vector3 startPosition = item.transform.position; Vector3 startScale = item.transform.localScale * 1.5f; // Start with a scale 1.5 times the original Vector3 endScale = Vector3.one; while (elapsed < duration) { elapsed += Time.deltaTime; float t = elapsed / duration; item.transform.position = Vector3.Lerp(startPosition, endPosition+itemOffset , t); item.transform.localScale = Vector3.Lerp(startScale, endScale, t); yield return null; } // Ensure the item is exactly at the end position and has the correct scale when the animation is done item.transform.position = endPosition; item.transform.localScale = endScale; } private void ChangeStateTo(SlotState targetState) { state = targetState; } public void ItemGrabbed() { if (currentItem != null) { currentItem.gameObject.SetActive(false); } } public void ItemReturned() { if (currentItem != null) { currentItem.gameObject.SetActive(true); currentItem.transform.position = transform.position + itemOffset; } } public void ClearSlot() { currentItem = null; state = SlotState.Empty; } private void ReceiveItem(int id) { switch (state) { case SlotState.Empty: CreateItem(id); ChangeStateTo(SlotState.Full); break; case SlotState.Full: if (currentItem.id == id) { //Merged Debug.Log("Merged"); } else { //Push item back Debug.Log("Push back"); } break; } } } public enum SlotState { Empty, Full } using UnityEngine; public class CameraController : MonoBehaviour { public float panSpeed = 20f; public float zoomSpeed = 2f; public float minX, maxX, minY, maxY; // Define these values based on your grid size public float minZoom, maxZoom; private Camera cam; private Vector3 lastPanPosition; private int panFingerId; // Touch mode only private bool wasZoomingLastFrame; // Touch mode only private Vector2[] lastZoomPositions; // Touch mode only public float panMargin = 0.1f; // Margin for triggering panning while dragging an object, as a fraction of the viewport size void Awake() { cam = GetComponent<Camera>(); } void Update() { if (Input.touchSupported && Application.platform != RuntimePlatform.WebGLPlayer) { HandleTouch(); } else { HandleMouse(); } } void HandleMouse() { // On mouse down, capture its position. if (Input.GetMouseButtonDown(0)) { lastPanPosition = Input.mousePosition; } // Only move camera if mouse button is down if (Input.GetMouseButton(0)) { if (GameController.instance.IsDraggingItem()) { // If an item is being dragged, only pan the camera if the mouse position is within the pan margin of the viewport edges Vector3 mousePosition = Input.mousePosition; Vector3 viewportPosition = Camera.main.ScreenToViewportPoint(mousePosition); if (viewportPosition.x < panMargin || viewportPosition.x > 1 - panMargin || viewportPosition.y < panMargin || viewportPosition.y > 1 - panMargin) { PanCamera(mousePosition); } } else { // If the mouse has moved a significant distance, pan the camera if (Vector3.Distance(Input.mousePosition, lastPanPosition) > 10) // Change this value to adjust the sensitivity { PanCamera(Input.mousePosition); } } } // Update lastPanPosition when mouse button is released if (Input.GetMouseButtonUp(0)) { lastPanPosition = Input.mousePosition; } // Check for scrolling to zoom the camera if (!GameController.instance.IsDraggingItem()) { // Only zoom the camera if no item is being dragged float scroll = Input.GetAxis("Mouse ScrollWheel"); ZoomCamera(scroll, zoomSpeed); } } void HandleTouch() { switch (Input.touchCount) { case 1: // Panning wasZoomingLastFrame = false; // If the touch began, capture its position. if (Input.GetTouch(0).phase == TouchPhase.Began) { lastPanPosition = Input.GetTouch(0).position; } if (Input.GetTouch(0).phase == TouchPhase.Moved) { if (GameController.instance.IsDraggingItem()) { // If an item is being dragged, only pan the camera if the touch position is within the pan margin of the viewport edges Vector3 touchPosition = Input.GetTouch(0).position; Vector3 viewportPosition = Camera.main.ScreenToViewportPoint(touchPosition); if (viewportPosition.x < panMargin || viewportPosition.x > 1 - panMargin || viewportPosition.y < panMargin || viewportPosition.y > 1 - panMargin) { //PanCamera(touchPosition); } } else { PanCamera(Input.GetTouch(0).position); } } // Update lastPanPosition when the touch ends if (Input.GetTouch(0).phase == TouchPhase.Ended) { lastPanPosition = Input.GetTouch(0).position; } break; case 2: // Zooming Vector2[] newPositions = new Vector2[]{Input.GetTouch(0).position, Input.GetTouch(1).position}; if (!wasZoomingLastFrame) { lastZoomPositions = newPositions; wasZoomingLastFrame = true; } else { // Zoom based on the distance between the new positions compared to the // distance between the previous positions. float newDistance = Vector2.Distance(newPositions[0], newPositions[1]); float oldDistance = Vector2.Distance(lastZoomPositions[0], lastZoomPositions[1]); float offset = newDistance - oldDistance; ZoomCamera(offset, zoomSpeed); lastZoomPositions = newPositions; } break; } } void PanCamera(Vector3 newPanPosition) { // Determine how much to move the camera Vector3 offset = cam.ScreenToViewportPoint(newPanPosition - lastPanPosition); Vector3 move; if (GameController.instance.IsDraggingItem()) { // If an item is being dragged, pan the camera in the same direction as the drag move = new Vector3(offset.x * panSpeed * cam.orthographicSize, offset.y * panSpeed * cam.orthographicSize, 0); } else { // If no item is being dragged, pan the camera in the opposite direction of the drag move = new Vector3(-offset.x * panSpeed * cam.orthographicSize, -offset.y * panSpeed * cam.orthographicSize, 0); } // Perform the movement transform.Translate(move, Space.World); // Ensure the camera remains within bounds. Vector3 pos = transform.position; pos.x = Mathf.Clamp(transform.position.x, minX, maxX); pos.y = Mathf.Clamp(transform.position.y, minY, maxY); transform.position = pos; // Cache the position lastPanPosition = newPanPosition; } void ZoomCamera(float offset, float speed) { if (offset == 0) { return; } cam.orthographicSize = Mathf.Clamp(cam.orthographicSize - (offset * speed), minZoom, maxZoom); } } { "items": [ { "id": 0, "Name": "Item 1", "Description": "Description for Item 1", "SpriteName": "cauldron", "ChainID": 0, "Mergeable": true, "IsCrafter": true, "StoredItemId": -1, "SpawnItemId": -1, "SpawnAmount": 0, "TapTimeThreshold": 0 }, { "id": 1, "Name": "Item 2", "Description": "Description for Item 2", "SpriteName": "acorn_gold", "ChainID": 1, "Mergeable": true, "IsCrafter": false, "StoredItemId": -1, "SpawnItemId": 10, "SpawnAmount": 1, "TapTimeThreshold": 0.5 }, { "id": 2, "Name": "Item 3", "Description": "Description for Item 3", "SpriteName": "bettle", "ChainID": 1, "Mergeable": false, "IsCrafter": false, "StoredItemId": -1, "SpawnItemId": -1, "SpawnAmount": 0, "TapTimeThreshold": 0 }, { "id": 3, "Name": "Item 4", "Description": "Description for Item 4", "SpriteName": "black_cherry", "ChainID": 2, "Mergeable": true, "IsCrafter": false, "StoredItemId": -1, "SpawnItemId": 11, "SpawnAmount": 2, "TapTimeThreshold": 0.5 }, { "id": 4, "Name": "Item 5", "Description": "Description for Item 5", "SpriteName": "blood", "ChainID": 2, "Mergeable": true, "IsCrafter": false, "StoredItemId": -1, "SpawnItemId": 12, "SpawnAmount": 3, "TapTimeThreshold": 0.5 }, { "id": 5, "Name": "Item 6", "Description": "Description for Item 6", "SpriteName": "bloodsucker", "ChainID": 2, "Mergeable": false, "IsCrafter": false, "StoredItemId": -1, "SpawnItemId": -1, "SpawnAmount": 0, "TapTimeThreshold": 0 }, { "id": 6, "Name": "Item 7", "Description": "Description for Item 7", "SpriteName": "blue_bread", "ChainID": 3, "Mergeable": true, "IsCrafter": false, "StoredItemId": -1, "SpawnItemId": -1, "SpawnAmount": 0, "TapTimeThreshold": 0 }, { "id": 7, "Name": "Item 8", "Description": "Description for Item 8", "SpriteName": "bones", "ChainID": 3, "Mergeable": true, "IsCrafter": false, "StoredItemId": -1, "SpawnItemId": -1, "SpawnAmount": 0, "TapTimeThreshold": 0 }, { "id": 8, "Name": "Item 9", "Description": "Description for Item 9", "SpriteName": "bones_soup", "ChainID": 3, "Mergeable": false, "IsCrafter": false, "StoredItemId": -1, "SpawnItemId": 13, "SpawnAmount": 2, "TapTimeThreshold": 0.5 } ] }
Editor is loading...