UPF/Assets/Game/Scripts/WorldItemSelector.cs
2023-02-24 22:14:55 +05:30

176 lines
6.1 KiB
C#
Executable File

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<Building>();
// 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<HumanInteractor>();
Selector.selectHuman(interactor);
WorldspaceButton button = hit.collider.GetComponent<WorldspaceButton>();
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;
}
}
public void SelectBuilding(Building building){
Selector.selectBuilding(building);
}
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<Collider>().bounds.center, Selector.movingBuilding.GetComponent<Collider>().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();
AudioManager.instnace.UIClick();
}
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();
}
}