using UnityEngine;
using Unity.Mathematics;
using Unity.Entities;
using Unity.Transforms;
using Unity.Rendering;
public class LookAtDoubleClickedEntity : MonoBehaviour
{
void OnEnable ()
{
SelectionSystem.onDoubleClick += OnDoubleClick;
}
void OnDisable ()
{
SelectionSystem.onDoubleClick -= OnDoubleClick;
}
void OnDoubleClick ( Entity entity , EntityManager entityManager )
{
var clickedTransform = entityManager.GetComponentData<LocalToWorld>( entity );
Vector3 clickedPos = clickedTransform.Position;
AABB clickedBounds = entityManager.GetComponentData<WorldRenderBounds>( entity ).Value;
Vector3 clickedCenter = clickedBounds.Center;
Debug.DrawLine( transform.position , clickedBounds.Center , Color.magenta , 5f );
transform.rotation = Quaternion.LookRotation( clickedCenter-transform.position , Vector3.up );
}
}
Last active
August 9, 2023 20:46
-
-
Save andrew-raphael-lukasik/917046557baed6646c9fdc3b40671307 to your computer and use it in GitHub Desktop.
Simple entity selection system
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// src: https://gist.github.com/andrew-raphael-lukasik/917046557baed6646c9fdc3b40671307 | |
using UnityEngine; | |
using Unity.Entities; | |
using Unity.Mathematics; | |
using Unity.Collections; | |
using Unity.Rendering; | |
[UpdateInGroup( typeof(PresentationSystemGroup) )] | |
public class SelectionSystem : SystemBase | |
{ | |
public static event System.Action<Entity,EntityManager> onClick = (clicked,clickedEntityManager)=> | |
{ | |
#if DEBUG | |
Debug.Log($"{clicked} <b>clicked</b>"); | |
#endif | |
}; | |
public static event System.Action<Entity,EntityManager> onDoubleClick = (clicked,clickedEntityManager)=> | |
{ | |
#if DEBUG | |
Debug.Log($"{clicked} <b>double-clicked</b>"); | |
#endif | |
}; | |
const double k_double_click_threshold = 0.5f; | |
public NativeQueue<(Entity entity,float distance)> _hits = new NativeQueue<(Entity,float)>( Allocator.Persistent ); | |
public NativeArray<(Entity entity,double time)> _clicks = new NativeArray<(Entity,double)>( length:2 , Allocator.Persistent ); | |
protected override void OnUpdate () | |
{ | |
if( EntityManager.Exists(_clicks[0].entity) ) | |
{ | |
var click = _clicks[0]; | |
var oldClick = _clicks[1]; | |
if( click.entity==oldClick.entity && (click.time-oldClick.time)<k_double_click_threshold ) | |
onDoubleClick( click.entity , EntityManager ); | |
else | |
onClick( click.entity , EntityManager ); | |
_clicks[1] = click; | |
_clicks[0] = ( Entity.Null , 0f ); | |
} | |
if( Input.GetMouseButtonDown(0) ) | |
{ | |
var ray = Camera.main.ScreenPointToRay( Input.mousePosition ); | |
var hits = _hits; | |
var hits_writer = _hits.AsParallelWriter(); | |
var clicks = _clicks.Slice();// alias | |
double time = Time.ElapsedTime; | |
Entities | |
.WithNone<Disabled,Prefab>() | |
// .WithAll<SELECTABLE>()// uncomment to enable this filter | |
.ForEach( ( in Entity entity , in WorldRenderBounds wrb ) => | |
{ | |
if( wrb.Value.ToBounds().IntersectRay(ray,out float distance) ) | |
hits_writer.Enqueue( (entity,distance) ); | |
}) | |
.WithBurst().Schedule(); | |
Job | |
.WithName("select_best_click_candidate_job") | |
.WithCode( ()=> | |
{ | |
Entity nearest = Entity.Null; | |
float dist = float.MaxValue; | |
while( hits.Count!=0 ) | |
{ | |
var hit = hits.Dequeue(); | |
if( hit.distance<dist ) | |
{ | |
nearest = hit.entity; | |
dist = hit.distance; | |
} | |
} | |
clicks[0] = ( entity:nearest , time:time ); | |
}) | |
.WithBurst().Schedule(); | |
} | |
} | |
protected override void OnDestroy () | |
{ | |
_hits.Dispose(); | |
_clicks.Dispose(); | |
} | |
} | |
// <summary> Tag component to flag selectable entities. </summary> | |
public struct SELECTABLE : IComponentData {} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment