using System.Collections; using UnityEngine; using UnityEngine.Events; using UnityEngine.EventSystems; public class WorldItemSelector : MonoBehaviour { public float moveThreshold = 10; public LayerMask layerMask; public LayerMask gndMask; public void SelectScreenPoint(Vector2 screenPoint){ Ray ray = Camera.main.ScreenPointToRay(screenPoint); RaycastHit hit = new RaycastHit(); if(Physics.Raycast(ray,out hit, Mathf.Infinity, layerMask)){ Building selectedB = hit.collider.GetComponent(); // if(selectedB!=null){ // Debug.Log("Selected building : " + selectedB.buildingData.buildingName); // // }else{ // Debug.Log("No target here, Unselecting"); // //Selector.selectBuilding(null); // } Selector.selectBuilding(selectedB); if(Selector.insideHall){ HumanInteractor interactor = hit.collider.GetComponent(); Selector.selectHuman(interactor); WorldspaceButton button = hit.collider.GetComponent(); if(button!=null){ button.Click(); } } }else{ Selector.selectBuilding(null); } } public Vector3? GetTouchingWorldPoint(Vector2 screenPoint){ Ray ray = Camera.main.ScreenPointToRay(screenPoint); RaycastHit hit = new RaycastHit(); if(Physics.Raycast(ray,out hit, Mathf.Infinity, gndMask)){ return hit.point; }else{ return null; } } private Vector2? startedPos= null; private bool isPointerDown => startedPos!=null; private bool holdingPointer = false; public float dragDelay = 0.85f; private long pointerDownTimestamp; public void OnPointerDown(BaseEventData e){ PointerEventData ped = (PointerEventData) e as PointerEventData; startedPos = ped.position; holdingPointer =true; Debug.Log($"Pointer timestamp : {pointerDownTimestamp}"); StartCoroutine(startDragCheck()); } IEnumerator startDragCheck(){ yield return new WaitForSeconds(dragDelay); if(holdingPointer){ Debug.Log("Initiating Drag"); SelectScreenPoint(startedPos ?? Vector2.zero); Selector.setMoving(Selector.selectedBuilding); } } public void OnPointerMove(BaseEventData e){ PointerEventData ped = (PointerEventData) e as PointerEventData; if(isPointerDown){ float pointerDiff = Mathf.Abs(ped.position.magnitude - (startedPos ?? Vector2.zero).magnitude); holdingPointer=(pointerDiff < moveThreshold); if(Selector.isMovingBuilding){ // Debug.Log("Gnd position: " + GetTouchingWorldPoint(ped.position)); Vector3 worldPos = GetTouchingWorldPoint(ped.position) ?? Selector.movingBuilding.transform.position; //validatePoint Selector.movingPointValid = true; Collider[] buildingsInside = Physics.OverlapBox(Selector.movingBuilding.GetComponent().bounds.center, Selector.movingBuilding.GetComponent().bounds.extents); foreach(Collider collider in buildingsInside){ if((collider.tag == "Building" || collider.tag == "Obstacle" ) && collider.transform != Selector.movingBuilding.transform){ Selector.movingPointValid =false; } } Selector.movingBuilding.ChangeOutlineColor(Selector.movingPointValid ? Color.green : Color.red); Selector.movingBuilding.transform.position = worldPos; } } } public void OnPointerUp(BaseEventData e){ Selector.resetMoving(); PointerEventData ped = (PointerEventData) e as PointerEventData; float pointerDiff = Mathf.Abs(ped.position.magnitude - (startedPos ?? Vector2.zero).magnitude); if(pointerDiff < moveThreshold){ SelectScreenPoint(ped.position); }else{ // Debug.Log("Pointer moved (" + pointerDiff+ "), Not gonna select item"); } startedPos = null; holdingPointer=false; Selector.refresh(); } } public static class Selector{ //public static bool enabled=true; public static bool insideHall = false; public static bool movingPointValid; public static Building movingBuilding; public static bool isMovingBuilding => movingBuilding!=null; public static Building selectedBuilding; public static BuildingData selectedData => selectedBuilding.buildingData; public static HumanInteractor selectedHuman; public static UnityEvent OnSelectedChanged = new UnityEvent(); public static void selectBuilding(Building e){ selectedBuilding = e; if(insideHall){selectedBuilding=null;} OnSelectedChanged.Invoke(); } public static void selectHuman(HumanInteractor e){ selectedHuman = e; if(!insideHall){selectedHuman=null;} OnSelectedChanged.Invoke(); } public static void resetMoving(){ if(movingBuilding!=null ){ if(movingPointValid) { DBmanager.RelocateBuilding(movingBuilding.buildingData.buildingName, movingBuilding.transform.position); }else{ movingBuilding.transform.position = movingStartedPosition; } } movingBuilding=null; refresh(); } private static Vector3 movingStartedPosition; public static void setMoving(Building e){ movingBuilding=e; if(e!=null){ movingStartedPosition=e.transform.position;} refresh(); } public static void refresh(){ OnSelectedChanged.Invoke(); } }