using System; using System.Globalization; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; using UnityEngine.EventSystems; using static GadgetManager; using UnityEngine.InputSystem; using static UIconfig; public class WorldCursor : MonoBehaviour { public RaycastHit Hit; public string deactivateSnapKey; private Camera Cam; private int layerMask; public LayerMask snapLayerMask; public float MaxRange = 10f; private float MaxRange_ = 10f; public bool useCamCurser = false; private int whichCheckMouseButton = 1; private void Awake() { //Ignore player and TalkingZone this.layerMask = ~LayerMask.GetMask("Player", "TalkingZone"); } void Start() { Cam = Camera.main; //Set MarkPointMode as the default ActiveToolMode // ActiveToolMode = ToolMode.ExtraMode;//ToolMode.MarkPointMode; // CommunicationEvents.ToolModeChangedEvent.Invoke(activeGadget.id); CultureInfo.CurrentCulture = new CultureInfo("en-US"); } public void setLayerMask(int layerMask) { this.layerMask = layerMask; } void Update() { updateMaxRange(); Cam = Camera.main; //WARN: Should not called every Update; Vector3 mousePos = new(0, 0, 0); //************************************************ if (UIconfig.InputManagerVersion == 1) { mousePos = Input.mousePosition; } if (UIconfig.InputManagerVersion == 2) { //mousePos = Mouse.current.position.ReadValue(); mousePos = Input.mousePosition; } if (UIconfig.InputManagerVersion == 3) { //mousePos = Mouse.current.position.ReadValue(); mousePos = Input.mousePosition; } //**************************************************** //Ray ray = useCamCurser ? new Ray(Cam.transform.position, Cam.transform.forward) : Cam.ScreenPointToRay(Input.mousePosition); Ray ray = useCamCurser ? new Ray(Cam.transform.position, Cam.transform.forward) : Cam.ScreenPointToRay(mousePos); this.Hit = new RaycastHit(); transform.up = Cam.transform.forward; transform.position = ray.GetPoint(GlobalBehaviour.GadgetPhysicalDistance); //************************************************ int rayCastMask = this.layerMask; if (Input.GetButton(this.deactivateSnapKey) && UIconfig.InputManagerVersion >= 1 && UIconfig.InputManagerVersion <= 3) rayCastMask &= ~this.snapLayerMask.value; //************************************************ if (Physics.Raycast(ray, out Hit, MaxRange_, rayCastMask) || (MaxRange_ <= GlobalBehaviour.GadgetPhysicalDistance && Physics.Raycast(transform.position, Vector3.down, out Hit, GlobalBehaviour.GadgetPhysicalDistance, rayCastMask))) { bool deactSnapKey = false; if (UIconfig.InputManagerVersion == 1) { Input.GetButton(this.deactivateSnapKey); } if ((Hit.collider.transform.CompareTag("SnapZone") || Hit.collider.transform.CompareTag("Selectable")) && !deactSnapKey) if (Hit.transform.TryGetComponent<FactObject>(out var obj) && StageStatic.stage.factState[obj.URI] is AbstractLineFact lineFact) { PointFact p1 = StageStatic.stage.factState[lineFact.Pid1] as PointFact; Hit.point = Math3d.ProjectPointOnLine(p1.Point, lineFact.Dir, Hit.point); } else { Hit.point = Hit.collider.transform.position; Hit.normal = Vector3.up; } transform.up = Hit.normal; transform.position = Hit.point + .01f * Hit.normal; //Link to CheckMouseButtonHandler if (whichCheckMouseButton == 0) { CheckMouseButtons(); } if (whichCheckMouseButton == 1) { CheckMouseButtons1(); } } } void updateMaxRange() { switch (UIconfig.GameplayMode) { case 2: UIconfig.interactingRangeMode = InteractingRangeMode.fromObserverView; break; case 5: case 6: UIconfig.interactingRangeMode = InteractingRangeMode.fromCharacterView; break; default: break; } MaxRange_ = UIconfig.interactingRangeMode switch { InteractingRangeMode.fromObserverView => cursorMaxRange_fromObeserverView, InteractingRangeMode.fromCharacterView or _ => MaxRange, }; } //Check if left Mouse-Button was pressed and handle it void CheckMouseButtons() { if (Input.GetMouseButtonDown(0) && !EventSystem.current.IsPointerOverGameObject() //this prevents rays from shooting through ui && Hit.transform.gameObject.layer != LayerMask.NameToLayer("Water")) // not allowed to meassure on water CommunicationEvents.TriggerEvent.Invoke(Hit); } //Check if left Mouse-Button was pressed and handle it //Alternative Version void CheckMouseButtons1(bool OnSnap = false, bool onLine = false) { if (Input.GetMouseButtonDown(0) && checkClickPermission()) { //other Things todo first? if (Hit.collider.transform.CompareTag("NPC1_text") && nextDialogPlease < 2) { nextDialogPlease++; } //if (EventSystem.current.IsPointerOverGameObject()) return; //this prevents rays from shooting through ui if (IsPointerOverUIObject()) return; //Needed for Android if (!checkLayerAndTags()) return; // not allowed to meassure on water //if (Hit.transform.gameObject.layer == LayerMask.NameToLayer("TransparentFX")) return; // not allowed to meassure on TransparentFX if (!OnSnap) { CommunicationEvents.TriggerEvent.Invoke(Hit); } else if (GadgetManager.ActiveGadget is Pointer) { if (!onLine) Hit.collider.enabled = false; CommunicationEvents.TriggerEvent.Invoke(Hit); // CommunicationEvents.SnapEvent.Invoke(Hit); } } } private bool checkLayerAndTags() => Hit.transform.gameObject.layer != LayerMask.NameToLayer("Water") // not allowed to meassure on water && !Hit.collider.transform.CompareTag("NPC1_text"); // not allowed to meassure on textfields private bool IsPointerOverUIObject() { PointerEventData eventDataCurrentPosition = new(EventSystem.current) { position = new Vector2(Input.mousePosition.x, Input.mousePosition.y) }; List<RaycastResult> results = new(); EventSystem.current.RaycastAll(eventDataCurrentPosition, results); return results.Count > 0; } public bool checkClickPermission() => true; //{ // if (UIconfig.CanvasOnOff_Array[14] > 0) // return true; // //return false; //todo // return true; //} }