├── LICENSE.meta ├── README.md.meta ├── package.json.meta ├── Runtime.meta ├── Runtime ├── Abstractions.meta ├── MadeYellow.InputBuffer.asmdef.meta ├── BoolInputBuffer.cs.meta ├── FloatInputBuffer.cs.meta ├── IntInputBuffer.cs.meta ├── SimpleInputBuffer.cs.meta ├── Vector2InputBuffer.cs.meta ├── Vector3InputBuffer.cs.meta ├── Abstractions │ ├── InputBufferBase.cs.meta │ ├── InputBufferValueBase.cs.meta │ ├── InputBufferValueBase.cs │ └── InputBufferBase.cs ├── MadeYellow.InputBuffer.asmdef ├── BoolInputBuffer.cs ├── IntInputBuffer.cs ├── FloatInputBuffer.cs ├── Vector3InputBuffer.cs ├── Vector2InputBuffer.cs └── SimpleInputBuffer.cs ├── package.json ├── LICENSE └── README.md /LICENSE.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3f58029ed548b1849bcb908ef61eccdb 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8c3f9adeaa9fed1468a82c2b43957e74 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e28e85fb2fa3af84699079d0675c0694 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 026eb1f5750100645810ee51639642f6 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Abstractions.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3b57a2c0ee251cc4896ad73a261117a5 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/MadeYellow.InputBuffer.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6c36cd3b11ea485458411d93123c521f 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime/BoolInputBuffer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0a5f32ca99fb0454aa9751eab95eacb4 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/FloatInputBuffer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3d82f7ebf801af34593633fd37c25205 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/IntInputBuffer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4b778abe8a7552a458b062f8de150a03 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/SimpleInputBuffer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 81cb9fcce5bdcad4c8328e8dadb0f304 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Vector2InputBuffer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3bdef6df661bbb242973273d325ed9be 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Vector3InputBuffer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 98afbe4d2863e40448083c8ca5f6898f 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Abstractions/InputBufferBase.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 09459dddf238ea64ea630ff0456d4bec 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Abstractions/InputBufferValueBase.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: becd689f84b4ef44daab95a0e3300296 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/MadeYellow.InputBuffer.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MadeYellow.InputBuffer", 3 | "rootNamespace": "", 4 | "references": [], 5 | "includePlatforms": [], 6 | "excludePlatforms": [], 7 | "allowUnsafeCode": false, 8 | "overrideReferences": false, 9 | "precompiledReferences": [], 10 | "autoReferenced": true, 11 | "defineConstraints": [], 12 | "versionDefines": [], 13 | "noEngineReferences": false 14 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "madeyellow.input-buffer", 3 | "displayName": "InputBuffer", 4 | "version": "1.0.1", 5 | "unity": "2019.1", 6 | "author": { 7 | "name": "MadeYellow", 8 | "url": "https://github.com/madeyellow" 9 | }, 10 | "description": "Buffering input (simple or with value storing) for a configurable time span", 11 | "dependencies": { 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "https://github.com/madeyellow/InputBuffer.git" 16 | } 17 | } -------------------------------------------------------------------------------- /Runtime/BoolInputBuffer.cs: -------------------------------------------------------------------------------- 1 | using MadeYellow.InputBuffer.Abstractions; 2 | 3 | namespace MadeYellow.InputBuffer 4 | { 5 | /// 6 | /// Buffers input value of type 7 | /// 8 | [System.Serializable] 9 | public class BoolInputBuffer : InputBufferValueBase 10 | { 11 | public BoolInputBuffer() 12 | { 13 | 14 | } 15 | 16 | /// 17 | /// 18 | /// 19 | /// Time span after which buffer should be reset 20 | public BoolInputBuffer(float holdTime) : base(holdTime) 21 | { 22 | 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /Runtime/IntInputBuffer.cs: -------------------------------------------------------------------------------- 1 | using MadeYellow.InputBuffer.Abstractions; 2 | 3 | namespace MadeYellow.InputBuffer 4 | { 5 | /// 6 | /// Buffers input value of type . Best for buffering single axis 7 | /// 8 | [System.Serializable] 9 | public class IntInputBuffer : InputBufferValueBase 10 | { 11 | public IntInputBuffer() 12 | { 13 | 14 | } 15 | 16 | /// 17 | /// 18 | /// 19 | /// Time span after which buffer should be reset 20 | public IntInputBuffer(float holdTime) : base(holdTime) 21 | { 22 | 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /Runtime/FloatInputBuffer.cs: -------------------------------------------------------------------------------- 1 | using MadeYellow.InputBuffer.Abstractions; 2 | 3 | namespace MadeYellow.InputBuffer 4 | { 5 | /// 6 | /// Buffers input value of type . Best for buffering single axis 7 | /// 8 | [System.Serializable] 9 | public class FloatInputBuffer : InputBufferValueBase 10 | { 11 | public FloatInputBuffer() 12 | { 13 | 14 | } 15 | 16 | /// 17 | /// 18 | /// 19 | /// Time span after which buffer should be reset 20 | public FloatInputBuffer(float holdTime) : base(holdTime) 21 | { 22 | 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /Runtime/Vector3InputBuffer.cs: -------------------------------------------------------------------------------- 1 | using MadeYellow.InputBuffer.Abstractions; 2 | using UnityEngine; 3 | 4 | namespace MadeYellow.InputBuffer 5 | { 6 | /// 7 | /// Buffers input value of type 8 | /// 9 | [System.Serializable] 10 | public class Vector3InputBuffer : InputBufferValueBase 11 | { 12 | public Vector3InputBuffer() 13 | { 14 | 15 | } 16 | 17 | /// 18 | /// 19 | /// 20 | /// Time span after which buffer should be reset 21 | public Vector3InputBuffer(float holdTime) : base(holdTime) 22 | { 23 | 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /Runtime/Vector2InputBuffer.cs: -------------------------------------------------------------------------------- 1 | using MadeYellow.InputBuffer.Abstractions; 2 | using UnityEngine; 3 | 4 | namespace MadeYellow.InputBuffer 5 | { 6 | /// 7 | /// Buffers input value of type . Best for buffering gamepad 8 | /// 9 | [System.Serializable] 10 | public class Vector2InputBuffer : InputBufferValueBase 11 | { 12 | public Vector2InputBuffer() 13 | { 14 | 15 | } 16 | 17 | /// 18 | /// 19 | /// 20 | /// Time span after which buffer should be reset 21 | public Vector2InputBuffer(float holdTime) : base(holdTime) 22 | { 23 | 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /Runtime/SimpleInputBuffer.cs: -------------------------------------------------------------------------------- 1 | using MadeYellow.InputBuffer.Abstractions; 2 | 3 | namespace MadeYellow.InputBuffer 4 | { 5 | /// 6 | /// Buffers input fact. Best for buffering button press. 7 | /// 8 | [System.Serializable] 9 | public class SimpleInputBuffer : InputBufferBase 10 | { 11 | public SimpleInputBuffer() 12 | { 13 | 14 | } 15 | 16 | /// 17 | /// 18 | /// 19 | /// Time span after which buffer should be reset 20 | public SimpleInputBuffer(float holdTime) : base(holdTime) 21 | { 22 | 23 | } 24 | 25 | /// 26 | /// Set up buffer 27 | /// 28 | public void Set() 29 | { 30 | SetTimestamp(); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Runtime/Abstractions/InputBufferValueBase.cs: -------------------------------------------------------------------------------- 1 | namespace MadeYellow.InputBuffer.Abstractions 2 | { 3 | /// 4 | /// 5 | /// 6 | /// 7 | [System.Serializable] 8 | public abstract class InputBufferValueBase : InputBufferBase 9 | { 10 | public TValue value { get; private set; } 11 | 12 | public InputBufferValueBase() 13 | { 14 | 15 | } 16 | 17 | public InputBufferValueBase(float holdTime) : base(holdTime) 18 | { 19 | 20 | } 21 | 22 | /// 23 | /// Set up buffer with value 24 | /// 25 | /// 26 | public void Set(TValue value) 27 | { 28 | this.value = value; 29 | 30 | SetTimestamp(); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 MadeYellow 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 | -------------------------------------------------------------------------------- /Runtime/Abstractions/InputBufferBase.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace MadeYellow.InputBuffer.Abstractions 4 | { 5 | /// 6 | /// Basis for buffering input data 7 | /// 8 | [System.Serializable] 9 | public abstract class InputBufferBase 10 | { 11 | /// 12 | /// of last usage 13 | /// 14 | private float _timestamp = float.MinValue; 15 | 16 | 17 | [SerializeField] 18 | [Range(0f, 10f)] 19 | private float _holdTime = 0.25f; 20 | 21 | /// 22 | /// Time span after which buffer should be reset 23 | /// 24 | public float holdTime => _holdTime; 25 | 26 | /// 27 | /// Indicates if buffer hold input data at this moment 28 | /// 29 | public bool hasBuffer => _timestamp + _holdTime >= Time.time; 30 | 31 | public InputBufferBase() 32 | { 33 | 34 | } 35 | 36 | public InputBufferBase(float holdTime) 37 | { 38 | _holdTime = holdTime; 39 | } 40 | 41 | /// 42 | /// Updates , so can be checked 43 | /// 44 | protected void SetTimestamp() 45 | { 46 | _timestamp = Time.time; 47 | } 48 | 49 | /// 50 | /// Resets buffer 51 | /// 52 | public void Reset() 53 | { 54 | _timestamp = float.MinValue; 55 | } 56 | 57 | /// 58 | /// Changes time span after which buffer should be reset 59 | /// 60 | /// 61 | public void UpdateHoldTIme(float holdTime) 62 | { 63 | _holdTime = holdTime; 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ❓ What is it? 2 | Simple yet effective input buffering with **just 4 lines of code!** ⚡ 3 | Never miss player actions again - perfect for jumps, dashes, and combo moves. 4 | 5 | Check if buffer isn't expired at any given moment, configure buffer's lifetime, cache input values & etc. 6 | 7 | ## 💡 Why Use Input Buffering? 8 | 9 | *Eliminate frustrating gameplay moments!* 10 | 11 | When players press jump **just before landing**, your logic might ignore it. 12 | **This solution**: Buffers inputs so they execute when conditions are right! 13 | 14 | ``` 15 | // Problem solved in 3 simple steps: 16 | jumpBuffer.Set(); // 1. Buffer on player input 17 | if (jumpBuffer.HasBuffer) // 2. Check when it's needed 18 | PerformJump(); // 3. Execute perfectly! 19 | ``` 20 | 21 | # 💾 Installation 22 | * Open **Unity Package Manager** (Window > Package Manager) OR (Window > Package Management > Package Manager) in **Unity 6**; 23 | * Click "+" → "Add package from git URL"; 24 | * Paste this **repo's URL**; 25 | * Hit **Install**; 26 | 27 | # 🚀 Getting started 28 | ## Step 1: Define buffers 29 | First of all declare input buffer: 30 | 31 | ```csharp 32 | using MadeYellow.InputBuffer; 33 | 34 | public SimpleInputBuffer jumpInputBuffer = new SimpleInputBuffer(); // Init input buffer 35 | ``` 36 | 37 | You can choose between various types of `InputBuffer`: 38 | 39 | * `SimpleInputBuffer` - best for buffering button presses *(in terms of Unity's InputSystem)*; 40 | * `IntInputBuffer`, `FloatInputBuffer` - best for buffering axis 1D input *(in terms of Unity's InputSystem)*; 41 | * `Vector2InputBuffer` - best for buffering gamepad stick input or any other 2D input; 42 | 43 | ## Step 2: Buffer input 44 | You may configure buffer **hold time** from Unity Editor by changing `holdTime` slider OR by passing `holdTime` argument to `InputBuffer` constructor. 45 | 46 | After you've set up suitable `InputBuffer` you should use `.Set();` or `.Set(value);` method each time you want to buffer your input. You may do it like so: 47 | 48 | ```csharp 49 | jumpInputBuffer.Set(); // Set input buffer when input happened 50 | ``` 51 | 52 | ## Step 3: Check against the buffer 53 | When you need to check if certain input **is buffered or not** you can perform a simple & performant check: 54 | 55 | ```csharp 56 | if (jumpInputBuffer.hasBuffer) 57 | { 58 | jumpInputBuffer.Reset(); // Reset buffer since we most likely want to perform action required by input only once 59 | 60 | // Your code goes here, e.g. perform Jump action if input was buffered, etc. 61 | } 62 | ``` 63 | 64 | **TIP:** It's best to perform those checks each frame in `Update()` or `LateUpdate()` method inside your MonoBehaviour, so you won't miss any input. It's super cheap in terms of performance. 65 | 66 | # Getting the buffered value 67 | 68 | If you created `InputBuffer` of any type **except** of `SimpleInputBuffer` (*that one doesn't store any value at all, only the fact of the input*) you can call `.value` to retrieve current value of input. 69 | 70 | ```csharp 71 | var vectorBuffer = new Vector2InputBuffer(); 72 | 73 | vectorBuffer.Set(Vector2.one); 74 | 75 | Debug.Log(vectorBuffer.value); // Will log (1.00, 1.00) 76 | ``` 77 | 78 | # ✅ Recomendations 79 | 80 | * **Don't** reuse single `InputBuffer` instance for various input actions: one instance for *jumping*, another for *dashing*, etc; 81 | * **Use** `.hasBuffer` check each frame in order not to miss a frame where you might execute your buffered action; 82 | 83 | # ⚡ Why You’ll Love It 84 | * 🧠 **Easy to use** – pick a right buffer and use it right away; 85 | * 🚀 **Great performance** – buffers are greatly optimized under the hood; 86 | * 💎 **Clean syntax** – `.Set()` and `.Reset()` for buffering, `.hasBuffer` for conditions; 87 | * 📦 **Tiny & dependency-free** – Minimal footprint; 88 | * 89 | # Want me to add something OR found a bug? 90 | 91 | Please add an issue and describe your feature request or bug. I will add a feature if consider it usefull, and for sure will fix bugs, 'cause I'm using that package myself in my games. 92 | --------------------------------------------------------------------------------