Files
Studio/Assets/Scripts/XED/Building/ObjectHandler.cs
2025-02-19 17:43:14 +09:00

184 lines
4.5 KiB
C#

using RTG;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using WI;
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<TwinObject> onDrop;
public event Action<TwinObject> onSelect;
public event Action<TwinObject> onDeselect;
List<TwinObject> 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<GizmoController>().GetGizmoHover())
// return;
onClickTwinObject = true;
clickObject = comp as TwinObject;
}
public void OnStayGround(RaycastHit hit, Component comp)
{
//if (FindSingle<GizmoController>().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<GizmoController>().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);
}
}
}