ScriptBundle
unknown
plain_text
2 years ago
25 kB
8
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...