achievement system example

This commit is contained in:
max 2022-12-28 14:56:13 +01:00
parent 37a4cdb1e1
commit 23f7283e28
18 changed files with 527 additions and 0 deletions

View File

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

View File

@ -0,0 +1,16 @@
{
"name": "AchievementSystem",
"rootNamespace": "",
"references": [
"GUID:73106583b323919458c1e05166706ce3"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 7b45b7480b703784cbbb1d5d6fe4f98c
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@ -0,0 +1,53 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c041c0f0630187644bd2e92ba3dbbb37, type: 3}
m_Name: DatabaseObject
m_EditorClassIdentifier:
achievements:
- name: KillEasySkeletons
icon: {fileID: 0}
platformsSettings:
- rid: 332205990316343307
- rid: 332205990316343308
- rid: 332205990316343312
unlock:
unlockTriggers:
- rid: 332205990316343309
unlockConditions:
- rid: 332205990316343310
- rid: 332205990316343311
references:
version: 2
RefIds:
- rid: 332205990316343307
type: {class: PC, ns: , asm: AchievementSystem}
data:
achievementKey: sadkjhw8rh23hr0293rh2039rh
- rid: 332205990316343308
type: {class: PS4, ns: , asm: AchievementSystem}
data:
achievementKey: asd234e234sd2342d23e
- rid: 332205990316343309
type: {class: EnemyKilledTrigger, ns: , asm: AchievementSystem}
- rid: 332205990316343310
type: {class: KillEnemies, ns: , asm: AchievementSystem}
data:
targetType: 0
targetKills: 100
- rid: 332205990316343311
type: {class: LevelDifficulty, ns: , asm: AchievementSystem}
data:
difficulty: 0
- rid: 332205990316343312
type: {class: SteamDeck, ns: , asm: AchievementSystem}
data:
achievementKey: 12342673658362456458356824612

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 769f40e54734cab4598106717122485f
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,18 @@
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "DatabaseObject", menuName = "DatabaseObject")]
public class DatabaseObject : ScriptableObject
{
public List<Achievement> achievements = new List<Achievement>();
}
[System.Serializable]
public class Achievement
{
public string name;
public Sprite icon;
[SerializeReference, SerializeReferenceButton]
public IPlatform[] platformsSettings = null;
public Unlock unlock;
}

View File

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

View File

@ -0,0 +1,54 @@
using UnityEngine;
public interface IPlatform
{
public string AchievementKey { get; }
}
[System.Serializable]
public class PC : IPlatform
{
public string AchievementKey => achievementKey;
[SerializeField]
private string achievementKey;
}
[System.Serializable]
public class PS4 : IPlatform
{
public string AchievementKey => achievementKey;
[SerializeField]
private string achievementKey;
}
[System.Serializable]
public class PS5 : IPlatform
{
public string AchievementKey => achievementKey;
[SerializeField]
private string achievementKey;
}
[System.Serializable]
public class XBOX : IPlatform
{
public string AchievementKey => achievementKey;
[SerializeField]
private string achievementKey;
}
[System.Serializable]
public class Quest : IPlatform
{
public string AchievementKey => achievementKey;
[SerializeField]
private string achievementKey;
}
[System.Serializable]
public class SteamDeck : IPlatform
{
public string AchievementKey => achievementKey;
[SerializeField]
private string achievementKey;
}

View File

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

View File

@ -0,0 +1,141 @@
using System;
using UnityEngine;
public interface IUnlockCondition
{
public event Action OnUnlockEvent;
public bool IsUnlocked { get; }
public float Progress { get; }
public bool ResetOnFailedCheck { get; }
//public UnlockResetMode { get; }
//public IString ProgressString { get; }
//public IString UnlockString { get; }
public bool ShouldBePersistent { get; }
public string Data { get; set; }
public void Initialize();
public void Reset();
}
// Maybe make an IUnlockReset interface to have expandable unlock reset modes.
// The interface could then return a bool if it should reset or not.
public enum UnlockResetMode
{
NeverReset,
ResetOnFailedCheck,
ResetWithOthers,
}
public enum EnemyType
{
Skeleton,
Zombie,
Dragon,
Snek
}
public enum Difficulty
{
Easy,
Medium,
Hard
}
[System.Serializable]
public class KillEnemies : IUnlockCondition
{
// Serialized Parameters.
[SerializeField]
private EnemyType targetType = EnemyType.Skeleton;
[SerializeField]
private int targetKills = 100;
// Implementation.
public event Action OnUnlockEvent;
public bool IsUnlocked => kills >= targetKills;
public float Progress => kills / targetKills;
public bool ResetOnFailedCheck => false;
public bool ShouldBePersistent => true;
public string Data { get => kills.ToString(); set { kills = int.Parse(value); } }
private int kills = 0;
public void Initialize()
{
// Start listening to some events to collect data.
}
public void Reset()
{
kills = 0;
}
}
[System.Serializable]
public class LevelDifficulty : IUnlockCondition
{
[SerializeField]
private Difficulty difficulty = Difficulty.Easy;
public event Action OnUnlockEvent;
public bool IsUnlocked => false;
public float Progress => 0;
public bool ResetOnFailedCheck => true;
public bool ShouldBePersistent => false;
public string Data { get => ""; set { } }
public void Initialize()
{
// Start listening to some events to collect data.
}
public void Reset()
{
}
}
[System.Serializable]
public class Accuracy : IUnlockCondition
{
[SerializeField, Range(0, 1)]
private float targetAccuracy = 0.5f;
public event Action OnUnlockEvent;
public bool IsUnlocked => false;
public float Progress => 0;
public bool ResetOnFailedCheck => true;
public bool ShouldBePersistent => false;
public string Data { get => ""; set { } }
public void Initialize()
{
// Start listening to some events to collect data.
}
public void Reset()
{
}
}
[System.Serializable]
public class OwnDLC : IUnlockCondition
{
[SerializeField]
private string dlcName = "";
public event Action OnUnlockEvent;
public bool IsUnlocked => false;
public float Progress => 0;
public bool ResetOnFailedCheck => true;
public bool ShouldBePersistent => false;
public string Data { get => ""; set { } }
public void Initialize()
{
// Start listening to some events to collect data.
}
public void Reset()
{
}
}

View File

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

View File

@ -0,0 +1,31 @@
using System;
public interface IUnlockTrigger
{
public event Action OnTriggerEvent;
public void Initialize();
}
[System.Serializable]
public class LevelCompleteTrigger : IUnlockTrigger
{
public event Action OnTriggerEvent;
public void Initialize()
{
// Subscribe to on level complete event.
// OnTriggerEvent?.Invoke();
}
}
[System.Serializable]
public class EnemyKilledTrigger : IUnlockTrigger
{
public event Action OnTriggerEvent;
public void Initialize()
{
// Subscribe to on enemy killed event.
// OnTriggerEvent?.Invoke();
}
}

View File

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

View File

@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Unlock : IDisposable
{
public event Action OnUnlockEvent;
[SerializeReference, SerializeReferenceButton] private List<IUnlockTrigger> unlockTriggers = new List<IUnlockTrigger>();
[SerializeReference, SerializeReferenceButton] private List<IUnlockCondition> unlockConditions = new List<IUnlockCondition>();
public void Initialize()
{
foreach (IUnlockCondition condition in unlockConditions)
{
condition.Initialize();
}
foreach (IUnlockTrigger trigger in unlockTriggers)
{
trigger.OnTriggerEvent += HandleOnTriggerEvent;
trigger.Initialize();
}
}
public void Dispose()
{
foreach (IUnlockTrigger trigger in unlockTriggers)
{
trigger.OnTriggerEvent -= HandleOnTriggerEvent;
}
}
// Format data in some way to store compactly and be re-storable after load.
public bool Save(out string data)
{
data = "";
bool shouldSave = false;
foreach (IUnlockCondition condition in unlockConditions)
{
if (condition.ShouldBePersistent)
{
data += condition.Data;
shouldSave = true;
}
}
return shouldSave;
}
// Unpack data and load into conditions.
public void Load(string data)
{
foreach (IUnlockCondition condition in unlockConditions)
{
if (condition.ShouldBePersistent)
{
condition.Data = data;
}
}
}
public bool IsUnlocked()
{
foreach (IUnlockCondition condition in unlockConditions)
{
if (!condition.IsUnlocked)
{
return false;
}
}
return true;
}
private void HandleOnTriggerEvent()
{
bool shouldReset = false;
foreach (IUnlockCondition condition in unlockConditions)
{
if (!condition.IsUnlocked && condition.ResetOnFailedCheck)
{
shouldReset = true;
break;
}
}
if (shouldReset)
{
foreach (IUnlockCondition condition in unlockConditions)
{
condition.Reset();
}
}
else if (IsUnlocked())
{
OnUnlockEvent?.Invoke();
}
}
}

View File

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

View File

@ -0,0 +1,14 @@
using UnityEngine;
public class UnlockSystem : MonoBehaviour
{
public DatabaseObject dataBase;
public void OnFireBaseLoaded()
{
foreach (Achievement achievement in dataBase.achievements)
{
achievement.unlock.Initialize();
}
}
}

View File

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