Skip to content
Snippets Groups Projects
WorldCursor.cs 7.20 KiB
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;
    //}
}