Last active
November 5, 2015 17:59
-
-
Save bdecarne/32c7104f20e33658ddc4 to your computer and use it in GitHub Desktop.
Unity : UnitSelection
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
Shader "Projector/AdditiveTint" { | |
Properties { | |
_Color ("Tint Color", Color) = (1,1,1,1) | |
_Attenuation ("Falloff", Range(0.0, 1.0)) = 1.0 | |
_ShadowTex ("Cookie", 2D) = "gray" {} | |
} | |
Subshader { | |
Tags {"Queue"="Transparent"} | |
Pass { | |
ZWrite Off | |
ColorMask RGB | |
Blend SrcAlpha One // Additive blending | |
Offset -1, -1 | |
CGPROGRAM | |
#pragma vertex vert | |
#pragma fragment frag | |
#include "UnityCG.cginc" | |
struct v2f { | |
float4 uvShadow : TEXCOORD0; | |
float4 pos : SV_POSITION; | |
}; | |
float4x4 _Projector; | |
float4x4 _ProjectorClip; | |
v2f vert (float4 vertex : POSITION) | |
{ | |
v2f o; | |
o.pos = mul (UNITY_MATRIX_MVP, vertex); | |
o.uvShadow = mul (_Projector, vertex); | |
return o; | |
} | |
sampler2D _ShadowTex; | |
fixed4 _Color; | |
float _Attenuation; | |
fixed4 frag (v2f i) : SV_Target | |
{ | |
// Apply alpha mask | |
fixed4 texCookie = tex2Dproj (_ShadowTex, UNITY_PROJ_COORD(i.uvShadow)); | |
fixed4 outColor = _Color * texCookie.a; | |
// Attenuation | |
float depth = i.uvShadow.z; // [-1 (near), 1 (far)] | |
return outColor * clamp(1.0 - abs(depth) + _Attenuation, 0.0, 1.0); | |
} | |
ENDCG | |
} | |
} | |
} |
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
%YAML 1.1 | |
%TAG !u! tag:unity3d.com,2011: | |
--- !u!21 &2100000 | |
Material: | |
serializedVersion: 5 | |
m_ObjectHideFlags: 0 | |
m_PrefabParentObject: {fileID: 0} | |
m_PrefabInternal: {fileID: 0} | |
m_Name: ProjectorMaterial | |
m_Shader: {fileID: 4800000, guid: ee7f8a5cfe4359c4cb76cd823b1ba6fc, type: 3} | |
m_ShaderKeywords: | |
m_LightmapFlags: 5 | |
m_CustomRenderQueue: -1 | |
m_SavedProperties: | |
serializedVersion: 2 | |
m_TexEnvs: | |
data: | |
first: | |
name: _MainTex | |
second: | |
m_Texture: {fileID: 0} | |
m_Scale: {x: 1, y: 1} | |
m_Offset: {x: 0, y: 0} | |
data: | |
first: | |
name: _BumpMap | |
second: | |
m_Texture: {fileID: 0} | |
m_Scale: {x: 1, y: 1} | |
m_Offset: {x: 0, y: 0} | |
data: | |
first: | |
name: _DetailNormalMap | |
second: | |
m_Texture: {fileID: 0} | |
m_Scale: {x: 1, y: 1} | |
m_Offset: {x: 0, y: 0} | |
data: | |
first: | |
name: _ParallaxMap | |
second: | |
m_Texture: {fileID: 0} | |
m_Scale: {x: 1, y: 1} | |
m_Offset: {x: 0, y: 0} | |
data: | |
first: | |
name: _OcclusionMap | |
second: | |
m_Texture: {fileID: 0} | |
m_Scale: {x: 1, y: 1} | |
m_Offset: {x: 0, y: 0} | |
data: | |
first: | |
name: _EmissionMap | |
second: | |
m_Texture: {fileID: 0} | |
m_Scale: {x: 1, y: 1} | |
m_Offset: {x: 0, y: 0} | |
data: | |
first: | |
name: _DetailMask | |
second: | |
m_Texture: {fileID: 0} | |
m_Scale: {x: 1, y: 1} | |
m_Offset: {x: 0, y: 0} | |
data: | |
first: | |
name: _DetailAlbedoMap | |
second: | |
m_Texture: {fileID: 0} | |
m_Scale: {x: 1, y: 1} | |
m_Offset: {x: 0, y: 0} | |
data: | |
first: | |
name: _MetallicGlossMap | |
second: | |
m_Texture: {fileID: 0} | |
m_Scale: {x: 1, y: 1} | |
m_Offset: {x: 0, y: 0} | |
data: | |
first: | |
name: _ShadowTex | |
second: | |
m_Texture: {fileID: 2800000, guid: 852ae92a6c0ede749b3054826927ecaf, type: 3} | |
m_Scale: {x: 1, y: 1} | |
m_Offset: {x: 0, y: 0} | |
data: | |
first: | |
name: _FalloffTex | |
second: | |
m_Texture: {fileID: 2800000, guid: 23740055e2b119e40a939138ab8070f8, type: 3} | |
m_Scale: {x: 1, y: 1} | |
m_Offset: {x: 0, y: 0} | |
m_Floats: | |
data: | |
first: | |
name: _Cutoff | |
second: .5 | |
data: | |
first: | |
name: _SrcBlend | |
second: 1 | |
data: | |
first: | |
name: _DstBlend | |
second: 0 | |
data: | |
first: | |
name: _Parallax | |
second: .0199999996 | |
data: | |
first: | |
name: _ZWrite | |
second: 1 | |
data: | |
first: | |
name: _Glossiness | |
second: .5 | |
data: | |
first: | |
name: _BumpScale | |
second: 1 | |
data: | |
first: | |
name: _OcclusionStrength | |
second: 1 | |
data: | |
first: | |
name: _DetailNormalMapScale | |
second: 1 | |
data: | |
first: | |
name: _UVSec | |
second: 0 | |
data: | |
first: | |
name: _EmissionScaleUI | |
second: 0 | |
data: | |
first: | |
name: _Mode | |
second: 0 | |
data: | |
first: | |
name: _Metallic | |
second: 0 | |
data: | |
first: | |
name: _Falloff | |
second: 1 | |
data: | |
first: | |
name: _Attenuation | |
second: 1 | |
m_Colors: | |
data: | |
first: | |
name: _EmissionColor | |
second: {r: 0, g: 0, b: 0, a: 1} | |
data: | |
first: | |
name: _Color | |
second: {r: .930362105, g: 1, b: 0, a: 1} | |
data: | |
first: | |
name: _EmissionColorUI | |
second: {r: 1, g: 1, b: 1, a: 1} |
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 UnityEngine; | |
using System; | |
using System.Linq; | |
using System.Collections; | |
using System.Collections.Generic; | |
public class SelectableUnitComponent : MonoBehaviour | |
{ | |
public GameObject selectionCircle; | |
} |
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 UnityEngine; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Text; | |
public class UnitSelectionComponent : MonoBehaviour { | |
bool isSelecting = false; | |
Vector3 mousePosition1; | |
public GameObject selectionCirclePrefab; | |
void Update() | |
{ | |
// If we press the left mouse button, begin selection and remember the location of the mouse | |
if (Input.GetMouseButtonDown(0)) | |
{ | |
isSelecting = true; | |
mousePosition1 = Input.mousePosition; | |
foreach (var selectableObject in FindObjectsOfType<SelectableUnitComponent>()) | |
{ | |
if (selectableObject.selectionCircle != null) | |
{ | |
Destroy(selectableObject.selectionCircle.gameObject); | |
selectableObject.selectionCircle = null; | |
} | |
} | |
} | |
// If we let go of the left mouse button, end selection | |
if (Input.GetMouseButtonUp(0)) | |
{ | |
var selectedObjects = new List<SelectableUnitComponent>(); | |
foreach (var selectableObject in FindObjectsOfType<SelectableUnitComponent>()) | |
{ | |
if (IsWithinSelectionBounds(selectableObject.gameObject)) | |
{ | |
selectedObjects.Add(selectableObject); | |
} | |
} | |
var sb = new StringBuilder(); | |
sb.AppendLine(string.Format("Selecting [{0}] Units", selectedObjects.Count)); | |
foreach (var selectedObject in selectedObjects) | |
sb.AppendLine("-> " + selectedObject.gameObject.name); | |
Debug.Log(sb.ToString()); | |
isSelecting = false; | |
} | |
// Highlight all objects within the selection box | |
if (isSelecting) | |
{ | |
foreach (var selectableObject in FindObjectsOfType<SelectableUnitComponent>()) | |
{ | |
if (IsWithinSelectionBounds(selectableObject.gameObject)) | |
{ | |
if (selectableObject.selectionCircle == null) | |
{ | |
selectableObject.selectionCircle = Instantiate(selectionCirclePrefab); | |
selectableObject.selectionCircle.transform.SetParent(selectableObject.transform, false); | |
selectableObject.selectionCircle.transform.eulerAngles = new Vector3(90, 0, 0); | |
} | |
} | |
else | |
{ | |
if (selectableObject.selectionCircle != null) | |
{ | |
Destroy(selectableObject.selectionCircle.gameObject); | |
selectableObject.selectionCircle = null; | |
} | |
} | |
} | |
} | |
} | |
public bool IsWithinSelectionBounds(GameObject gameObject) | |
{ | |
if (!isSelecting) | |
return false; | |
var camera = Camera.main; | |
var viewportBounds = Utils.GetViewportBounds(camera, mousePosition1, Input.mousePosition); | |
return viewportBounds.Contains( camera.WorldToViewportPoint(gameObject.transform.position)); | |
} | |
void OnGUI() | |
{ | |
if (isSelecting) | |
{ | |
// Create a rect from both mouse positions | |
var rect = Utils.GetScreenRect(mousePosition1, Input.mousePosition); | |
Utils.DrawScreenRect(rect, new Color(0.8f, 0.8f, 0.95f, 0.25f)); | |
Utils.DrawScreenRectBorder(rect, 2, new Color(0.8f, 0.8f, 0.95f)); | |
} | |
} | |
} |
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 UnityEngine; | |
using System.Collections; | |
public static class Utils | |
{ | |
static Texture2D _whiteTexture; | |
public static Texture2D WhiteTexture | |
{ | |
get | |
{ | |
if (_whiteTexture == null) | |
{ | |
_whiteTexture = new Texture2D(1, 1); | |
_whiteTexture.SetPixel(0, 0, Color.white); | |
_whiteTexture.Apply(); | |
} | |
return _whiteTexture; | |
} | |
} | |
public static void DrawScreenRect(Rect rect, Color color) | |
{ | |
GUI.color = color; | |
GUI.DrawTexture(rect, WhiteTexture); | |
GUI.color = Color.white; | |
} | |
public static void DrawScreenRectBorder(Rect rect, float thickness, Color color) | |
{ | |
// Top | |
Utils.DrawScreenRect(new Rect(rect.xMin, rect.yMin, rect.width, thickness), color); | |
// Left | |
Utils.DrawScreenRect(new Rect(rect.xMin, rect.yMin, thickness, rect.height), color); | |
// Right | |
Utils.DrawScreenRect(new Rect(rect.xMax - thickness, rect.yMin, thickness, rect.height), color); | |
// Bottom | |
Utils.DrawScreenRect(new Rect(rect.xMin, rect.yMax - thickness, rect.width, thickness), color); | |
} | |
public static Rect GetScreenRect(Vector3 screenPosition1, Vector3 screenPosition2) | |
{ | |
// Move origin from bottom left to top left | |
screenPosition1.y = Screen.height - screenPosition1.y; | |
screenPosition2.y = Screen.height - screenPosition2.y; | |
// Calculate corners | |
var topLeft = Vector3.Min(screenPosition1, screenPosition2); | |
var bottomRight = Vector3.Max(screenPosition1, screenPosition2); | |
// Create Rect | |
return Rect.MinMaxRect(topLeft.x, topLeft.y, bottomRight.x, bottomRight.y); | |
} | |
public static Bounds GetViewportBounds(Camera camera, Vector3 screenPosition1, Vector3 screenPosition2) | |
{ | |
var v1 = Camera.main.ScreenToViewportPoint(screenPosition1); | |
var v2 = Camera.main.ScreenToViewportPoint(screenPosition2); | |
var min = Vector3.Min(v1, v2); | |
var max = Vector3.Max(v1, v2); | |
min.z = camera.nearClipPlane; | |
max.z = camera.farClipPlane; | |
var bounds = new Bounds(); | |
bounds.SetMinMax(min, max); | |
return bounds; | |
} | |
} |
Author
bdecarne
commented
Nov 5, 2015
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment