Newer
Older
using System.Collections.Generic;
using UnityEngine;
public class WorldCursor : MonoBehaviour
{
// TODO experimentell for multiple hits
Marco Zimmer
committed
public string deactivateSnapKey;
public float MaxRange = 10f;
public bool useCamCurser = false;
private void Awake()
{
//Ignore player and TalkingZone
this.layerMask = ~LayerMask.GetMask("Player", "TalkingZone");
void Start()
{
Cam = Camera.main;
CultureInfo.CurrentCulture = new CultureInfo("en-US");
public void setLayerMask(int layerMask)
{
this.layerMask = layerMask;
}
// working currently to include multiple hits
// TODO
Stefan Richter
committed
Cam = Camera.main; //WARN: Should not called every Update; TODO: Cache in Start/Awake?
Vector3 mousePos = UIconfig.InputManagerVersion switch
1 or 2 or 3 => Input.mousePosition,
_ => Vector3.zero
};
Ray ray = useCamCurser
? new Ray(Cam.transform.position, Cam.transform.forward)
: Cam.ScreenPointToRay(mousePos);
transform.up = Cam.transform.forward;
transform.position = ray.GetPoint(GlobalBehaviour.GadgetPhysicalDistance);
//************************************************
bool deactSnapKey =
Input.GetButton(this.deactivateSnapKey)
&& UIconfig.InputManagerVersion >= 1
&& UIconfig.InputManagerVersion <= 3;
//************************************************
Marco Zimmer
committed
Hits = Physics.RaycastAll(ray, MaxRange, layerMask);
if (Hits.Length == 0)
Hits = Physics.RaycastAll(transform.position, Vector3.down, GlobalBehaviour.GadgetPhysicalDistance, layerMask);
if (Hits.Length == 0)
return; // in case we dont hit anything, just return
Hits = Hits
.OrderBy(h => h.distance)
.ToArray();
Fact[] facts = Hits
.Select(h =>
h.transform.TryGetComponent(out FactObject factObj)
? FactOrganizer.AllFacts[factObj.URI]
: null)
.ToArray();
Hits[i].point =
Math3d.ProjectPointOnLine(lineFact.Point1.Point, lineFact.Dir, Hits[i].point);
var projPlane =
Math3d.ProjectPointOnPlane(circleFact.normal, circleFact.Point1.Point, Hits[i].point);
var circleDistance = projPlane - circleFact.Point1.Point;
if (circleDistance.magnitude >= circleFact.radius)
{
projPlane = circleFact.Point1.Point + circleDistance.normalized * circleFact.radius;
Hits[i].normal = circleDistance.normalized;
}
Hits[i].point = projPlane;
else if (!deactSnapKey &&
(Hits[i].collider.transform.CompareTag("SnapZone")
|| Hits[i].collider.transform.CompareTag("Selectable")))
Hits[i].point = Hits[i].collider.transform.position;
Hits[i].normal = Vector3.up;
break; // we had at least 1 succesfull case
}
if (i == Hits.Length)
return; // no valid Hit
Hits = Hits.Skip(i)
.TakeWhile(h => h.distance - Hits[i].distance < IntersectionDistance)
.ToArray();
if (Hits.Length > 1)
{ // we have two or more objects intersecting
if (facts[i + 0] is RayFact rayFact1
&& facts[i + 1] is RayFact rayFact2)
if (Math3d.LineLineIntersection(out Vector3 intersectionPoint
, rayFact2.Point1.Point, rayFact2.Dir
, rayFact1.Point1.Point, rayFact1.Dir))
{
Hits[i + 0].point = intersectionPoint;
Hits[i + 1].point = intersectionPoint;
//TODO: check for other types of intersection. Future Work
}
transform.up = Hits[0].normal;
transform.position = Hits[0].point + .01f * Hits[0].normal;
if (Input.GetMouseButtonDown(0))
ClickHandler();
Stefan Richter
committed
{
Stefan Richter
committed
case 2:
Marco Zimmer
committed
UIconfig.interactingRangeMode = UIconfig.InteractingRangeMode.fromObserverView;
Stefan Richter
committed
break;
Stefan Richter
committed
case 5:
case 6:
Marco Zimmer
committed
UIconfig.interactingRangeMode = UIconfig.InteractingRangeMode.fromCharacterView;
Stefan Richter
committed
break;
default:
break;
}
John Schihada
committed
}
if (Hits[0].collider.transform.CompareTag("NPC1_text")
&& UIconfig.nextDialogPlease < 2)
UIconfig.nextDialogPlease++;
if (IsPointerOverUIObject() //Needed for Android. NOT JUST: EventSystem.current.IsPointerOverGameObject()
|| Hits[0].transform.gameObject.layer == LayerMask.NameToLayer("Water") // not allowed to meassure on water
|| Hits[0].collider.transform.CompareTag("NPC1_text")) // not allowed to meassure on textfields
Stefan Richter
committed
CommunicationEvents.TriggerEvent.Invoke(Hits);
return;
static 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);