using Fruitomation.Global; using UnityEngine; namespace Fruitomation.Game.Items { public sealed class ItemBehaviour : MonoBehaviour { public RectTransform RectTransform { get; private set; } public Rigidbody2D Body2D { get; private set; } private Canvas AttachedCanvas { get; set; } private bool EnteredCanvas { get; set; } private CustomItemBehaviour CustomBehaviour; private GameObject CurrentChild; private ItemType InternalItemType; public ItemType CurrentType { get => InternalItemType; set { if (InternalItemType != value) // Stops unneeded changes { InternalItemType = value; OnUpdateItemType(); } } } public void InitBehaviour(Canvas canvas, ItemType startType) { RectTransform = transform.GetComponent(); Body2D = transform.GetComponent(); AttachedCanvas = canvas; CurrentType = startType; EnteredCanvas = false; CustomBehaviour?.OnCreation(); } private void OnUpdateItemType() { if (CurrentChild is not null) { CustomBehaviour = null; Destroy(CurrentChild); } ItemInfo info = ItemInfoRegistry.Get(CurrentType); CurrentChild = Instantiate(info.Prefab, transform); CustomBehaviour = info.GetCustomBehaviour(); if (CustomBehaviour is not null) { CustomBehaviour.AttachedItemBehaviour = this; CustomBehaviour.OnCreation(); } } private void Update() { if (!GameStateController.Is(GameState.Simulation)) { TriggerDestruction(false); } } private void FixedUpdate() { bool contained = IsWithinCanvas(RectTransform, AttachedCanvas.GetComponent()); EnteredCanvas = EnteredCanvas || contained; if (!contained && EnteredCanvas) { TriggerDestruction(); } } private static bool IsWithinCanvas(RectTransform element, RectTransform canvas) { Vector3[] elementCorners = new Vector3[4]; Vector3[] canvasCorners = new Vector3[4]; element.GetWorldCorners(elementCorners); canvas.GetWorldCorners(canvasCorners); Rect bounds = new ( canvasCorners[0].x, canvasCorners[0].y, canvasCorners[2].x - canvasCorners[0].x, canvasCorners[2].y - canvasCorners[0].y ); foreach (Vector3 corner in elementCorners) { if (bounds.Contains(corner)) { return true; } } return false; } public void TriggerDestruction(bool harvest = true) { if (harvest) { ItemInfo info = ItemInfoRegistry.Get(CurrentType); float money = Random.Range(info.MinMoney, info.MaxMoney); MoneyController.Add(money); } Destroy(gameObject); } } }