using RTG; using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using XRLib; using XED; public class ObjectHandler : MonoBehaviour, ISingle { Vector3 groundPoint; bool onClickGround; bool onClickTwinObject; public TwinObject heldObject; public TwinObject clickObject; Dictionary<(bool, bool, bool), HandState> handleStateTable = new(); public event Action onDrop; public event Action onSelect; public event Action onDeselect; List selectedObjects = new(); public override void AfterAwake() { GenerateStateTable(); } void GenerateStateTable() { //heldObject==null && onClickGround && onClickTwinObject handleStateTable.Add((true, true, true), HandState.Select); handleStateTable.Add((true, true, false), HandState.Ground); handleStateTable.Add((true, false, true), HandState.Nothing); handleStateTable.Add((true, false, false), HandState.Nothing); handleStateTable.Add((false, true, true), HandState.Drop); handleStateTable.Add((false, true, false), HandState.Nothing); handleStateTable.Add((false, false, true), HandState.Nothing); handleStateTable.Add((false, false, false), HandState.Nothing); } public void Grab(TwinObject to) { heldObject = to; } public void Select(TwinObject to) { if (!to.physics.activeSelf) return; if (multiSelect) { if (selectedObjects.Remove(clickObject)) { onDeselect?.Invoke(clickObject); return; } } else { foreach (var twinobj in selectedObjects) { onDeselect?.Invoke(twinobj); } selectedObjects.Clear(); } clickObject = to; selectedObjects.Add(clickObject); onSelect?.Invoke(clickObject); } public void OnClickGround(RaycastHit hit, Component comp) { if (EventSystem.current.IsPointerOverGameObject()) { return; } onClickGround = true; groundPoint = hit.point; } public void OnClickTwinObject(RaycastHit hit, Component comp) { //if (FindSingle().GetGizmoHover()) // return; onClickTwinObject = true; clickObject = comp as TwinObject; } public void OnStayGround(RaycastHit hit, Component comp) { //if (FindSingle().GetGizmoHover()) // return; var pos = hit.point; if (heldObject != null) { var height = heldObject.physics.areabox.bounds.size.y * 0.5f; pos = new Vector3(pos.x, height, pos.z); } groundPoint = pos; } public enum HandState { Select, Drop, Ground, Nothing, } public HandState eventState { get { var key = (heldObject == null, onClickGround, onClickTwinObject); return handleStateTable[key]; } } public bool multiSelect; void Update() { multiSelect = Input.GetKey(KeyCode.LeftShift); HandlingAction(); } void HandlingAction() { switch (eventState) { case HandState.Select: Select(clickObject); break; case HandState.Drop: onDrop?.Invoke(heldObject); heldObject = null; break; case HandState.Ground: if (multiSelect) break; //if (FindSingle().GetGizmoHover()) // break; foreach (var twinobj in selectedObjects) { onDeselect?.Invoke(twinobj); } selectedObjects.Clear(); break; case HandState.Nothing: if (heldObject == null) { break; } heldObject.transform.position = groundPoint; break; } clickObject = null; onClickGround = false; onClickTwinObject = false; } void DeselectObject(TwinObject to) { onDeselect?.Invoke(to); } public void Remove(TwinObject to) { if (selectedObjects.Contains(to)) { //onDeselectEvent?.Invoke(to); selectedObjects.Remove(to); } } }