├── .gitignore ├── BatchedParticleSystem ├── README.md ├── Source │ ├── BatchedParticleEmitter.cs │ ├── BatchedParticleSystem.cs │ └── Editor │ │ └── BatchedParticleEmitterPropertyDrawers.cs └── gifs │ ├── BatchedParticles.gif │ └── particles.gif ├── GridScrollingShader ├── README.md ├── gifs │ ├── Bidirectional.gif │ └── GridScroller_half.gif └── source │ ├── ExampleGrid.png │ └── LoopingGridScroller.shader ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | [Ll]ibrary/ 2 | [Tt]emp/ 3 | [Oo]bj/ 4 | [Bb]uild/ 5 | [Bb]uilds/ 6 | Assets/AssetStoreTools* 7 | 8 | # Visual Studio cache directory 9 | .vs/ 10 | 11 | # Autogenerated VS/MD/Consulo solution and project files 12 | ExportedObj/ 13 | .consulo/ 14 | *.csproj 15 | *.unityproj 16 | *.sln 17 | *.suo 18 | *.tmp 19 | *.user 20 | *.userprefs 21 | *.pidb 22 | *.booproj 23 | *.svd 24 | *.pdb 25 | *.opendb 26 | 27 | # Unity3D generated meta files 28 | *.pidb.meta 29 | *.pdb.meta 30 | 31 | # Unity3D Generated File On Crash Reports 32 | sysinfo.txt 33 | 34 | # Builds 35 | *.apk 36 | *.unitypackage 37 | -------------------------------------------------------------------------------- /BatchedParticleSystem/README.md: -------------------------------------------------------------------------------- 1 | # Batched Particle Systems 2 | Simple scripts that leverage ParticleSystem.Emit() and the ParticleSystem.EmitParams structure to allow multiple instances of similar particle systems to be batched into a single particle system with multiple emitters. 3 | 4 | ![](gifs/particles.gif) 5 | ![](gifs/BatchedParticles.gif) 6 | 7 | ## Usage 8 | Attach the BatchedParticleSystem component to the same GameObject as your main particle system. Attach the BatchedParticleEmitter to any GameObject that you would like to emit particles in that system, and add them to the BatchParticleSystems emitter list. Then, tweak the override settings on each emitter to achieve your desired effect. 9 | 10 | 11 | [More Info Here](https://www.grizzly-machine.com/entries/drawing-multiple-effects-with-one-particle-system) 12 | -------------------------------------------------------------------------------- /BatchedParticleSystem/Source/BatchedParticleEmitter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace GrizzlyMachine 5 | { 6 | public class BatchedParticleEmitter : MonoBehaviour 7 | { 8 | [Header("Emission")] 9 | [SerializeField] private float _emissionRate = 10; 10 | [SerializeField] private bool _useTransformAsEmitterPosition = true; 11 | [SerializeField] private bool _applyEmitterShape = true; 12 | 13 | [Header("Emitter Overrides")] 14 | [SerializeField] private FloatOverride _angularVelocity; 15 | [SerializeField] private Vector3Override _angularVelocity3D; 16 | [SerializeField] private Vector3Override _axisOfRotation; 17 | [SerializeField] private UIntOverride _randomSeed; 18 | [SerializeField] private FloatOverride _rotation; 19 | [SerializeField] private Vector3Override _rotation3D; 20 | [SerializeField] private Color32Override _startColor; 21 | [SerializeField] private FloatOverride _startLifetime; 22 | [SerializeField] private FloatOverride _startSize; 23 | [SerializeField] private Vector3Override _startSize3D; 24 | [SerializeField] private Vector3Override _velocity; 25 | 26 | public float EmissionRate => _emissionRate; 27 | public float EmissionTimer { get; set; } 28 | 29 | public virtual ParticleSystem.EmitParams GetEmitParams(ParticleSystem targetSystem) 30 | { 31 | ParticleSystem.EmitParams emitParams = new ParticleSystem.EmitParams(); 32 | 33 | if (_useTransformAsEmitterPosition) 34 | { 35 | emitParams.position = ConvertWorldPointToSimulationSpace(transform.position, targetSystem); 36 | } 37 | emitParams.applyShapeToPosition = _applyEmitterShape; 38 | 39 | if (_angularVelocity.enabled) { emitParams.angularVelocity = _angularVelocity.value; } 40 | if (_angularVelocity3D.enabled) { emitParams.angularVelocity3D = _angularVelocity3D.value; } 41 | if (_axisOfRotation.enabled) { emitParams.axisOfRotation = _axisOfRotation.value; } 42 | if (_randomSeed.enabled) { emitParams.randomSeed = _randomSeed.value; } 43 | if (_rotation.enabled) { emitParams.rotation = _rotation.value; } 44 | if (_rotation3D.enabled) { emitParams.rotation3D = _rotation3D.value; } 45 | if (_startColor.enabled) { emitParams.startColor = _startColor.value; } 46 | if (_startLifetime.enabled) { emitParams.startLifetime = _startLifetime.value; } 47 | if (_startSize.enabled) { emitParams.startSize = _startSize.value; } 48 | if (_startSize3D.enabled) { emitParams.startSize3D = _startSize3D.value; } 49 | if (_velocity.enabled) { emitParams.velocity = _velocity.value; } 50 | 51 | return emitParams; 52 | } 53 | 54 | private static Vector3 ConvertWorldPointToSimulationSpace(Vector3 worldPos, ParticleSystem targetSystem) 55 | { 56 | ParticleSystem.MainModule mainModule = targetSystem.main; 57 | switch (mainModule.simulationSpace) 58 | { 59 | case ParticleSystemSimulationSpace.World: 60 | return worldPos; 61 | 62 | case ParticleSystemSimulationSpace.Custom: 63 | return mainModule.customSimulationSpace.InverseTransformPoint(worldPos); 64 | 65 | default: 66 | case ParticleSystemSimulationSpace.Local: 67 | return targetSystem.transform.InverseTransformPoint(worldPos); 68 | } 69 | } 70 | 71 | [Serializable] 72 | public struct UIntOverride 73 | { 74 | public bool enabled; 75 | public uint value; 76 | } 77 | 78 | [Serializable] 79 | public struct FloatOverride 80 | { 81 | public bool enabled; 82 | public float value; 83 | } 84 | 85 | [Serializable] 86 | public struct Vector3Override 87 | { 88 | public bool enabled; 89 | public Vector3 value; 90 | } 91 | 92 | [Serializable] 93 | public struct Color32Override 94 | { 95 | public bool enabled; 96 | public Color32 value; 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /BatchedParticleSystem/Source/BatchedParticleSystem.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | namespace GrizzlyMachine 5 | { 6 | [RequireComponent(typeof(ParticleSystem))] 7 | public class BatchedParticleSystem : MonoBehaviour 8 | { 9 | [SerializeField] private List _emitters; 10 | 11 | private ParticleSystem _particleSystem; 12 | 13 | private void Awake() 14 | { 15 | _particleSystem = GetComponent(); 16 | } 17 | 18 | private void Update() 19 | { 20 | for (int i = 0; i < _emitters.Count; ++i) 21 | { 22 | if (_emitters[i] == null) { continue; } 23 | 24 | int emitCount = Mathf.FloorToInt(_emitters[i].EmissionTimer); 25 | if (emitCount > 0) 26 | { 27 | for (int e = 0; e < emitCount; ++e) 28 | { 29 | ParticleSystem.EmitParams emitParams = _emitters[i].GetEmitParams(_particleSystem); 30 | _particleSystem.Emit(emitParams, 1); 31 | } 32 | 33 | _emitters[i].EmissionTimer %= 1f; 34 | } 35 | else 36 | { 37 | _emitters[i].EmissionTimer += _emitters[i].EmissionRate * Time.deltaTime; 38 | } 39 | } 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /BatchedParticleSystem/Source/Editor/BatchedParticleEmitterPropertyDrawers.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | using UnityEngine; 3 | 4 | namespace GrizzlyMachine 5 | { 6 | [CustomPropertyDrawer(typeof(BatchedParticleEmitter.FloatOverride))] 7 | [CustomPropertyDrawer(typeof(BatchedParticleEmitter.UIntOverride))] 8 | [CustomPropertyDrawer(typeof(BatchedParticleEmitter.Vector3Override))] 9 | [CustomPropertyDrawer(typeof(BatchedParticleEmitter.Color32Override))] 10 | public class BatchedParticleEmitterPropertyDrawers : PropertyDrawer 11 | { 12 | public override float GetPropertyHeight(SerializedProperty property, GUIContent label) 13 | { 14 | return EditorGUIUtility.singleLineHeight; 15 | } 16 | 17 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 18 | { 19 | Rect toggleRect = position; 20 | toggleRect.width = 15f; 21 | EditorGUI.PropertyField(toggleRect, property.FindPropertyRelative("enabled"), new GUIContent(), true); 22 | 23 | Rect valueRect = position; 24 | valueRect.x += 15f; 25 | valueRect.width -= 20f; 26 | EditorGUI.PropertyField(valueRect, property.FindPropertyRelative("value"), label, true); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /BatchedParticleSystem/gifs/BatchedParticles.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grizzly-machine/gists/7ce6da6452d4653ab9fbb891a592a3bbc42f94e8/BatchedParticleSystem/gifs/BatchedParticles.gif -------------------------------------------------------------------------------- /BatchedParticleSystem/gifs/particles.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grizzly-machine/gists/7ce6da6452d4653ab9fbb891a592a3bbc42f94e8/BatchedParticleSystem/gifs/particles.gif -------------------------------------------------------------------------------- /GridScrollingShader/README.md: -------------------------------------------------------------------------------- 1 | # Grid Scrolling Shader 2 | This simple unlit shader endlessly scrolls through a grid of cells within a texture. It supports scrolling vertically or horizontally, and can work within a subset of the texture to allow for atlassing. 3 | 4 | [More info and tutorial here.](https://www.grizzly-machine.com/entries/tutorial-looped-grid-scrolling-shader) 5 | 6 | ![](gifs/GridScroller_half.gif) 7 | ![](gifs/Bidirectional.gif) 8 | 9 | ## Usage 10 | Create a material with this shader and assign your grid texture to the Main Texture slot. Enter the width and height of the grid-cells in the x and y tiling properties of the texture (you can calculate this number by taking the dimensions of the cell in pixels and dividing by the dimensions of the texture in pixels). If your grid is not anchored at the bottom-left corner of the texture, use the offset property to define the starting position of the grid. Finally, enter the number of rows and columns in their respective properties, and use the scroll position property to animate your effect. 11 | -------------------------------------------------------------------------------- /GridScrollingShader/gifs/Bidirectional.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grizzly-machine/gists/7ce6da6452d4653ab9fbb891a592a3bbc42f94e8/GridScrollingShader/gifs/Bidirectional.gif -------------------------------------------------------------------------------- /GridScrollingShader/gifs/GridScroller_half.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grizzly-machine/gists/7ce6da6452d4653ab9fbb891a592a3bbc42f94e8/GridScrollingShader/gifs/GridScroller_half.gif -------------------------------------------------------------------------------- /GridScrollingShader/source/ExampleGrid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grizzly-machine/gists/7ce6da6452d4653ab9fbb891a592a3bbc42f94e8/GridScrollingShader/source/ExampleGrid.png -------------------------------------------------------------------------------- /GridScrollingShader/source/LoopingGridScroller.shader: -------------------------------------------------------------------------------- 1 | Shader "Grizzly Machine/Unlit Looping Grid Scroller" 2 | { 3 | Properties 4 | { 5 | _MainTex ("Texture", 2D) = "white" {} 6 | _ScrollPosition ("Scroll Position", Float) = 0 7 | _RowCount ("Row Count", Float) = 1 8 | _ColumnCount ("Column Count", Float) = 1 9 | [KeywordEnum(Vertical,Horizontal)]_Direction("Direction", Float) = 0 10 | } 11 | SubShader 12 | { 13 | Tags { "RenderType"="Opaque" } 14 | LOD 100 15 | 16 | Pass 17 | { 18 | CGPROGRAM 19 | #pragma vertex vert 20 | #pragma fragment frag 21 | #pragma multi_compile _DIRECTION_VERTICAL _DIRECTION_HORIZONTAL 22 | 23 | #include "UnityCG.cginc" 24 | 25 | struct appdata 26 | { 27 | float4 vertex : POSITION; 28 | float2 uv : TEXCOORD0; 29 | }; 30 | 31 | struct v2f 32 | { 33 | float2 uv : TEXCOORD0; 34 | float4 vertex : SV_POSITION; 35 | }; 36 | 37 | sampler2D _MainTex; 38 | float4 _MainTex_ST; 39 | float _ScrollPosition; 40 | float _RowCount; 41 | float _ColumnCount; 42 | 43 | #ifdef _DIRECTION_VERTICAL 44 | #define CELL_WIDTH _MainTex_ST.x 45 | #define CELL_HEIGHT _MainTex_ST.y 46 | #define SCROLL_AXIS y 47 | #define NON_SCROLL_AXIS x 48 | #define SCROLL_AXIS_HEIGHT _RowCount * CELL_HEIGHT 49 | #define SCROLL_DIR_COUNT _ColumnCount 50 | #endif 51 | #ifdef _DIRECTION_HORIZONTAL 52 | #define CELL_WIDTH _MainTex_ST.y 53 | #define CELL_HEIGHT _MainTex_ST.x 54 | #define SCROLL_AXIS x 55 | #define NON_SCROLL_AXIS y 56 | #define SCROLL_AXIS_HEIGHT _ColumnCount * CELL_HEIGHT 57 | #define SCROLL_DIR_COUNT _RowCount 58 | #endif 59 | 60 | v2f vert (appdata v) 61 | { 62 | v2f o; 63 | o.vertex = UnityObjectToClipPos(v.vertex); 64 | float numCells = _RowCount * _ColumnCount; 65 | v.uv.SCROLL_AXIS += (numCells - ((_ScrollPosition * -1) % numCells)); 66 | o.uv = v.uv * _MainTex_ST.xy; 67 | return o; 68 | } 69 | 70 | fixed4 frag (v2f i) : SV_Target 71 | { 72 | float scrollHeight = SCROLL_AXIS_HEIGHT; 73 | i.uv.NON_SCROLL_AXIS += CELL_WIDTH * (trunc(i.uv.SCROLL_AXIS / scrollHeight) % SCROLL_DIR_COUNT); 74 | i.uv.SCROLL_AXIS %= scrollHeight; 75 | i.uv += _MainTex_ST.zw; 76 | fixed4 col = tex2D(_MainTex, i.uv); 77 | return col; 78 | } 79 | ENDCG 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Grizzly Machine 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Grizzly Machine's Unity Utilities and Samples 2 | This is a dumping ground for utilties and sample code that do not warrant their own repos (things that would be in gists if orgs could create gists). 3 | 4 | ## [Grid Scrolling Shader](/GridScrollingShader/) 5 | This simple unlit shader endlessly scrolls through a grid of cells within a texture. It supports scrolling vertically or horizontally, and can work within a subset of the texture to allow for atlassing. 6 | 7 | [Tutorial Here](https://www.grizzly-machine.com/entries/tutorial-looped-grid-scrolling-shader) 8 | 9 | ![](/GridScrollingShader/gifs/GridScroller_half.gif) 10 | 11 | ## [Batched Particle Systems](/BatchedParticleSystem/) 12 | Contains a couple simple scripts that allow multiple instances of the same or similar particle systems to be combined into one particle system with multiple emitters. 13 | 14 | ![](/BatchedParticleSystem/gifs/particles.gif) ![](/BatchedParticleSystem/gifs/BatchedParticles.gif) 15 | 16 | [More Info Here](https://www.grizzly-machine.com/entries/drawing-multiple-effects-with-one-particle-system) 17 | --------------------------------------------------------------------------------