From 76a38d741c64d6e9a20d1e3d2933329ddb0e602f Mon Sep 17 00:00:00 2001 From: krylj Date: Sat, 28 Mar 2026 09:07:10 +0100 Subject: [PATCH] minihra_dira spawnuje itemy a uprostred je dira. cilem je nahazet x veci do diry. desing a smysl motivu je na vas --- Assets/Scripts/hod_veci_do_diry.meta | 8 ++ .../hod_veci_do_diry/DraggableObject.cs | 133 ++++++++++++++++++ .../hod_veci_do_diry/DraggableObject.cs.meta | 2 + Assets/Scripts/hod_veci_do_diry/Hole.cs | 105 ++++++++++++++ Assets/Scripts/hod_veci_do_diry/Hole.cs.meta | 2 + .../Scripts/hod_veci_do_diry/LevelManager.cs | 41 ++++++ .../hod_veci_do_diry/LevelManager.cs.meta | 2 + .../Scripts/hod_veci_do_diry/ObjectSpawner.cs | 113 +++++++++++++++ .../hod_veci_do_diry/ObjectSpawner.cs.meta | 2 + 9 files changed, 408 insertions(+) create mode 100644 Assets/Scripts/hod_veci_do_diry.meta create mode 100644 Assets/Scripts/hod_veci_do_diry/DraggableObject.cs create mode 100644 Assets/Scripts/hod_veci_do_diry/DraggableObject.cs.meta create mode 100644 Assets/Scripts/hod_veci_do_diry/Hole.cs create mode 100644 Assets/Scripts/hod_veci_do_diry/Hole.cs.meta create mode 100644 Assets/Scripts/hod_veci_do_diry/LevelManager.cs create mode 100644 Assets/Scripts/hod_veci_do_diry/LevelManager.cs.meta create mode 100644 Assets/Scripts/hod_veci_do_diry/ObjectSpawner.cs create mode 100644 Assets/Scripts/hod_veci_do_diry/ObjectSpawner.cs.meta diff --git a/Assets/Scripts/hod_veci_do_diry.meta b/Assets/Scripts/hod_veci_do_diry.meta new file mode 100644 index 0000000..d243a73 --- /dev/null +++ b/Assets/Scripts/hod_veci_do_diry.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9bee8d2d15f48de4c86e3b983e5d1ca6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/hod_veci_do_diry/DraggableObject.cs b/Assets/Scripts/hod_veci_do_diry/DraggableObject.cs new file mode 100644 index 0000000..9a9b5ed --- /dev/null +++ b/Assets/Scripts/hod_veci_do_diry/DraggableObject.cs @@ -0,0 +1,133 @@ +using UnityEngine; + +[RequireComponent(typeof(Rigidbody2D))] +[RequireComponent(typeof(Collider2D))] +public class DraggableObject : MonoBehaviour +{ + [Header("Přetahování")] + public float dragSmoothness = 15f; + + [Header("Vizuální zpětná vazba")] + public SpriteRenderer spriteRenderer; + public Color normalColor = Color.white; + public Color dragColor = new Color(1f, 1f, 0.5f); + public float scaleOnDrag = 1.15f; + + private Rigidbody2D rb; + private Camera mainCamera; + private bool isDragging = false; + private Vector3 targetPosition; + private Vector3 originalScale; + private bool hasBeenScored = false; + + void Awake() + { + rb = GetComponent(); + mainCamera = Camera.main; + originalScale = transform.localScale; + + if (spriteRenderer == null) + spriteRenderer = GetComponent(); + } + + void Start() + { + rb.gravityScale = 0f; + rb.constraints = RigidbodyConstraints2D.FreezeRotation; + targetPosition = transform.position; + } + + void Update() + { + HandleInput(); + + if (isDragging) + transform.position = Vector3.Lerp(transform.position, targetPosition, Time.deltaTime * dragSmoothness); + } + + void HandleInput() + { + + if (Input.touchCount > 0) + { + Touch touch = Input.GetTouch(0); + Vector3 worldPos = mainCamera.ScreenToWorldPoint(new Vector3(touch.position.x, touch.position.y, 10f)); + + if (touch.phase == TouchPhase.Began) TryStartDrag(worldPos); + else if (touch.phase == TouchPhase.Moved || + touch.phase == TouchPhase.Stationary) { if (isDragging) targetPosition = worldPos; } + else if (touch.phase == TouchPhase.Ended || + touch.phase == TouchPhase.Canceled) { if (isDragging) EndDrag(); } + } + // na twest pro myŠ + else + { + Vector3 worldPos = mainCamera.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 10f)); + + if (Input.GetMouseButtonDown(0)) TryStartDrag(worldPos); + else if (Input.GetMouseButton(0) && isDragging) targetPosition = worldPos; + else if (Input.GetMouseButtonUp(0) && isDragging) EndDrag(); + } + } + + void TryStartDrag(Vector3 worldPos) + { + if (GetComponent().OverlapPoint(worldPos)) + StartDrag(worldPos); + } + + void StartDrag(Vector3 worldPos) + { + isDragging = true; + rb.linearVelocity = Vector2.zero; + targetPosition = worldPos; + + transform.localScale = originalScale * scaleOnDrag; + if (spriteRenderer != null) + { + spriteRenderer.color = dragColor; + spriteRenderer.sortingOrder = 10; + } + } + + void EndDrag() + { + isDragging = false; + transform.localScale = originalScale; + if (spriteRenderer != null) + { + spriteRenderer.color = normalColor; + spriteRenderer.sortingOrder = 0; + } + } + + public void OnScored() + { + if (hasBeenScored) return; + hasBeenScored = true; + isDragging = false; + + StartCoroutine(SinkIntoHole()); + } + + System.Collections.IEnumerator SinkIntoHole() + { + float duration = 0.35f; + float elapsed = 0f; + Vector3 startScale = transform.localScale; + + while (elapsed < duration) + { + elapsed += Time.deltaTime; + float t = elapsed / duration; + transform.localScale = Vector3.Lerp(startScale, Vector3.zero, t); + if (spriteRenderer != null) + spriteRenderer.color = new Color(normalColor.r, normalColor.g, normalColor.b, 1f - t); + yield return null; + } + + gameObject.SetActive(false); + + LevelManager.Instance?.RegisterItem(); + } +} diff --git a/Assets/Scripts/hod_veci_do_diry/DraggableObject.cs.meta b/Assets/Scripts/hod_veci_do_diry/DraggableObject.cs.meta new file mode 100644 index 0000000..3cb7291 --- /dev/null +++ b/Assets/Scripts/hod_veci_do_diry/DraggableObject.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: fb5157d7cd78450439c40cd6f5afe6ac \ No newline at end of file diff --git a/Assets/Scripts/hod_veci_do_diry/Hole.cs b/Assets/Scripts/hod_veci_do_diry/Hole.cs new file mode 100644 index 0000000..48cb1c6 --- /dev/null +++ b/Assets/Scripts/hod_veci_do_diry/Hole.cs @@ -0,0 +1,105 @@ +using UnityEngine; +using System.Collections; + +public class Hole : MonoBehaviour +{ + [Header("Nastavení")] + [Tooltip("Poloměr zachycení – do kolika jednotek od středu se item 'vtáhne'")] + public float catchRadius = 0.6f; + + [Tooltip("Síla vtahování itemu k díře")] + public float pullForce = 4f; + + [Header("Pohyb díry (volitelné)")] + public bool hasMovement = false; + public float moveSpeed = 2f; + public Vector2 moveRange = new Vector2(1.5f, 0f); + + [Header("Vizuál")] + public SpriteRenderer glowRenderer; + + private Vector3 startPosition; + private bool isGlowing = false; + + void Awake() + { + startPosition = transform.position; + + CircleCollider2D col = GetComponent(); + if (col != null) + { + col.isTrigger = true; + col.radius = catchRadius; + } + } + + void Update() + { + if (hasMovement) + { + float x = startPosition.x + Mathf.Sin(Time.time * moveSpeed) * moveRange.x; + float y = startPosition.y + Mathf.Cos(Time.time * moveSpeed * 0.7f) * moveRange.y; + transform.position = new Vector3(x, y, transform.position.z); + } + } + + void OnTriggerStay2D(Collider2D other) + { + DraggableObject draggable = other.GetComponent(); + if (draggable == null) return; + + float dist = Vector2.Distance(transform.position, other.transform.position); + + + Rigidbody2D rb = other.GetComponent(); + if (rb != null) + { + Vector2 dir = ((Vector2)transform.position - rb.position).normalized; + rb.AddForce(dir * pullForce * Time.fixedDeltaTime, ForceMode2D.Impulse); + } + + + if (dist < catchRadius * 0.4f) + { + draggable.OnScored(); + SetGlow(false); + } + } + + void OnTriggerEnter2D(Collider2D other) + { + if (other.GetComponent() != null) SetGlow(true); + } + + void OnTriggerExit2D(Collider2D other) + { + if (other.GetComponent() != null) SetGlow(false); + } + + void SetGlow(bool active) + { + isGlowing = active; + if (glowRenderer == null) return; + glowRenderer.enabled = active; + if (active) StartCoroutine(PulseGlow()); + } + + IEnumerator PulseGlow() + { + while (isGlowing && glowRenderer != null) + { + float t = Mathf.PingPong(Time.time * 3f, 1f); + Color c = glowRenderer.color; + glowRenderer.color = new Color(c.r, c.g, c.b, Mathf.Lerp(0.3f, 0.9f, t)); + yield return null; + } + } + + void OnDrawGizmosSelected() + { + Gizmos.color = Color.green; + Gizmos.DrawWireSphere(transform.position, catchRadius); + Gizmos.color = Color.yellow; + Gizmos.DrawWireSphere(transform.position, catchRadius * 0.4f); + } +} diff --git a/Assets/Scripts/hod_veci_do_diry/Hole.cs.meta b/Assets/Scripts/hod_veci_do_diry/Hole.cs.meta new file mode 100644 index 0000000..753f62c --- /dev/null +++ b/Assets/Scripts/hod_veci_do_diry/Hole.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: ca7423fcca5f83249a2574cd84b7f806 \ No newline at end of file diff --git a/Assets/Scripts/hod_veci_do_diry/LevelManager.cs b/Assets/Scripts/hod_veci_do_diry/LevelManager.cs new file mode 100644 index 0000000..f39d4c8 --- /dev/null +++ b/Assets/Scripts/hod_veci_do_diry/LevelManager.cs @@ -0,0 +1,41 @@ +using UnityEngine; +using UnityEngine.Events; + +public class LevelManager : MonoBehaviour +{ + public static LevelManager Instance; + + [Header("Nastavení levelu")] + [Tooltip("Kolik itemů musí hráč trefit pro splnění levelu")] + public int itemsToScore = 3; + + [Header("Event – vyvolá se po trefení všech itemů")] + public UnityEvent OnAllItemsScored; + + private int scoredCount = 0; + + void Awake() + { + if (Instance == null) Instance = this; + else Destroy(gameObject); + } + + public void RegisterItem() + { + scoredCount++; + Debug.Log($"Trefeno: {scoredCount} / {itemsToScore}"); + + if (scoredCount >= itemsToScore) + { + OnAllItemsScored?.Invoke(); + } + } + + public void ResetCounter() + { + scoredCount = 0; + } + + public int GetScoredCount() => scoredCount; + public int GetTotalCount() => itemsToScore; +} diff --git a/Assets/Scripts/hod_veci_do_diry/LevelManager.cs.meta b/Assets/Scripts/hod_veci_do_diry/LevelManager.cs.meta new file mode 100644 index 0000000..252153c --- /dev/null +++ b/Assets/Scripts/hod_veci_do_diry/LevelManager.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: a819c02c3679b5a449b41052d2e6b3c9 \ No newline at end of file diff --git a/Assets/Scripts/hod_veci_do_diry/ObjectSpawner.cs b/Assets/Scripts/hod_veci_do_diry/ObjectSpawner.cs new file mode 100644 index 0000000..71a46da --- /dev/null +++ b/Assets/Scripts/hod_veci_do_diry/ObjectSpawner.cs @@ -0,0 +1,113 @@ +using UnityEngine; +using System.Collections.Generic; + + + + +public class ObjectSpawner : MonoBehaviour +{ + public static ObjectSpawner Instance; + + [Header("Prefaby")] + public GameObject[] objectPrefabs; + public GameObject holePrefab; + + [Header("Počty")] + [Tooltip("Kolik předmětů spawnovat")] + public int objectCount = 3; + [Tooltip("Kolik děr spawnovat")] + public int holeCount = 1; + + [Header("Pohyb děr")] + public bool holesMove = false; + public float holeMoveSpeed = 2f; + + [Header("Spawn hranice (odpovídají kameře)")] + public float minX = -3.5f; + public float maxX = 3.5f; + public float minY = -5f; + public float maxY = 4f; + + [Header("Rodiče pro přehlednost (volitelné)")] + public Transform objectParent; + public Transform holeParent; + + private List spawnedObjects = new List(); + private List spawnedHoles = new List(); + + void Awake() + { + if (Instance == null) Instance = this; + else Destroy(gameObject); + } + + void Start() + { + Spawn(); + } + + public void Spawn() + { + Clear(); + + // LevelManager na aktuální počet + if (LevelManager.Instance != null) + { + LevelManager.Instance.itemsToScore = objectCount; + LevelManager.Instance.ResetCounter(); + } + + SpawnHoles(); + SpawnObjects(); + } + + void SpawnHoles() + { + for (int i = 0; i < holeCount; i++) + { + Vector2 pos = RandomPos(1f); + GameObject hole = Instantiate(holePrefab, pos, Quaternion.identity, holeParent); + + Hole h = hole.GetComponent(); + if (h != null && holesMove) + { + h.hasMovement = true; + h.moveSpeed = holeMoveSpeed; + h.moveRange = new Vector2(Random.Range(0.8f, 1.8f), 0f); + } + + spawnedHoles.Add(hole); + } + } + + void SpawnObjects() + { + for (int i = 0; i < objectCount; i++) + { + GameObject prefab = objectPrefabs[Random.Range(0, objectPrefabs.Length)]; + Vector2 pos = RandomPos(0.5f); + GameObject obj = Instantiate(prefab, pos, Quaternion.identity, objectParent); + + // Náhodná barva + SpriteRenderer sr = obj.GetComponent(); + if (sr != null) + sr.color = Random.ColorHSV(0f, 1f, 0.7f, 1f, 0.9f, 1f); + + spawnedObjects.Add(obj); + } + } + + public void Clear() + { + foreach (var o in spawnedObjects) if (o != null) Destroy(o); + foreach (var h in spawnedHoles) if (h != null) Destroy(h); + spawnedObjects.Clear(); + spawnedHoles.Clear(); + } + + Vector2 RandomPos(float margin) => + new Vector2( + Random.Range(minX + margin, maxX - margin), + Random.Range(minY + margin, maxY - margin) + ); +} diff --git a/Assets/Scripts/hod_veci_do_diry/ObjectSpawner.cs.meta b/Assets/Scripts/hod_veci_do_diry/ObjectSpawner.cs.meta new file mode 100644 index 0000000..3f28526 --- /dev/null +++ b/Assets/Scripts/hod_veci_do_diry/ObjectSpawner.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 071f79f81861c2741a92d8b044457d94 \ No newline at end of file