init
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 82fc4c0e14e4428c94d80ad7d8f3478f
|
||||
timeCreated: 1760365090
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "RPGCoreCommon.Select.Editor",
|
||||
"rootNamespace": "RPGCoreCommon.Select.Editor",
|
||||
"references": [
|
||||
"RPGCoreCommon.Select"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d5409c4df0ac49708b21e8a873cd579f
|
||||
timeCreated: 1760365113
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 67a0be04866b4bcb839c1cd59382d984
|
||||
timeCreated: 1760365094
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace RPGCoreCommon.Select
|
||||
{
|
||||
public interface ISelectableUI
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 66449a5b73074169bc67a4d588153bb3
|
||||
timeCreated: 1760365219
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "RPGCoreCommon.Select",
|
||||
"rootNamespace": "RPGCoreCommon.Select",
|
||||
"references": [
|
||||
"RPGCoreCommon.Settings",
|
||||
"Unity.InputSystem"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c350403567f6400a9fa854add1fded97
|
||||
timeCreated: 1760365117
|
||||
@@ -0,0 +1,115 @@
|
||||
using System;
|
||||
using RPGCoreCommon.Settings;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.UIElements;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace RPGCoreCommon.Select
|
||||
{
|
||||
public static class Select
|
||||
{
|
||||
private static IRuntimePanel _panel;
|
||||
|
||||
private static IRuntimePanel GetPanel()
|
||||
{
|
||||
if (_panel != null) return _panel;
|
||||
|
||||
const string documentUITag = "MainUIDocument";
|
||||
UIDocument uiDocument = null;
|
||||
|
||||
try
|
||||
{
|
||||
// FIND BY TAG
|
||||
var go = GameObject.FindWithTag(documentUITag);
|
||||
if (go) uiDocument = go.GetComponent<UIDocument>();
|
||||
}
|
||||
catch (UnityException)
|
||||
{
|
||||
Debug.LogError($"Tag {documentUITag} not found! Please add it to the project.");
|
||||
}
|
||||
|
||||
// FIND ANY UI DOCUMENT
|
||||
if (!uiDocument)
|
||||
{
|
||||
Debug.LogWarning($"Found no {nameof(UIDocument)} with tag '{documentUITag}', started looking for any on scene...");
|
||||
uiDocument = Object.FindAnyObjectByType<UIDocument>();
|
||||
}
|
||||
|
||||
// PANEL NOT FOUND
|
||||
if (!uiDocument)
|
||||
{
|
||||
Debug.LogError($"Current scene has no {nameof(UIDocument)}! {nameof(Select)} won't work with UI!");
|
||||
return null;
|
||||
}
|
||||
|
||||
_panel = uiDocument.runtimePanel;
|
||||
return _panel;
|
||||
}
|
||||
|
||||
/// <summary>Get <see cref="GetFromUI"/> and if nothing selected then get <see cref="GetFromScene"/> instead.</summary>
|
||||
public static SelectUtilResult Get()
|
||||
{
|
||||
if (GetFromUI() is { hit: SelectType.UI } fromUI) return fromUI;
|
||||
if (GetFromScene() is { hit: SelectType.Scene } fromScene) return fromScene;
|
||||
return new SelectUtilResult();
|
||||
}
|
||||
|
||||
/// <summary>Try to select anything from given position on UI that extends <see cref="ISelectableUI"/></summary>
|
||||
public static SelectUtilResult GetFromUI()
|
||||
{
|
||||
var mousePos = Mouse.current.position.ReadValue();
|
||||
mousePos.y = Screen.height - mousePos.y;
|
||||
var mousePosOnUI = RuntimePanelUtils.ScreenToPanel(GetPanel(), mousePos);
|
||||
|
||||
return new SelectUtilResult(mousePosOnUI, GetPanel().Pick(mousePosOnUI));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TComponent is <see cref="Rigidbody"/> by default if not provided.<br/>
|
||||
/// <inheritdoc cref="GetFromScene{TComponent}"/>
|
||||
/// </summary>
|
||||
public static SelectUtilResult GetFromScene()
|
||||
{
|
||||
return GetFromScene<Rigidbody>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to select <see cref="GameObject"/> with component of given type '<typeparamref name="TComponent"/>' in self or in any parent.
|
||||
/// If not found then gets <see cref="Collider"/>'s <see cref="GameObject"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TComponent">Type of component to look for</typeparam>
|
||||
public static SelectUtilResult GetFromScene<TComponent>() where TComponent : Component
|
||||
{
|
||||
var hit = SelectHit();
|
||||
|
||||
// Nothing hit - clicked void?
|
||||
if (!hit.collider) return new SelectUtilResult();
|
||||
|
||||
var component = hit.collider.gameObject.GetComponentInParent<TComponent>();
|
||||
|
||||
// Wanted component not found - get GameObject from Collider
|
||||
if (!component) return new SelectUtilResult(hit.point, hit.collider.gameObject);
|
||||
|
||||
return new SelectUtilResult(hit.point, component.gameObject, component);
|
||||
}
|
||||
|
||||
/// <summary>Returns Vector3 of clicked position</summary>
|
||||
public static Vector3 SelectPosition()
|
||||
{
|
||||
return SelectHit().point;
|
||||
}
|
||||
|
||||
/// <summary>Returns <see cref="RaycastHit"/> of clicked position</summary>
|
||||
public static RaycastHit SelectHit()
|
||||
{
|
||||
Physics.Raycast(
|
||||
Camera.main.ScreenPointToRay(Mouse.current.position.ReadValue()),
|
||||
out var hit,
|
||||
Mathf.Infinity,
|
||||
SettingsManager.Get<SelectSettings>().collisionLayerMask);
|
||||
|
||||
return hit;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b9a458dd78d9450a9693ccc50b33458f
|
||||
timeCreated: 1760365381
|
||||
@@ -0,0 +1,64 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace RPGCoreCommon.Select
|
||||
{
|
||||
/// <summary>
|
||||
/// Result of using <see cref="Select"/>. Contains information what was clicked in a moment of execution.
|
||||
/// </summary>
|
||||
public class SelectUtilResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Source of selection:
|
||||
/// <ul>
|
||||
/// <li><see cref="SelectType.None"/> - probably pressed void, so nothing to select</li>
|
||||
/// <li><see cref="SelectType.Scene"/> - something from scene (GameObject and/or Component)</li>
|
||||
/// <li><see cref="SelectType.UI"/> - something from UI</li>
|
||||
/// </ul>
|
||||
/// </summary>
|
||||
public SelectType hit { get; private set; }
|
||||
|
||||
/// <summary>UI only: select position on UI</summary>
|
||||
public Vector2 uiPosition { get; private set; }
|
||||
/// <summary>UI only: All that extends <see cref="ISelectableUI"/>. Can be VisualElement itself, its userData or its dataSource.</summary>
|
||||
public List<ISelectableUI> uiSelectables { get; private set; } = new();
|
||||
/// <summary>UI only: first from <see cref="uiSelectables"/></summary>
|
||||
public ISelectableUI uiSelectable => uiSelectables.FirstOrDefault();
|
||||
|
||||
/// <summary>Scene only: select position on scene</summary>
|
||||
public Vector3 position { get; private set; }
|
||||
/// <summary>Scene only: selected GameObject</summary>
|
||||
public GameObject gameObject { get; private set; }
|
||||
/// <summary>Scene only: selected GameObject's Component</summary>
|
||||
public Component component { get; private set; }
|
||||
|
||||
internal SelectUtilResult(Vector3 position, GameObject gameObject = null, Component component = null)
|
||||
{
|
||||
hit = SelectType.Scene;
|
||||
this.position = position;
|
||||
this.gameObject = gameObject;
|
||||
this.component = component;
|
||||
}
|
||||
|
||||
internal SelectUtilResult(Vector2 uiPosition, VisualElement visualElement = null)
|
||||
{
|
||||
hit = visualElement == null ? SelectType.None : SelectType.UI;
|
||||
this.uiPosition = uiPosition;
|
||||
|
||||
while (visualElement != null)
|
||||
{
|
||||
if (visualElement is ISelectableUI iSelectableUI) uiSelectables.Add(iSelectableUI);
|
||||
else if (visualElement.dataSource is ISelectableUI dataSource) uiSelectables.Add(dataSource);
|
||||
else if (visualElement.userData is ISelectableUI userData) uiSelectables.Add(userData);
|
||||
visualElement = visualElement.parent;
|
||||
}
|
||||
}
|
||||
|
||||
internal SelectUtilResult()
|
||||
{
|
||||
hit = SelectType.None;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9195520c15f84eb285d576bd02f19fc5
|
||||
timeCreated: 1760368780
|
||||
@@ -0,0 +1,13 @@
|
||||
using RPGCoreCommon.Settings;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace RPGCoreCommon.Select
|
||||
{
|
||||
[CustomSettings("Tools/Select")]
|
||||
public class SelectSettings : CustomSettingsSO
|
||||
{
|
||||
public PanelSettings uiPanelSettings;
|
||||
public LayerMask collisionLayerMask = ~0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a220227e1d0c4485bedf7a577301a9b7
|
||||
timeCreated: 1760366831
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace RPGCoreCommon.Select
|
||||
{
|
||||
public enum SelectType
|
||||
{
|
||||
None,
|
||||
Scene,
|
||||
UI,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 51591d593b9b436ba9151be598ef5898
|
||||
timeCreated: 1760371617
|
||||
Reference in New Issue
Block a user