Action Bar (WIP)

Refactor item instance to use DatabaseLink
Labels now pop up when aiming at loot
Yeeted HUD trigger group UI into the abyss
Created rebindable action bar (missing: assigning actions)
Created Consumable Items
Refactored behaviors to work on consumable items
Implemented Velocity Conversion Behavior
This commit is contained in:
Reinier Vens 2021-04-18 05:13:20 +01:00
commit 4489b18452
217 changed files with 5105 additions and 5703 deletions

View file

@ -0,0 +1,206 @@
using System;
using System.Linq;
using JsonKnownTypes;
using MessagePack;
using Newtonsoft.Json;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class ActionBarSlot : MonoBehaviour
{
public TextMeshProUGUI Label;
public RawImage Icon;
public TextMeshProUGUI InputLabel;
public Image InputIcon;
public TextMeshProUGUI QuantityRemaining;
public Image Fill;
private ActionBarBinding binding;
public Entity Entity { get; set; }
public ActionBarBinding Binding
{
get => binding;
set
{
binding = value;
if (binding == null)
{
QuantityRemaining.gameObject.SetActive(false);
Icon.gameObject.SetActive(false);
}
}
}
private void Update()
{
Binding?.Update();
}
public SavedActionBarBinding Save()
{
return Binding switch
{
ActionBarConsumableBinding actionBarConsumableBinding => new SavedActionBarConsumableBinding
{
Target = new DatabaseLink<ConsumableItemData>{LinkID = actionBarConsumableBinding.Target.ID}
},
ActionBarGearBinding actionBarGearBinding => new SavedActionBarGearBinding
{
EquipmentIndex = Entity.Equipment.IndexOf(actionBarGearBinding.Item),
BehaviorIndex = Array.IndexOf(actionBarGearBinding.Item.Behaviors, actionBarGearBinding.Behavior)
},
ActionBarWeaponGroupBinding actionBarWeaponGroupBinding => new SavedActionBarWeaponGroupBinding
{
Group = actionBarWeaponGroupBinding.Group
},
_ => null
};
}
public void Restore(SavedActionBarBinding binding)
{
Binding = binding switch
{
SavedActionBarConsumableBinding savedActionBarConsumableBinding =>
new ActionBarConsumableBinding(
Entity,
this,
savedActionBarConsumableBinding.Target.Value),
SavedActionBarGearBinding savedActionBarGearBinding =>
new ActionBarGearBinding(
Entity,
this,
Entity.Equipment[savedActionBarGearBinding.EquipmentIndex],
Entity.Equipment[savedActionBarGearBinding.EquipmentIndex]
.Behaviors[savedActionBarGearBinding.BehaviorIndex] as IActivatedBehavior),
SavedActionBarWeaponGroupBinding savedActionBarWeaponGroupBinding =>
new ActionBarWeaponGroupBinding(Entity, this, savedActionBarWeaponGroupBinding.Group),
_ => null
};
}
}
public abstract class ActionBarBinding
{
protected Entity Entity { get; }
protected ActionBarSlot Slot { get; }
public abstract void Activate();
public abstract void Deactivate();
public abstract void Update();
public ActionBarBinding(Entity entity, ActionBarSlot slot)
{
Entity = entity;
Slot = slot;
}
}
public class ActionBarConsumableBinding : ActionBarBinding
{
public ConsumableItemData Target;
public ActionBarConsumableBinding(Entity entity, ActionBarSlot slot, ConsumableItemData target) : base(entity, slot)
{
Target = target;
Slot.QuantityRemaining.gameObject.SetActive(true);
var data = Target;
if(!string.IsNullOrEmpty(data.Icon))
{
Slot.Label.gameObject.SetActive(false);
Slot.Icon.gameObject.SetActive(true);
Slot.Icon.texture = Resources.Load<Texture2D>(data.Icon.Substring("Assets/Resources/".Length).Split('.').First());
}
else Slot.Icon.gameObject.SetActive(false);
}
public override void Activate()
{
Entity.TryActivateConsumable(Target);
}
public override void Deactivate()
{
}
public override void Update()
{
Slot.QuantityRemaining.text = $"{Entity.CountItemsInCargo(Target.ID)}";
var instance = Entity.FindActiveConsumable(Target);
if (instance == null) Slot.Fill.fillAmount = 0;
else Slot.Fill.fillAmount = instance.RemainingDuration / instance.Data.Duration;
}
}
public class ActionBarGearBinding : ActionBarBinding
{
public EquippedItem Item { get; }
public IActivatedBehavior Behavior { get; }
public bool Active;
public ActionBarGearBinding(Entity entity, ActionBarSlot slot, EquippedItem item, IActivatedBehavior behavior) : base(entity, slot)
{
Item = item;
Behavior = behavior;
Slot.QuantityRemaining.gameObject.SetActive(false);
if(!string.IsNullOrEmpty(Item.Data.ActionBarIcon))
{
Slot.Label.gameObject.SetActive(false);
Slot.Icon.gameObject.SetActive(true);
Slot.Icon.texture = Resources.Load<Texture2D>(Item.Data.ActionBarIcon.Substring("Assets/Resources/".Length).Split('.').First());
}
else Slot.Icon.gameObject.SetActive(false);
}
public override void Activate()
{
Active = true;
Behavior.Activate();
}
public override void Deactivate()
{
Active = false;
Behavior.Deactivate();
}
public override void Update()
{
Slot.Fill.fillAmount = Active ? 1 : 0;
}
}
[MessagePackObject]
public class ActionBarWeaponGroupBinding : ActionBarBinding
{
[Key(0)] public int Group;
public ActionBarWeaponGroupBinding(Entity entity, ActionBarSlot slot, int group) : base(entity, slot)
{
Group = group;
slot.Label.text = $"G{Group}";
Slot.Icon.gameObject.SetActive(false);
}
public override void Activate()
{
foreach (var weapon in Entity.TriggerGroups[Group].weapons)
{
weapon.Activate();
}
}
public override void Deactivate()
{
foreach (var weapon in Entity.TriggerGroups[Group].weapons)
{
weapon.Deactivate();
}
}
public override void Update()
{
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f285e0b05ca24b83bd6cd48419cbad6e
timeCreated: 1618532311

View file

@ -62,9 +62,7 @@ public class ActionGameManager : MonoBehaviour
}
public static Sector CurrentSector;
public GameSettings Settings;
//public string StarterShipTemplate = "Longinus";
public float2 Sensitivity;
@ -80,7 +78,14 @@ public class ActionGameManager : MonoBehaviour
public PostProcessVolume SevereHeatstrokePP;
public PostProcessVolume SevereHypothermiaPP;
[Header("Input Icons")]
public Sprite ShiftIcon;
public Sprite MouseLeftIcon;
public Sprite MouseMiddleIcon;
[Header("Scene Links")]
public Transform ActionBar;
public ActionBarSlot ActionBarSlot;
public Transform EffectManagerParent;
public TradeMenu TradeMenu;
public Prototype HostileTargetIndicator;
@ -132,6 +137,8 @@ public class ActionGameManager : MonoBehaviour
private float _severeHeatstrokePhase;
private bool _uiHidden;
private bool _menuShown;
private List<ActionBarSlot> _actionBarSlots = new List<ActionBarSlot>();
private List<InputAction> _actionBarActions = new List<InputAction>();
public AetheriaInput Input { get; private set; }
public EquippedDockingBay DockingBay { get; private set; }
@ -197,7 +204,6 @@ public class ActionGameManager : MonoBehaviour
Input = new AetheriaInput();
Input.Global.Enable();
Input.UI.Enable();
_zoomLevelIndex = Settings.DefaultMinimapZoom;
Input.Player.MinimapZoom.performed += context =>
@ -232,44 +238,7 @@ public class ActionGameManager : MonoBehaviour
else Undock();
};
Input.Global.MainMenu.performed += context =>
{
if (EventSystem.current.currentSelectedGameObject?.GetComponent<TMP_InputField>() != null) return;
if (CurrentEntity == null) return;
if (MainMenu.gameObject.activeSelf)
{
_paused = false;
VolumeRenderer.EnableDepth = true;
MainMenu.gameObject.SetActive(false);
if (_menuShown)
{
Menu.gameObject.SetActive(true);
}
else
{
GameplayUI.gameObject.SetActive(true);
Cursor.lockState = CursorLockMode.Locked;
Input.Player.Enable();
}
}
else
{
_paused = true;
VolumeRenderer.EnableDepth = false;
MainMenu.gameObject.SetActive(true);
_menuShown = Menu.gameObject.activeSelf;
if (_menuShown)
{
Menu.gameObject.SetActive(false);
}
else
{
GameplayUI.gameObject.SetActive(false);
Cursor.lockState = CursorLockMode.None;
Input.Player.Disable();
}
}
};
Input.Global.MainMenu.performed += context => ToggleMainMenu();
Input.Player.EnterWormhole.performed += context =>
{
@ -349,123 +318,42 @@ public class ActionGameManager : MonoBehaviour
#endregion
#region Trigger Groups
#region Action Bar
Input.Player.PreviousWeaponGroup.performed += context =>
ActionBarSlot createBinding(string controlPath)
{
if (CurrentEntity.Parent != null) return;
SchematicDisplay.SelectedGroupIndex--;
};
var action = new InputAction(binding: controlPath);
_actionBarActions.Add(action);
var slot = Instantiate(ActionBarSlot, ActionBar);
_actionBarSlots.Add(slot);
action.started += context => slot.Binding?.Activate();
action.canceled += context => slot.Binding?.Deactivate();
return slot;
}
Input.Player.NextWeaponGroup.performed += context =>
{
if (CurrentEntity.Parent != null) return;
SchematicDisplay.SelectedGroupIndex++;
};
Input.Player.PreviousWeapon.performed += context =>
{
if (CurrentEntity.Parent != null) return;
SchematicDisplay.SelectedItemIndex--;
};
Input.Player.NextWeapon.performed += context =>
{
if (CurrentEntity.Parent != null) return;
SchematicDisplay.SelectedItemIndex++;
};
Input.Player.ToggleWeaponGroup.performed += context =>
{
if (CurrentEntity.Parent != null) return;
var item = SchematicDisplay.SchematicItems[SchematicDisplay.SelectedItemIndex];
if (CurrentEntity.TriggerGroups[SchematicDisplay.SelectedGroupIndex].items.Contains(item.Item))
CurrentEntity.TriggerGroups[SchematicDisplay.SelectedGroupIndex].items.Remove(item.Item);
else CurrentEntity.TriggerGroups[SchematicDisplay.SelectedGroupIndex].items.Add(item.Item);
foreach (var group in item.Item.BehaviorGroups.Values)
{
var weapon = group.GetBehavior<Weapon>();
if(weapon != null)
{
if (CurrentEntity.TriggerGroups[SchematicDisplay.SelectedGroupIndex].weapons.Contains(weapon))
CurrentEntity.TriggerGroups[SchematicDisplay.SelectedGroupIndex].weapons.Remove(weapon);
else CurrentEntity.TriggerGroups[SchematicDisplay.SelectedGroupIndex].weapons.Add(weapon);
}
}
SchematicDisplay.UpdateTriggerGroups();
};
var shift = createBinding("<Keyboard>/leftShift");
shift.InputIcon.sprite = ShiftIcon;
shift.InputLabel.gameObject.SetActive(false);
Input.Player.FireGroup1.started += context =>
{
if (CurrentEntity.Parent != null) return;
foreach (var s in CurrentEntity.TriggerGroups[0].weapons) s.Activate();
};
var left = createBinding("<Mouse>/leftButton");
left.InputIcon.sprite = MouseLeftIcon;
left.InputLabel.gameObject.SetActive(false);
var right = createBinding("<Mouse>/rightButton");
right.InputIcon.sprite = MouseLeftIcon;
right.InputIcon.transform.localScale = new Vector3(-1, 1, 1);
right.InputLabel.gameObject.SetActive(false);
var middle = createBinding("<Mouse>/middleButton");
middle.InputIcon.sprite = MouseMiddleIcon;
middle.InputLabel.gameObject.SetActive(false);
Input.Player.FireGroup1.canceled += context =>
for (int i = 1; i < 6; i++)
{
if (CurrentEntity.Parent != null) return;
foreach (var s in CurrentEntity.TriggerGroups[0].weapons) s.Deactivate();
};
Input.Player.FireGroup2.started += context =>
{
if (CurrentEntity.Parent != null) return;
foreach (var s in CurrentEntity.TriggerGroups[1].weapons) s.Activate();
};
Input.Player.FireGroup2.canceled += context =>
{
if (CurrentEntity.Parent != null) return;
foreach (var s in CurrentEntity.TriggerGroups[1].weapons) s.Deactivate();
};
Input.Player.FireGroup3.started += context =>
{
if (CurrentEntity.Parent != null) return;
foreach (var s in CurrentEntity.TriggerGroups[2].weapons) s.Activate();
};
Input.Player.FireGroup3.canceled += context =>
{
if (CurrentEntity.Parent != null) return;
foreach (var s in CurrentEntity.TriggerGroups[2].weapons) s.Deactivate();
};
Input.Player.FireGroup4.started += context =>
{
if (CurrentEntity.Parent != null) return;
foreach (var s in CurrentEntity.TriggerGroups[3].weapons) s.Activate();
};
Input.Player.FireGroup4.canceled += context =>
{
if (CurrentEntity.Parent != null) return;
foreach (var s in CurrentEntity.TriggerGroups[3].weapons) s.Deactivate();
};
Input.Player.FireGroup5.started += context =>
{
if (CurrentEntity.Parent != null) return;
foreach (var s in CurrentEntity.TriggerGroups[4].weapons) s.Activate();
};
Input.Player.FireGroup5.canceled += context =>
{
if (CurrentEntity.Parent != null) return;
foreach (var s in CurrentEntity.TriggerGroups[4].weapons) s.Deactivate();
};
Input.Player.FireGroup6.started += context =>
{
if (CurrentEntity.Parent != null) return;
foreach (var s in CurrentEntity.TriggerGroups[5].weapons) s.Activate();
};
Input.Player.FireGroup6.canceled += context =>
{
if (CurrentEntity.Parent != null) return;
foreach (var s in CurrentEntity.TriggerGroups[5].weapons) s.Deactivate();
};
var num = createBinding($"<Keyboard>/{i}");
num.InputIcon.gameObject.SetActive(false);
num.InputLabel.text = i.ToString();
}
#endregion
@ -579,6 +467,18 @@ public class ActionGameManager : MonoBehaviour
});
}
public void EnablePlayerInput()
{
Input.Player.Enable();
foreach (var a in _actionBarActions) a.Enable();
}
public void DisablePlayerInput()
{
Input.Player.Disable();
foreach (var a in _actionBarActions) a.Disable();
}
private void EnterWormhole(Wormhole wormhole)
{
if (!(CurrentEntity is Ship ship)) return;
@ -639,6 +539,45 @@ public class ActionGameManager : MonoBehaviour
}
}
private void ToggleMainMenu()
{
if (EventSystem.current.currentSelectedGameObject?.GetComponent<TMP_InputField>() != null) return;
if (CurrentEntity == null) return;
if (MainMenu.gameObject.activeSelf)
{
_paused = false;
VolumeRenderer.EnableDepth = true;
MainMenu.gameObject.SetActive(false);
if (_menuShown)
{
Menu.gameObject.SetActive(true);
}
else
{
GameplayUI.gameObject.SetActive(true);
EnablePlayerInput();
Cursor.lockState = CursorLockMode.Locked;
}
}
else
{
_paused = true;
VolumeRenderer.EnableDepth = false;
MainMenu.gameObject.SetActive(true);
_menuShown = Menu.gameObject.activeSelf;
if (_menuShown)
{
Menu.gameObject.SetActive(false);
}
else
{
GameplayUI.gameObject.SetActive(false);
Cursor.lockState = CursorLockMode.None;
DisablePlayerInput();
}
}
}
private void ToggleMenuTab(MenuTab tab)
{
if (EventSystem.current.currentSelectedGameObject?.GetComponent<TMP_InputField>() != null) return;
@ -649,7 +588,7 @@ public class ActionGameManager : MonoBehaviour
Menu.gameObject.SetActive(false);
if (CurrentEntity != null && CurrentEntity.Parent == null)
{
Input.Player.Enable();
EnablePlayerInput();
GameplayUI.gameObject.SetActive(true);
SchematicDisplay.ShowShip(CurrentEntity);
@ -659,7 +598,7 @@ public class ActionGameManager : MonoBehaviour
}
Cursor.lockState = CursorLockMode.None;
Input.Player.Disable();
DisablePlayerInput();
Menu.ShowTab(tab);
GameplayUI.gameObject.SetActive(false);
}
@ -832,7 +771,7 @@ public class ActionGameManager : MonoBehaviour
_visibleHostileIndicators.Clear();
if(_lockingIndicators!=null) foreach(var (_, indicator, _) in _lockingIndicators)
indicator.GetComponent<Prototype>().ReturnToPool();
Input.Player.Disable();
DisablePlayerInput();
Cursor.lockState = CursorLockMode.None;
GameplayUI.gameObject.SetActive(false);
@ -862,7 +801,7 @@ public class ActionGameManager : MonoBehaviour
_viewDirection = float3(CurrentEntity.Direction.x,0,CurrentEntity.Direction.y);
Cursor.lockState = CursorLockMode.Locked;
Input.Player.Enable();
EnablePlayerInput();
GameplayUI.gameObject.SetActive(true);
ShipPanel.Display(CurrentEntity, true);
SchematicDisplay.ShowShip(CurrentEntity);

View file

@ -1,6 +1,41 @@
using System;
using TMPro;
using Unity.Mathematics;
using UnityEngine;
using static Unity.Mathematics.math;
public class ItemPickup : MonoBehaviour
{
public float LabelFadeDuration = .5f;
public float LabelPersistDuration = 3;
public float LabelDisplayAngle = 15;
public float LabelDisplayMaxDistance = 500;
public Transform ScanLabelContainer;
public TextMeshPro ScanLabel;
public ItemInstance Item { get; set; }
public ZoneRenderer ZoneRenderer { get; set; }
public float3 ViewOrigin { get; set; }
public float3 ViewDirection { get; set; }
private float _displayTime;
private void Update()
{
var diff = (float3) transform.position - ViewOrigin;
var toThis = normalize(diff);
var viewAngle = acos(Vector3.Dot(toThis, ViewDirection)) * Mathf.Rad2Deg;
if (length(diff) < LabelDisplayMaxDistance && viewAngle < LabelDisplayAngle)
_displayTime = Time.time;
var targetAlpha = Time.time - _displayTime < LabelPersistDuration ? 1 : 0;
var c = ScanLabel.color;
c.a = c.a + sign(targetAlpha - c.a) * (Time.deltaTime / LabelFadeDuration);
ScanLabel.color = c;
ScanLabelContainer.rotation = Quaternion.LookRotation(-toThis);
}
private void OnDestroy()
{
ZoneRenderer.DestroyLoot(this);
}
}