1003 lines
28 KiB
C#
1003 lines
28 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using BitStrap;
|
|
using LE_LevelEditor.Commands;
|
|
using LE_LevelEditor.Core;
|
|
using LE_LevelEditor.Events;
|
|
using LE_LevelEditor.Logic;
|
|
using S_SnapTools;
|
|
using UndoRedo;
|
|
using UnityEngine;
|
|
|
|
namespace LE_LevelEditor.UI
|
|
{
|
|
public class LE_GUI3dObject : LE_GUI3dBase
|
|
{
|
|
private const float MIN_FOCUS_DISTANCE = 3f;
|
|
|
|
private const float SELECTION_MAX_OVERSIZE = 10f;
|
|
|
|
[ReadOnly]
|
|
public LE_Object m_object;
|
|
|
|
private string m_objectResourcePath;
|
|
|
|
[ReadOnly]
|
|
public bool m_isObjectPlaceable;
|
|
|
|
[ReadOnly]
|
|
public bool m_isSceneInstanceFound;
|
|
|
|
private string m_dragMessage = string.Empty;
|
|
|
|
[ReadOnly]
|
|
public LE_Object m_previewInstance;
|
|
|
|
[ReadOnly]
|
|
public LE_Object m_selectedObject;
|
|
|
|
private LE_Object m_cursorActionOnObject;
|
|
|
|
private bool m_isSelectionPossible;
|
|
|
|
private bool m_isCursorAction;
|
|
|
|
private bool m_isCursorActionInThisFrame;
|
|
|
|
private Vector3 m_lastCursorActionStartPos = -100f * Vector3.one;
|
|
|
|
private Dictionary<string, S_SnapToObject> m_snapPointUIDsToSnapPoints = new Dictionary<string, S_SnapToObject>();
|
|
|
|
private Dictionary<string, int> m_snapPointUIDsToObjUIDs = new Dictionary<string, int>();
|
|
|
|
private int m_snapPointUIDToSnapPointsInvalidatedFrame = -1;
|
|
|
|
private bool m_isSnapToObjectActive = true;
|
|
|
|
public int TERRAIN_LAYER = 28;
|
|
|
|
public Action<Vector3, float> OnFocused;
|
|
|
|
private LE_EObjectEditSpace m_objectEditSpace;
|
|
|
|
private LE_EObjectEditMode m_objectEditMode;
|
|
|
|
private bool m_isKeyComboDuplicate = true;
|
|
|
|
private bool m_isKeyComboFocus = true;
|
|
|
|
private bool m_isKeyComboDelete = true;
|
|
|
|
public LE_Object SelectedPrefab
|
|
{
|
|
get
|
|
{
|
|
return m_object;
|
|
}
|
|
}
|
|
|
|
public bool IsSceneInstanceFound
|
|
{
|
|
get
|
|
{
|
|
return m_isSceneInstanceFound;
|
|
}
|
|
}
|
|
|
|
public LE_Object SelectedObject
|
|
{
|
|
get
|
|
{
|
|
return m_selectedObject;
|
|
}
|
|
}
|
|
|
|
public bool IsSelectedObjectSmartMoved
|
|
{
|
|
get
|
|
{
|
|
return m_selectedObject != null && m_selectedObject.EditHandle != null && m_selectedObject.EditHandle.EditMode == LE_EObjectEditMode.SMART && m_selectedObject.EditHandle.IsDrag;
|
|
}
|
|
}
|
|
|
|
public Dictionary<string, int> SnapPointUIDsToObjUIDs
|
|
{
|
|
get
|
|
{
|
|
return m_snapPointUIDsToObjUIDs;
|
|
}
|
|
}
|
|
|
|
public bool IsSnapToObjectActive
|
|
{
|
|
get
|
|
{
|
|
return m_isSnapToObjectActive;
|
|
}
|
|
}
|
|
|
|
public override LE_EEditMode ActiveEditMode
|
|
{
|
|
get
|
|
{
|
|
return LE_EEditMode.OBJECT;
|
|
}
|
|
}
|
|
|
|
public LE_EObjectEditSpace ObjectEditSpace
|
|
{
|
|
get
|
|
{
|
|
return m_objectEditSpace;
|
|
}
|
|
set
|
|
{
|
|
m_objectEditSpace = value;
|
|
}
|
|
}
|
|
|
|
public LE_EObjectEditMode ObjectEditMode
|
|
{
|
|
get
|
|
{
|
|
return m_objectEditMode;
|
|
}
|
|
set
|
|
{
|
|
m_objectEditMode = value;
|
|
}
|
|
}
|
|
|
|
public bool IsKeyComboDuplicate
|
|
{
|
|
get
|
|
{
|
|
return m_isKeyComboDuplicate;
|
|
}
|
|
set
|
|
{
|
|
m_isKeyComboDuplicate = value;
|
|
}
|
|
}
|
|
|
|
public bool IsKeyComboFocus
|
|
{
|
|
get
|
|
{
|
|
return m_isKeyComboFocus;
|
|
}
|
|
set
|
|
{
|
|
m_isKeyComboFocus = value;
|
|
}
|
|
}
|
|
|
|
public bool IsKeyComboDelete
|
|
{
|
|
get
|
|
{
|
|
return m_isKeyComboDelete;
|
|
}
|
|
set
|
|
{
|
|
m_isKeyComboDelete = value;
|
|
}
|
|
}
|
|
|
|
public override void SetCursorPosition(Vector3 p_cursorScreenCoords)
|
|
{
|
|
if (m_object != null && (m_object.SnapType == LE_Object.ESnapType.SNAP_TO_TERRAIN || m_object.SnapType == LE_Object.ESnapType.SNAP_TO_2D_GRID_AND_TERRAIN))
|
|
{
|
|
m_cursorScreenCoords = p_cursorScreenCoords;
|
|
m_cursorRay = Camera.main.ScreenPointToRay(p_cursorScreenCoords);
|
|
SetIsCursorOverSomething(Physics.Raycast(m_cursorRay, out m_cursorHitInfo, float.MaxValue, 1 << TERRAIN_LAYER));
|
|
return;
|
|
}
|
|
if (IsSelectedObjectSmartMoved)
|
|
{
|
|
int layer = LayerMask.NameToLayer("Ignore Raycast");
|
|
Dictionary<GameObject, int> dictionary = new Dictionary<GameObject, int>();
|
|
MoveToLayer(m_selectedObject.transform, layer, dictionary);
|
|
base.SetCursorPosition(p_cursorScreenCoords);
|
|
{
|
|
foreach (KeyValuePair<GameObject, int> item in dictionary)
|
|
{
|
|
if (item.Key != null)
|
|
{
|
|
item.Key.layer = item.Value;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
base.SetCursorPosition(p_cursorScreenCoords);
|
|
}
|
|
|
|
public override void SetIsCursorAction(bool p_isCursorAction)
|
|
{
|
|
if (base.IsInteractable)
|
|
{
|
|
m_isCursorActionInThisFrame |= p_isCursorAction;
|
|
}
|
|
}
|
|
|
|
public void SetDraggableObject(LE_Object p_object, string p_objectResourcePath)
|
|
{
|
|
if (m_object != p_object)
|
|
{
|
|
m_isSceneInstanceFound = false;
|
|
m_dragMessage = string.Empty;
|
|
SetDragMessageInUI();
|
|
m_object = p_object;
|
|
m_objectResourcePath = p_objectResourcePath;
|
|
m_isObjectPlaceable = IsObjectPlaceable();
|
|
}
|
|
}
|
|
|
|
public void SelectObject(LE_Object p_object)
|
|
{
|
|
LE_Object p_priorSelectedObject = null;
|
|
if (m_selectedObject != null && m_selectedObject != p_object)
|
|
{
|
|
m_selectedObject.EditMode = LE_EObjectEditMode.NO_EDIT;
|
|
m_selectedObject.IsSelected = false;
|
|
p_priorSelectedObject = m_selectedObject;
|
|
}
|
|
if (LE_LevelEditorMain.Instance != null && LE_LevelEditorMain.Instance.EditMode != LE_EEditMode.OBJECT)
|
|
{
|
|
p_object = null;
|
|
}
|
|
m_selectedObject = p_object;
|
|
if (m_selectedObject != null)
|
|
{
|
|
m_selectedObject.IsSelected = true;
|
|
}
|
|
if (LE_EventInterface.OnObjectSelectedInScene != null)
|
|
{
|
|
LE_EventInterface.OnObjectSelectedInScene(this, new LE_ObjectSelectedEvent(m_selectedObject, p_priorSelectedObject));
|
|
}
|
|
if ((bool)p_object && (bool)p_object.GetComponent<FishSpawner>())
|
|
{
|
|
FisheryEditor.Instance.ShowFishSpeciesWindow(p_object);
|
|
}
|
|
else
|
|
{
|
|
FisheryEditor.Instance.ShowFishSpeciesWindow(null);
|
|
}
|
|
}
|
|
|
|
public void Focus()
|
|
{
|
|
if (!(m_selectedObject != null))
|
|
{
|
|
return;
|
|
}
|
|
Renderer[] componentsInChildren = m_selectedObject.GetComponentsInChildren<Renderer>();
|
|
Vector3 vector = Vector3.zero;
|
|
Vector3 vector2 = Vector3.zero;
|
|
float num = 0f;
|
|
Renderer[] array = componentsInChildren;
|
|
foreach (Renderer renderer in array)
|
|
{
|
|
if (renderer.GetComponentInParent<LE_ObjectEditHandle>() == null)
|
|
{
|
|
vector += renderer.bounds.center;
|
|
vector2 += renderer.bounds.size;
|
|
num += 1f;
|
|
}
|
|
}
|
|
if (num != 0f)
|
|
{
|
|
vector *= 1f / num;
|
|
vector2 *= 1f / num;
|
|
}
|
|
else
|
|
{
|
|
vector = m_selectedObject.transform.position;
|
|
vector2 = Vector3.one * 3f;
|
|
}
|
|
Vector3 vector3 = Camera.main.transform.position - vector;
|
|
float num2 = Mathf.Max(vector2.x, vector2.y, vector2.z) * 3f;
|
|
Camera.main.transform.position = vector + vector3.normalized * num2;
|
|
if (Camera.main.transform.position.y < vector.y)
|
|
{
|
|
Vector3 position = Camera.main.transform.position;
|
|
position.y = vector.y;
|
|
Camera.main.transform.position = position;
|
|
}
|
|
Camera.main.transform.LookAt(vector, Vector3.up);
|
|
if (OnFocused != null)
|
|
{
|
|
OnFocused(vector, num2);
|
|
}
|
|
}
|
|
|
|
public void SelectNFocusPrefabInstanceInScene()
|
|
{
|
|
bool flag = m_selectedObject != null && m_object != null && m_selectedObject.name == m_objectResourcePath;
|
|
LE_Object lE_Object = null;
|
|
LE_Object[] array = UnityEngine.Object.FindObjectsOfType<LE_Object>();
|
|
for (int i = 0; i < array.Length; i++)
|
|
{
|
|
if (array[i].name == m_objectResourcePath)
|
|
{
|
|
if (!flag)
|
|
{
|
|
SelectObject(array[i]);
|
|
Focus();
|
|
return;
|
|
}
|
|
if (lE_Object == null)
|
|
{
|
|
lE_Object = array[i];
|
|
}
|
|
if (m_selectedObject == array[i])
|
|
{
|
|
flag = false;
|
|
}
|
|
}
|
|
}
|
|
if (lE_Object != null)
|
|
{
|
|
SelectObject(lE_Object);
|
|
Focus();
|
|
}
|
|
}
|
|
|
|
public void Delete()
|
|
{
|
|
if (m_selectedObject != null)
|
|
{
|
|
UR_CommandMgr.Instance.Execute(new LE_CmdDeleteObject(this, m_selectedObject));
|
|
FisheryEditor.Instance.ShowFishSpeciesWindow(null);
|
|
SelectObject(null);
|
|
m_object = null;
|
|
m_previewInstance = null;
|
|
}
|
|
}
|
|
|
|
public void RemoveSelection()
|
|
{
|
|
SelectObject(null);
|
|
}
|
|
|
|
public void CloneObject()
|
|
{
|
|
string text = m_selectedObject.name;
|
|
if (m_selectedObject != null && IsObjectPlaceable(m_selectedObject, text))
|
|
{
|
|
m_selectedObject.EditMode = LE_EObjectEditMode.NO_EDIT;
|
|
m_selectedObject.IsSelected = false;
|
|
m_selectedObject.ApplySelectionState();
|
|
UR_CommandMgr.Instance.Execute(new LE_CmdCloneObject(this, m_selectedObject.UID, m_selectedObject.transform, text));
|
|
}
|
|
}
|
|
|
|
public bool IsObjectPlaceable(LE_Object p_object, string p_resourcePath)
|
|
{
|
|
m_isSceneInstanceFound = false;
|
|
if (p_object.MaxInstancesInLevel != 0)
|
|
{
|
|
int num = 0;
|
|
LE_Object[] array = UnityEngine.Object.FindObjectsOfType<LE_Object>();
|
|
for (int i = 0; i < array.Length; i++)
|
|
{
|
|
if (array[i].name == p_resourcePath)
|
|
{
|
|
m_isSceneInstanceFound = true;
|
|
num++;
|
|
if (p_object.MaxInstancesInLevel <= num)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
if (p_object.gameObject.HasTag("ICE_EDITOR") && (bool)FisheryEditor.Instance.GetIceOnLevel(p_object))
|
|
{
|
|
m_isSceneInstanceFound = true;
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_isSceneInstanceFound = GameObject.Find(m_objectResourcePath);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public void UpdateIsObjectPlaceable()
|
|
{
|
|
m_isObjectPlaceable = IsObjectPlaceable();
|
|
}
|
|
|
|
public void SetSnapPointUIDsToObjUIDs(Dictionary<string, int> p_snapPointUIDsToObjUIDs)
|
|
{
|
|
foreach (KeyValuePair<string, int> p_snapPointUIDsToObjUID in p_snapPointUIDsToObjUIDs)
|
|
{
|
|
if (!m_snapPointUIDsToObjUIDs.ContainsKey(p_snapPointUIDsToObjUID.Key))
|
|
{
|
|
m_snapPointUIDsToObjUIDs.Add(p_snapPointUIDsToObjUID.Key, p_snapPointUIDsToObjUID.Value);
|
|
continue;
|
|
}
|
|
Debug.LogError("LE_GUI3dObject: SetSnapPointUIDsToObjUIDs: snap point with UID '" + p_snapPointUIDsToObjUID.Key + "' is already snapped to object with UID '" + m_snapPointUIDsToObjUIDs[p_snapPointUIDsToObjUID.Key] + "'! This call tried to snap it to object with UID '" + p_snapPointUIDsToObjUID.Value + "'");
|
|
}
|
|
}
|
|
|
|
public void SetSnapPointUIDsToObjUIDsAndApplyChanges(Dictionary<string, int> p_snapPointUIDsToObjUIDs)
|
|
{
|
|
SetSnapPointUIDsToObjUIDs(p_snapPointUIDsToObjUIDs);
|
|
foreach (string key in p_snapPointUIDsToObjUIDs.Keys)
|
|
{
|
|
S_SnapToObject value;
|
|
if (m_snapPointUIDsToSnapPoints.TryGetValue(key, out value))
|
|
{
|
|
if (value.SnapCounter == 0)
|
|
{
|
|
value.IncSnapCounter();
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning("LE_GUI3dObject: SetSnapPointUIDsToObjUIDsAndApplyChanges: snap point with UID '" + key + "' already was snapped!");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void AddSnapPoint(string p_snapPointUID, S_SnapToObject p_snapInstance)
|
|
{
|
|
if (!m_snapPointUIDsToSnapPoints.ContainsKey(p_snapPointUID))
|
|
{
|
|
m_snapPointUIDsToSnapPoints.Add(p_snapPointUID, p_snapInstance);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("LE_GUI3dObject: AddSnapPoint: a snap point instance with the UID '" + p_snapPointUID + "' already exists!");
|
|
}
|
|
}
|
|
|
|
public void LoadSnapCounter(string snapPointUID, S_SnapToObject snapInstance)
|
|
{
|
|
if (m_snapPointUIDsToObjUIDs.ContainsKey(snapPointUID))
|
|
{
|
|
snapInstance.IncSnapCounter();
|
|
}
|
|
}
|
|
|
|
public List<KeyValuePair<string, int>> GetSnapPointsToReactivate(int p_deletedObjectUID, int p_deletedObjectSnapPointCount)
|
|
{
|
|
List<KeyValuePair<string, int>> list = new List<KeyValuePair<string, int>>();
|
|
for (int i = 0; i < p_deletedObjectSnapPointCount; i++)
|
|
{
|
|
string snapPointUID = LE_LogicObjects.GetSnapPointUID(p_deletedObjectUID, i);
|
|
if (m_snapPointUIDsToObjUIDs.ContainsKey(snapPointUID))
|
|
{
|
|
list.Add(new KeyValuePair<string, int>(snapPointUID, m_snapPointUIDsToObjUIDs[snapPointUID]));
|
|
}
|
|
}
|
|
foreach (KeyValuePair<string, int> snapPointUIDsToObjUID in m_snapPointUIDsToObjUIDs)
|
|
{
|
|
if (snapPointUIDsToObjUID.Value == p_deletedObjectUID)
|
|
{
|
|
list.Add(new KeyValuePair<string, int>(snapPointUIDsToObjUID.Key, p_deletedObjectUID));
|
|
}
|
|
}
|
|
return list;
|
|
}
|
|
|
|
public void ReactivateSnapPoints(int p_deletedObjectUID, int p_deletedObjectSnapPointCount)
|
|
{
|
|
List<KeyValuePair<string, int>> snapPointsToReactivate = GetSnapPointsToReactivate(p_deletedObjectUID, p_deletedObjectSnapPointCount);
|
|
foreach (KeyValuePair<string, int> item in snapPointsToReactivate)
|
|
{
|
|
if (m_snapPointUIDsToSnapPoints.ContainsKey(item.Key))
|
|
{
|
|
m_snapPointUIDsToSnapPoints[item.Key].DecSnapCounter();
|
|
}
|
|
m_snapPointUIDsToObjUIDs.Remove(item.Key);
|
|
}
|
|
m_snapPointUIDToSnapPointsInvalidatedFrame = Time.frameCount;
|
|
}
|
|
|
|
public void MarkSnapPointAsUsed(LE_Object p_sourceObj, LE_Object p_destinationObj, S_SnapToObject p_snapScript)
|
|
{
|
|
if (p_sourceObj != null)
|
|
{
|
|
int snapPointIndex = GetSnapPointIndex(p_sourceObj, p_snapScript);
|
|
MarkSnapPointAsUsed(p_sourceObj, p_destinationObj, snapPointIndex);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("LE_GUI3dObject: MarkSnapPointAsUsed: could not find LE_Object of snap source!");
|
|
}
|
|
}
|
|
|
|
public void MarkSnapPointAsUsed(LE_Object p_sourceObj, LE_Object p_destinationObj, int snapPointIndex)
|
|
{
|
|
if (p_sourceObj != null)
|
|
{
|
|
if (snapPointIndex != -1)
|
|
{
|
|
string text = p_sourceObj.UID + "_" + snapPointIndex;
|
|
if (!m_snapPointUIDsToObjUIDs.ContainsKey(text))
|
|
{
|
|
m_snapPointUIDsToObjUIDs.Add(text, p_destinationObj.UID);
|
|
return;
|
|
}
|
|
Debug.LogError("LE_GUI3dObject: MarkSnapPointAsUsed: duplicate snapping on snapPointUID(" + text + ") new (ignored) objID(" + p_destinationObj.UID + ") and old objID(" + m_snapPointUIDsToObjUIDs[text] + ")");
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("LE_GUI3dObject: MarkSnapPointAsUsed: could not find LE_ObjectSnapPoint of snap source!");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("LE_GUI3dObject: MarkSnapPointAsUsed: could not find LE_Object of snap source!");
|
|
}
|
|
}
|
|
|
|
public void ClearLevelData()
|
|
{
|
|
m_snapPointUIDsToSnapPoints.Clear();
|
|
m_snapPointUIDsToObjUIDs.Clear();
|
|
m_isSnapToObjectActive = true;
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
if (LE_GUIInterface.Instance.delegates.IsObjectDragged == null)
|
|
{
|
|
Debug.LogError("LE_GUI3dObject: you must provide the LE_GUIInterface.delegates.IsObjectDragged to make the object drag&drop working!");
|
|
}
|
|
if (LE_GUIInterface.Instance.delegates.SetDraggableObjectMessage == null)
|
|
{
|
|
Debug.LogWarning("LE_GUI3dObject: LE_GUIInterface.delegates.SetDraggableObjectMessage is not set. Set it if you want to visualize the 'max. # reached!' message or messages generated via LE_ObjectDragEvent.");
|
|
}
|
|
if (LE_GUIInterface.Instance.delegates.SetDraggableObjectState == null)
|
|
{
|
|
Debug.LogWarning("LE_GUI3dObject: LE_GUIInterface.delegates.SetDraggableObjectState is not set. Set it if you want to hide your UI when a 3d preview is shown or show different UI if the object is not placeable.");
|
|
}
|
|
S_SnapToObject.OnGlobalBeforeObjectSnapped = (EventHandler<S_SnapToObjectBeforePlacementEventArgs>)Delegate.Combine(S_SnapToObject.OnGlobalBeforeObjectSnapped, new EventHandler<S_SnapToObjectBeforePlacementEventArgs>(OnBeforeObjectSnapped));
|
|
S_SnapToObject.OnGlobalPreviewObjectInstantiated = (EventHandler<S_SnapToObjectEventArgs>)Delegate.Combine(S_SnapToObject.OnGlobalPreviewObjectInstantiated, new EventHandler<S_SnapToObjectEventArgs>(OnPreviewObjectInstantiated));
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
S_SnapToObject.OnGlobalBeforeObjectSnapped = (EventHandler<S_SnapToObjectBeforePlacementEventArgs>)Delegate.Remove(S_SnapToObject.OnGlobalBeforeObjectSnapped, new EventHandler<S_SnapToObjectBeforePlacementEventArgs>(OnBeforeObjectSnapped));
|
|
S_SnapToObject.OnGlobalPreviewObjectInstantiated = (EventHandler<S_SnapToObjectEventArgs>)Delegate.Remove(S_SnapToObject.OnGlobalPreviewObjectInstantiated, new EventHandler<S_SnapToObjectEventArgs>(OnPreviewObjectInstantiated));
|
|
}
|
|
|
|
private void OnPreviewObjectInstantiated(object p_sender, S_SnapToObjectEventArgs p_args)
|
|
{
|
|
LE_Object component = p_args.NewInstance.GetComponent<LE_Object>();
|
|
if (component != null)
|
|
{
|
|
UnityEngine.Object.Destroy(component);
|
|
}
|
|
}
|
|
|
|
private void OnBeforeObjectSnapped(object p_sender, S_SnapToObjectBeforePlacementEventArgs p_args)
|
|
{
|
|
p_args.IsDelayedPlacePrefab = true;
|
|
LE_Object componentInParent = p_args.Source.GetComponentInParent<LE_Object>();
|
|
int snapPointIndex = GetSnapPointIndex(componentInParent, p_args.Source);
|
|
if (snapPointIndex >= 0)
|
|
{
|
|
UR_CommandMgr.Instance.Execute(new LE_CmdSnapObjectToObject(this, componentInParent.UID, snapPointIndex, p_args.SnapPrefab));
|
|
}
|
|
}
|
|
|
|
private int GetSnapPointIndex(LE_Object p_obj, S_SnapToObject p_snapScript)
|
|
{
|
|
if (p_obj != null)
|
|
{
|
|
for (int i = 0; i < p_obj.ObjectSnapPoints.Length; i++)
|
|
{
|
|
if (p_obj.ObjectSnapPoints[i].SnapSystemInstance == p_snapScript)
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
Debug.LogError("LE_GUI3dObject: GetSnapPointIndex: p_snapScript is not a SnapSystemInstance of p_obj!");
|
|
return -1;
|
|
}
|
|
Debug.LogError("LE_GUI3dObject: GetSnapPointIndex: p_obj is null!");
|
|
return -1;
|
|
}
|
|
|
|
private bool IsObjectPlaceable()
|
|
{
|
|
if (m_object != null)
|
|
{
|
|
if (!IsObjectPlaceable(m_object, m_objectResourcePath))
|
|
{
|
|
m_dragMessage = "max. # reached!";
|
|
SetDragMessageInUI();
|
|
return false;
|
|
}
|
|
m_dragMessage = string.Empty;
|
|
SetDragMessageInUI();
|
|
return true;
|
|
}
|
|
m_isSceneInstanceFound = false;
|
|
return false;
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
UpdateObjectSelection();
|
|
UpdateNewObjectDragAndDrop();
|
|
UpdateSmartMove();
|
|
UpdateSnapToObjectInstances();
|
|
if (FisheryEditor.Instance.allowKeyboardInput)
|
|
{
|
|
if (m_isKeyComboFocus && Input.GetKeyDown(KeyCode.F))
|
|
{
|
|
Focus();
|
|
}
|
|
if (m_isKeyComboDelete && Input.GetKeyDown(KeyCode.Delete))
|
|
{
|
|
Delete();
|
|
}
|
|
}
|
|
m_isCursorActionInThisFrame = false;
|
|
}
|
|
|
|
private void OnGUI()
|
|
{
|
|
if (FisheryEditor.Instance.allowKeyboardInput && m_isKeyComboDuplicate)
|
|
{
|
|
Event current = Event.current;
|
|
if (current.type == EventType.KeyUp && current.control && current.keyCode == KeyCode.D)
|
|
{
|
|
CloneObject();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void UpdateObjectSelection()
|
|
{
|
|
bool isCursorOverSomething = base.IsCursorOverSomething;
|
|
if (m_previewInstance == null && !IsObjectDraggedInUI())
|
|
{
|
|
if (!base.IsInteractable)
|
|
{
|
|
m_isCursorAction = isCursorOverSomething;
|
|
m_isSelectionPossible = false;
|
|
}
|
|
else if (!m_isCursorAction && m_isCursorActionInThisFrame)
|
|
{
|
|
if (isCursorOverSomething)
|
|
{
|
|
m_cursorActionOnObject = m_cursorHitInfo.collider.GetComponentInParent<LE_Object>();
|
|
}
|
|
else
|
|
{
|
|
m_cursorActionOnObject = null;
|
|
}
|
|
m_lastCursorActionStartPos = m_cursorScreenCoords;
|
|
m_isSelectionPossible = true;
|
|
m_isCursorAction = true;
|
|
}
|
|
else if (m_isCursorAction && m_isCursorActionInThisFrame)
|
|
{
|
|
if ((!isCursorOverSomething && m_cursorActionOnObject != null) || (isCursorOverSomething && m_cursorActionOnObject != m_cursorHitInfo.collider.GetComponentInParent<LE_Object>()) || (double)(m_lastCursorActionStartPos - m_cursorScreenCoords).magnitude > (double)Screen.height * 0.025)
|
|
{
|
|
m_isSelectionPossible = false;
|
|
m_cursorActionOnObject = null;
|
|
}
|
|
}
|
|
else if (m_isCursorAction && !m_isCursorActionInThisFrame)
|
|
{
|
|
if (m_isSelectionPossible)
|
|
{
|
|
if (m_cursorActionOnObject == null)
|
|
{
|
|
m_cursorActionOnObject = TrySelectByOversizedBoundingVolume();
|
|
}
|
|
SelectObject(m_cursorActionOnObject);
|
|
}
|
|
m_isSelectionPossible = false;
|
|
m_cursorActionOnObject = null;
|
|
m_isCursorAction = false;
|
|
}
|
|
else
|
|
{
|
|
m_cursorActionOnObject = null;
|
|
m_isCursorAction = false;
|
|
}
|
|
}
|
|
if (m_selectedObject != null)
|
|
{
|
|
m_selectedObject.EditSpace = m_objectEditSpace;
|
|
m_selectedObject.EditMode = m_objectEditMode;
|
|
}
|
|
}
|
|
|
|
private void UpdateNewObjectDragAndDrop()
|
|
{
|
|
FisheryEditor.Instance.fakeDragCollisionObject.SetActive(Input.GetKey(KeyCode.Mouse0) && m_object != null && m_objectResourcePath != null && IsObjectDraggedInUI());
|
|
Vector3 position = FisheryEditor.Instance.fakeDragCollisionObject.transform.position;
|
|
position.y = Camera.main.transform.position.y - 3f;
|
|
if (position.y > FisheryEditor.Instance.waterObject.transform.position.y - 1f)
|
|
{
|
|
position.y = FisheryEditor.Instance.waterObject.transform.position.y - 1f;
|
|
}
|
|
FisheryEditor.Instance.fakeDragCollisionObject.transform.position = position;
|
|
if (!(m_object != null) || m_objectResourcePath == null)
|
|
{
|
|
return;
|
|
}
|
|
SetDragMessageInUI();
|
|
if (!base.IsInteractable)
|
|
{
|
|
if (m_previewInstance != null)
|
|
{
|
|
UnityEngine.Object.Destroy(m_previewInstance.gameObject);
|
|
}
|
|
}
|
|
else if (base.IsCursorOverSomething)
|
|
{
|
|
if (IsObjectDraggedInUI())
|
|
{
|
|
if (OnObjectDrag() && ((m_object.SnapType != LE_Object.ESnapType.SNAP_TO_TERRAIN && m_object.SnapType != LE_Object.ESnapType.SNAP_TO_2D_GRID_AND_TERRAIN) || (m_cursorHitInfo.collider != null && m_cursorHitInfo.collider.gameObject.layer == TERRAIN_LAYER)))
|
|
{
|
|
if (m_previewInstance == null)
|
|
{
|
|
m_previewInstance = UnityEngine.Object.Instantiate(m_object);
|
|
m_previewInstance.name = "LE_GUI3dObject Preview Instance";
|
|
MoveToLayer(m_previewInstance.transform, LayerMask.NameToLayer("Ignore Raycast"));
|
|
Rigidbody[] componentsInChildren = m_previewInstance.GetComponentsInChildren<Rigidbody>();
|
|
for (int i = 0; i < componentsInChildren.Length; i++)
|
|
{
|
|
UnityEngine.Object.Destroy(componentsInChildren[i]);
|
|
}
|
|
if (m_previewInstance.SnapType == LE_Object.ESnapType.SNAP_TO_3D_GRID || m_previewInstance.SnapType == LE_Object.ESnapType.SNAP_TO_2D_GRID_AND_TERRAIN)
|
|
{
|
|
LE_LogicObjects.AddGridSnapping(this, m_previewInstance, true);
|
|
}
|
|
}
|
|
SmartMove(m_previewInstance);
|
|
}
|
|
}
|
|
else if (m_isObjectPlaceable)
|
|
{
|
|
PlaceObject();
|
|
}
|
|
else if (m_previewInstance != null)
|
|
{
|
|
UnityEngine.Object.Destroy(m_previewInstance.gameObject);
|
|
}
|
|
}
|
|
else if (m_previewInstance != null)
|
|
{
|
|
UnityEngine.Object.Destroy(m_previewInstance.gameObject);
|
|
}
|
|
if (LE_GUIInterface.Instance.delegates.SetDraggableObjectState != null)
|
|
{
|
|
if (!base.IsInteractable || !IsObjectDraggedInUI())
|
|
{
|
|
LE_GUIInterface.Instance.delegates.SetDraggableObjectState(LE_GUIInterface.Delegates.EDraggedObjectState.NONE);
|
|
}
|
|
else if (m_previewInstance != null)
|
|
{
|
|
LE_GUIInterface.Instance.delegates.SetDraggableObjectState(LE_GUIInterface.Delegates.EDraggedObjectState.IN_3D_PREVIEW);
|
|
}
|
|
else
|
|
{
|
|
LE_GUIInterface.Instance.delegates.SetDraggableObjectState(LE_GUIInterface.Delegates.EDraggedObjectState.NOT_PLACEABLE);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void UpdateSmartMove()
|
|
{
|
|
if (base.IsCursorOverSomething && IsSelectedObjectSmartMoved && ((m_selectedObject.SnapType != LE_Object.ESnapType.SNAP_TO_TERRAIN && m_selectedObject.SnapType != LE_Object.ESnapType.SNAP_TO_2D_GRID_AND_TERRAIN) || (m_cursorHitInfo.collider != null && m_cursorHitInfo.collider.gameObject.layer == TERRAIN_LAYER)))
|
|
{
|
|
SmartMove(m_selectedObject);
|
|
}
|
|
}
|
|
|
|
private void SmartMove(LE_Object p_obj)
|
|
{
|
|
p_obj.transform.position = m_cursorHitInfo.point;
|
|
if (p_obj.SnapType == LE_Object.ESnapType.SNAP_TO_3D_GRID || p_obj.SnapType == LE_Object.ESnapType.SNAP_TO_2D_GRID_AND_TERRAIN)
|
|
{
|
|
p_obj.transform.position += m_cursorHitInfo.normal * 0.005f;
|
|
}
|
|
if (p_obj.IsPlacementRotationByNormal)
|
|
{
|
|
p_obj.transform.up = m_cursorHitInfo.normal;
|
|
}
|
|
}
|
|
|
|
private void UpdateSnapToObjectInstances()
|
|
{
|
|
bool flag = !m_isSnapToObjectActive && base.IsInteractable;
|
|
if (!flag && (!m_isSnapToObjectActive || base.IsInteractable) && m_snapPointUIDToSnapPointsInvalidatedFrame != Time.frameCount - 1)
|
|
{
|
|
return;
|
|
}
|
|
m_isSnapToObjectActive = flag;
|
|
List<string> list = new List<string>();
|
|
Dictionary<string, S_SnapToObject>.KeyCollection keys = m_snapPointUIDsToSnapPoints.Keys;
|
|
foreach (string item in keys)
|
|
{
|
|
if (m_snapPointUIDsToSnapPoints[item] != null)
|
|
{
|
|
if (!flag || m_snapPointUIDsToSnapPoints[item].SnapCounter == 0)
|
|
{
|
|
m_snapPointUIDsToSnapPoints[item].gameObject.SetActive(flag);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
list.Add(item);
|
|
}
|
|
}
|
|
foreach (string item2 in list)
|
|
{
|
|
m_snapPointUIDsToSnapPoints.Remove(item2);
|
|
}
|
|
}
|
|
|
|
private LE_Object TrySelectByOversizedBoundingVolume()
|
|
{
|
|
List<LE_Object> list = new List<LE_Object>();
|
|
List<float> list2 = new List<float>();
|
|
LE_Object[] array = UnityEngine.Object.FindObjectsOfType<LE_Object>();
|
|
for (int i = 0; i < array.Length; i++)
|
|
{
|
|
Vector3 o_min;
|
|
Vector3 o_max;
|
|
if (GetMinMaxBounds(array[i], out o_min, out o_max))
|
|
{
|
|
float num = 1f;
|
|
float magnitude = (array[i].transform.position - Camera.main.transform.position).magnitude;
|
|
Vector3 vector = new Vector3
|
|
{
|
|
x = Mathf.Abs(o_max.x - o_min.x),
|
|
y = Mathf.Abs(o_max.y - o_min.y),
|
|
z = Mathf.Abs(o_max.z - o_min.z)
|
|
};
|
|
float magnitude2 = vector.magnitude;
|
|
Vector3 rhs = Vector3.one * 10f + vector;
|
|
if (magnitude > 50f)
|
|
{
|
|
num = 2.25f;
|
|
vector = Vector3.Max(vector, Vector3.one * 1.5f);
|
|
}
|
|
else if (magnitude > 25f)
|
|
{
|
|
num = 1.85f;
|
|
vector = Vector3.Max(vector, Vector3.one);
|
|
}
|
|
else if (magnitude > 15f)
|
|
{
|
|
num = 1.5f;
|
|
vector = Vector3.Max(vector, Vector3.one * 0.5f);
|
|
}
|
|
vector = Vector3.Min(vector * num, rhs);
|
|
if (new Bounds((o_max + o_min) * 0.5f, vector).IntersectRay(m_cursorRay))
|
|
{
|
|
list.Add(array[i]);
|
|
list2.Add(magnitude2);
|
|
}
|
|
}
|
|
}
|
|
if (list.Count > 0)
|
|
{
|
|
LE_Object result = list[0];
|
|
float num2 = list2[0];
|
|
for (int j = 1; j < list.Count; j++)
|
|
{
|
|
if (list2[j] < num2)
|
|
{
|
|
result = list[j];
|
|
num2 = list2[j];
|
|
}
|
|
}
|
|
float num3 = 9999999f;
|
|
for (int k = 0; k < list.Count; k++)
|
|
{
|
|
if (list2[k] <= num2 * 1.25f)
|
|
{
|
|
float magnitude3 = Vector3.Cross(m_cursorRay.direction, list[k].transform.position - m_cursorRay.origin).magnitude;
|
|
if (num3 > magnitude3)
|
|
{
|
|
num3 = magnitude3;
|
|
result = list[k];
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private bool GetMinMaxBounds(LE_Object p_object, out Vector3 o_min, out Vector3 o_max)
|
|
{
|
|
o_min = Vector3.one * 9999999f;
|
|
o_max = -Vector3.one * 9999999f;
|
|
Collider[] componentsInChildren = p_object.GetComponentsInChildren<Collider>();
|
|
if (componentsInChildren.Length > 0)
|
|
{
|
|
bool result = false;
|
|
for (int i = 0; i < componentsInChildren.Length; i++)
|
|
{
|
|
if (componentsInChildren[i].GetComponent<LE_ObjectEditHandleCollider>() == null)
|
|
{
|
|
result = true;
|
|
Bounds bounds = componentsInChildren[i].bounds;
|
|
o_min = Vector3.Min(o_min, bounds.min);
|
|
o_max = Vector3.Max(o_max, bounds.max);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private void PlaceObject()
|
|
{
|
|
if (m_previewInstance != null)
|
|
{
|
|
UnityEngine.Object.Destroy(m_previewInstance.gameObject);
|
|
UR_CommandMgr.Instance.Execute(new LE_CmdPlaceObject(this, m_object, m_previewInstance.transform, m_objectResourcePath));
|
|
}
|
|
}
|
|
|
|
private void MoveToLayer(Transform root, int layer, Dictionary<GameObject, int> layerBuffer = null)
|
|
{
|
|
if (layerBuffer != null)
|
|
{
|
|
layerBuffer.Add(root.gameObject, root.gameObject.layer);
|
|
}
|
|
root.gameObject.layer = layer;
|
|
foreach (Transform item in root)
|
|
{
|
|
MoveToLayer(item, layer, layerBuffer);
|
|
}
|
|
}
|
|
|
|
private bool OnObjectDrag()
|
|
{
|
|
bool isObjectPlaceable = m_isObjectPlaceable;
|
|
if (LE_EventInterface.OnObjectDragged != null)
|
|
{
|
|
LE_ObjectDragEvent lE_ObjectDragEvent = new LE_ObjectDragEvent(m_object, m_previewInstance, m_isObjectPlaceable, m_dragMessage, m_cursorHitInfo);
|
|
LE_EventInterface.OnObjectDragged(this, lE_ObjectDragEvent);
|
|
isObjectPlaceable = lE_ObjectDragEvent.IsObjectPlaceable;
|
|
SetDragMessageInUI(lE_ObjectDragEvent.Message);
|
|
}
|
|
if (!isObjectPlaceable && m_previewInstance != null)
|
|
{
|
|
UnityEngine.Object.Destroy(m_previewInstance.gameObject);
|
|
}
|
|
return isObjectPlaceable;
|
|
}
|
|
|
|
private void SetDragMessageInUI()
|
|
{
|
|
SetDragMessageInUI(m_dragMessage);
|
|
}
|
|
|
|
private void SetDragMessageInUI(string p_message)
|
|
{
|
|
if (LE_GUIInterface.Instance.delegates.SetDraggableObjectMessage != null)
|
|
{
|
|
LE_GUIInterface.Instance.delegates.SetDraggableObjectMessage(m_dragMessage);
|
|
}
|
|
}
|
|
|
|
private bool IsObjectDraggedInUI()
|
|
{
|
|
if (LE_GUIInterface.Instance.delegates.IsObjectDragged != null)
|
|
{
|
|
return LE_GUIInterface.Instance.delegates.IsObjectDragged();
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
}
|