Skip to content

Instantly share code, notes, and snippets.

@bdecarne
Last active November 5, 2015 17:59
Show Gist options
  • Save bdecarne/32c7104f20e33658ddc4 to your computer and use it in GitHub Desktop.
Save bdecarne/32c7104f20e33658ddc4 to your computer and use it in GitHub Desktop.
Unity : UnitSelection
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
}
}
}
%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}
using UnityEngine;
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
public class SelectableUnitComponent : MonoBehaviour
{
public GameObject selectionCircle;
}
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));
}
}
}
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;
}
}
@bdecarne
Copy link
Author

bdecarne commented Nov 5, 2015

selectioncirclealpha

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment