Last active
September 2, 2024 02:26
-
-
Save JohnnyTurbo/b46d383389f5615682ac713046ff8277 to your computer and use it in GitHub Desktop.
Code used in ECS Single Unit Selection tutorial video on the Turbo Makes Games YouTube Channel - https://youtu.be/x8pVhWCewjU
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
using System; | |
namespace TMG.UnitSelection | |
{ | |
[Flags] | |
public enum CollisionLayers | |
{ | |
Selection = 1 << 0, | |
Ground = 1 << 1, | |
Units = 1 << 2 | |
} | |
} |
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
using Unity.Entities; | |
namespace TMG.UnitSelection | |
{ | |
[GenerateAuthoringComponent] | |
public struct SelectableUnitTag : IComponentData | |
{ | |
} | |
} |
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
using Unity.Entities; | |
namespace TMG.UnitSelection | |
{ | |
public struct SelectedEntityTag : IComponentData{} | |
} |
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
using Unity.Entities; | |
namespace TMG.UnitSelection | |
{ | |
[GenerateAuthoringComponent] | |
public struct SelectionUIPrefab : IComponentData | |
{ | |
public Entity Value; | |
} | |
} |
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
using Unity.Entities; | |
using Unity.Mathematics; | |
using Unity.Transforms; | |
namespace TMG.UnitSelection | |
{ | |
public struct SelectionRingStateData : ISystemStateComponentData | |
{ | |
public Entity SelectionUI; | |
} | |
[UpdateAfter(typeof(UnitSelectionSystem))] | |
public class SpawnSelectionRingSystem : SystemBase | |
{ | |
private SelectionUIPrefab _selectionUIPrefab; | |
private EndSimulationEntityCommandBufferSystem _endSimulationEntityCommandBufferSystem; | |
protected override void OnStartRunning() | |
{ | |
_selectionUIPrefab = GetSingleton<SelectionUIPrefab>(); | |
_endSimulationEntityCommandBufferSystem = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>(); | |
} | |
protected override void OnUpdate() | |
{ | |
var ecb = _endSimulationEntityCommandBufferSystem.CreateCommandBuffer(); | |
var selectionPrefab = _selectionUIPrefab.Value; | |
Entities | |
.WithAll<SelectedEntityTag>() | |
.WithNone<SelectionRingStateData>() | |
.ForEach((Entity selectedEntity) => | |
{ | |
var selectionUI = ecb.Instantiate(selectionPrefab); | |
var newSelectionStateData = new SelectionRingStateData() | |
{ | |
SelectionUI = selectionUI | |
}; | |
ecb.AddComponent<SelectionRingStateData>(selectedEntity); | |
ecb.SetComponent(selectedEntity, newSelectionStateData); | |
ecb.AddComponent<Parent>(selectionUI); | |
ecb.SetComponent(selectionUI, new Parent{Value = selectedEntity}); | |
ecb.AddComponent<LocalToParent>(selectionUI); | |
ecb.SetComponent(selectionUI, new LocalToParent{Value = float4x4.zero}); | |
}).Run(); | |
} | |
} | |
[UpdateAfter(typeof(SpawnSelectionRingSystem))] | |
public class CleanupSelectionRingSystem : SystemBase | |
{ | |
private EndSimulationEntityCommandBufferSystem _endSimulationEntityCommandBufferSystem; | |
protected override void OnCreate() | |
{ | |
_endSimulationEntityCommandBufferSystem = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>(); | |
} | |
protected override void OnUpdate() | |
{ | |
var ecb = _endSimulationEntityCommandBufferSystem.CreateCommandBuffer(); | |
Entities | |
.WithNone<SelectedEntityTag>() | |
.ForEach((Entity e, in SelectionRingStateData selectionStateData) => | |
{ | |
ecb.DestroyEntity(selectionStateData.SelectionUI); | |
ecb.RemoveComponent<SelectionRingStateData>(e); | |
}).Run(); | |
} | |
} | |
} |
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
using Unity.Collections; | |
using Unity.Entities; | |
using Unity.Mathematics; | |
using Unity.Physics; | |
using Unity.Physics.Systems; | |
using Unity.Transforms; | |
using UnityEngine; | |
using RaycastHit = Unity.Physics.RaycastHit; | |
namespace TMG.UnitSelection | |
{ | |
[AlwaysUpdateSystem] | |
public class UnitSelectionSystem : SystemBase | |
{ | |
private Camera _mainCamera; | |
private BuildPhysicsWorld _buildPhysicsWorld; | |
private CollisionWorld _collisionWorld; | |
protected override void OnCreate() | |
{ | |
_mainCamera = Camera.main; | |
_buildPhysicsWorld = World.GetOrCreateSystem<BuildPhysicsWorld>(); | |
} | |
protected override void OnUpdate() | |
{ | |
if (Input.GetMouseButtonUp(0)) | |
{ | |
if (!Input.GetKey(KeyCode.LeftShift)) | |
{ | |
DeselectUnits(); | |
} | |
SelectSingleUnit(); | |
} | |
} | |
private void DeselectUnits() | |
{ | |
EntityManager.RemoveComponent<SelectedEntityTag>(GetEntityQuery(typeof(SelectedEntityTag))); | |
} | |
private void SelectSingleUnit() | |
{ | |
_collisionWorld = _buildPhysicsWorld.PhysicsWorld.CollisionWorld; | |
var ray = _mainCamera.ScreenPointToRay(Input.mousePosition); | |
var rayStart = ray.origin; | |
var rayEnd = ray.GetPoint(100f); | |
if (Raycast(rayStart, rayEnd, out var raycastHit)) | |
{ | |
var hitEntity = _buildPhysicsWorld.PhysicsWorld.Bodies[raycastHit.RigidBodyIndex].Entity; | |
if (EntityManager.HasComponent<SelectableUnitTag>(hitEntity)) | |
{ | |
EntityManager.AddComponent<SelectedEntityTag>(hitEntity); | |
} | |
} | |
} | |
private bool Raycast(float3 rayStart, float3 rayEnd, out RaycastHit raycastHit) | |
{ | |
var raycastInput = new RaycastInput | |
{ | |
Start = rayStart, | |
End = rayEnd, | |
Filter = new CollisionFilter | |
{ | |
BelongsTo = (uint) CollisionLayers.Selection, | |
CollidesWith = (uint) (CollisionLayers.Ground | CollisionLayers.Units) | |
} | |
}; | |
return _collisionWorld.CastRay(raycastInput, out raycastHit); | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment