ScriptBundle

 avatar
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...