Gradual jump and started orb events

This commit is contained in:
Gerard Gascón 2023-02-27 16:15:11 +01:00
parent e874c23647
commit b4e11ac33f
11 changed files with 1035 additions and 99 deletions

View file

@ -0,0 +1,184 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace GometGames.Tools
{
/// <summary>
/// Generic Serializable Dictionary for Unity 2020.1 and above.
/// Simply declare your key/value types and you're good to go - zero boilerplate.
/// </summary>
[Serializable]
public class GenericDictionary<TKey, TValue> : IDictionary<TKey, TValue>, ISerializationCallbackReceiver
{
// Internal
[SerializeField]
private List<KeyValuePair> list = new List<KeyValuePair>();
[SerializeField, HideInInspector]
private Dictionary<TKey, int> indexByKey = new Dictionary<TKey, int>();
[SerializeField, HideInInspector]
private Dictionary<TKey, TValue> dict = new Dictionary<TKey, TValue>();
#pragma warning disable 0414
[SerializeField, HideInInspector]
private bool keyCollision;
#pragma warning restore 0414
[Serializable]
private struct KeyValuePair
{
public TKey Key;
public TValue Value;
public KeyValuePair(TKey Key, TValue Value)
{
this.Key = Key;
this.Value = Value;
}
}
// Lists are serialized natively by Unity, no custom implementation needed.
public void OnBeforeSerialize() { }
// Populate dictionary with pairs from list and flag key-collisions.
public void OnAfterDeserialize()
{
dict.Clear();
indexByKey.Clear();
keyCollision = false;
for (int i = 0; i < list.Count; i++)
{
var key = list[i].Key;
if (key != null && !ContainsKey(key))
{
dict.Add(key, list[i].Value);
indexByKey.Add(key, i);
}
else
{
keyCollision = true;
}
}
}
// IDictionary
public TValue this[TKey key]
{
get => dict[key];
set
{
dict[key] = value;
if (indexByKey.ContainsKey(key))
{
var index = indexByKey[key];
list[index] = new KeyValuePair(key, value);
}
else
{
list.Add(new KeyValuePair(key, value));
indexByKey.Add(key, list.Count - 1);
}
}
}
public ICollection<TKey> Keys => dict.Keys;
public ICollection<TValue> Values => dict.Values;
public void Add(TKey key, TValue value)
{
dict.Add(key, value);
list.Add(new KeyValuePair(key, value));
indexByKey.Add(key, list.Count - 1);
}
public bool ContainsKey(TKey key) => dict.ContainsKey(key);
public bool Remove(TKey key)
{
if (dict.Remove(key))
{
var index = indexByKey[key];
list.RemoveAt(index);
UpdateIndexLookup(index);
indexByKey.Remove(key);
return true;
}
else
{
return false;
}
}
private void UpdateIndexLookup(int removedIndex) {
for (int i = removedIndex; i < list.Count; i++) {
var key = list[i].Key;
indexByKey[key]--;
}
}
public bool TryGetValue(TKey key, out TValue value) => dict.TryGetValue(key, out value);
// ICollection
public int Count => dict.Count;
public bool IsReadOnly { get; set; }
public void Add(KeyValuePair<TKey, TValue> pair)
{
Add(pair.Key, pair.Value);
}
public void Clear()
{
dict.Clear();
list.Clear();
indexByKey.Clear();
}
public bool Contains(KeyValuePair<TKey, TValue> pair)
{
TValue value;
if (dict.TryGetValue(pair.Key, out value))
{
return EqualityComparer<TValue>.Default.Equals(value, pair.Value);
}
else
{
return false;
}
}
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
if (array == null)
throw new ArgumentException("The array cannot be null.");
if (arrayIndex < 0)
throw new ArgumentOutOfRangeException("The starting array index cannot be negative.");
if (array.Length - arrayIndex < dict.Count)
throw new ArgumentException("The destination array has fewer elements than the collection.");
foreach (var pair in dict)
{
array[arrayIndex] = pair;
arrayIndex++;
}
}
public bool Remove(KeyValuePair<TKey, TValue> pair)
{
TValue value;
if (dict.TryGetValue(pair.Key, out value))
{
bool valueMatch = EqualityComparer<TValue>.Default.Equals(value, pair.Value);
if (valueMatch)
{
return Remove(pair.Key);
}
}
return false;
}
// IEnumerable
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() => dict.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => dict.GetEnumerator();
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8dee231b3f6acd04fb6f88737505c0bf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 854339740fd089942ba32bfdc1ff49c7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,40 @@
using System.Collections;
using System.Collections.Generic;
using GometGames.Tools;
using MyBox;
using UnityEngine;
using UnityEngine.Events;
[System.Serializable]
public enum OrbTypes {
Blue,
Red,
InvertedControls,
HighGravity,
LowGravity,
InvertedGravity,
DarkRoom,
HighSpeed,
LowSpeed
};
public class GameManager : MonoBehaviour {
[SerializeField] GenericDictionary<OrbTypes, UnityEvent> orbEffects;
[SerializeField] OrbTypes currentType;
// Start is called before the first frame update
void Start(){
}
// Update is called once per frame
void Update(){
}
void ChangeEventCall(OrbTypes type) {
currentType = type;
orbEffects[currentType].Invoke();
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0f92eb99eeecf254ab1db681d9f7d3e5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -6,17 +6,20 @@ using UnityEngine.Serialization;
public class PlayerController : MonoBehaviour {
[Header("Stats")]
[SerializeField] float speed = 50f;
[SerializeField, Range(0f, .5f)] float acceleration = .1f;
[SerializeField, Range(0f, .5f)] float flipSmooth = .1f;
[SerializeField] float jumpForce = 10f;
[SerializeField, Range(0f, 1f)] float gradualJumpMultiplier = .5f;
Vector2 _input;
float _xVelocity, _flipVelocity;
int _facingDirection = 1;
bool _cancelJump;
Rigidbody2D _rb2d;
[Space]
[Header("Jump Management")]
[SerializeField] LayerMask groundMask;
[SerializeField, Range(0f, 1f)] float feetHeight;
[SerializeField, Range(0f, 2f)] float feetWidth;
@ -40,13 +43,16 @@ public class PlayerController : MonoBehaviour {
_ => _facingDirection
};
transform.localScale =
new Vector3(Mathf.SmoothDamp(transform.localScale.x, _facingDirection, ref _flipVelocity, flipSmooth),
transform.localScale.y, transform.localScale.z);
Vector3 localScale = transform.localScale;
localScale = new Vector3(Mathf.SmoothDamp(localScale.x, _facingDirection, ref _flipVelocity, flipSmooth),
localScale.y, localScale.z);
transform.localScale = localScale;
_isGrounded = Physics2D.OverlapBox(feetPos.position, new Vector2(feetWidth, feetHeight), 0f, groundMask);
if (_isGrounded && _rb2d.velocity.y <= 0f) _coyoteTime = coyoteTime;
if (Input.GetKeyDown(KeyCode.Space)) _jumpBuffer = jumpBuffer;
if (Input.GetKeyUp(KeyCode.Space)) _cancelJump = true;
_jumpBuffer -= Time.deltaTime;
_coyoteTime -= Time.deltaTime;
@ -60,6 +66,11 @@ public class PlayerController : MonoBehaviour {
_rb2d.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
_coyoteTime = _jumpBuffer = 0f;
}
if (_cancelJump) {
if(_rb2d.velocity.y > 0f) _rb2d.velocity = new Vector2(_rb2d.velocity.x, _rb2d.velocity.y * gradualJumpMultiplier);
_cancelJump = false;
}
}
void OnDrawGizmosSelected() {