Last active
January 1, 2021 00:57
-
-
Save dallonf/981648a6786d1a4bc0536cc4f8dfce85 to your computer and use it in GitHub Desktop.
Unity "Reconciler" system
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using System.Linq; | |
using UnityEngine; | |
[System.Serializable] | |
public abstract class BaseReconciler<TKey, TObject> : ISerializationCallbackReceiver where TObject : Object | |
{ | |
private Dictionary<TKey, TObject> managedObjects; | |
private List<TObject> serializedManagedObjects; | |
public ICollection<KeyValuePair<TKey, TObject>> ManagedPairs | |
{ | |
get { return managedObjects; } | |
} | |
public ICollection<TObject> ManagedObjects | |
{ | |
get { return managedObjects.Values; } | |
} | |
public void Reconcile(IEnumerable<TKey> keys) | |
{ | |
if (managedObjects == null) | |
{ | |
managedObjects = new Dictionary<TKey, TObject>(); | |
} | |
var lastKeys = managedObjects.Keys.ToList(); | |
var keysToCreate = keys.Except(lastKeys); | |
var keysToRemove = lastKeys.Except(keys); | |
foreach (var item in keysToCreate) | |
{ | |
var newObj = Create(item); | |
managedObjects.Add(item, newObj); | |
} | |
foreach (var item in keysToRemove) | |
{ | |
Destroy(managedObjects[item]); | |
managedObjects.Remove(item); | |
} | |
} | |
public void Clear() | |
{ | |
foreach (var pair in managedObjects) | |
{ | |
Destroy(pair.Value); | |
} | |
managedObjects.Clear(); | |
} | |
public void OnBeforeSerialize() | |
{ | |
if (managedObjects != null) | |
{ | |
serializedManagedObjects = managedObjects.Values.ToList(); | |
} | |
} | |
public void OnAfterDeserialize() | |
{ | |
if (serializedManagedObjects != null) | |
{ | |
foreach (var item in serializedManagedObjects) | |
{ | |
Destroy(item); | |
} | |
} | |
} | |
/// <summary> | |
/// Create a new TObject and put it in the scene. Must be overriden by the base class. | |
/// </summary> | |
/// <param name="key"></param> | |
/// <returns></returns> | |
public abstract TObject Create(TKey key); | |
/// <summary> | |
/// Destroys a managed object. By default, calls Object.Destroy on it, but can be overridden. | |
/// </summary> | |
/// <param name="obj"></param> | |
protected virtual void Destroy(TObject obj) | |
{ | |
if (obj) | |
{ | |
Object.Destroy(obj); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using System.Linq; | |
using UnityEngine; | |
public class InteractIconManager : MonoBehaviour | |
{ | |
public Player Player; | |
public float IconVisibleRange = 100; | |
public InteractIcon InteractIconPrefab; | |
private InteractMode InteractMode; | |
InteractIconReconciler IconReconciler; | |
void Start() | |
{ | |
Player = GetComponent<Player>(); | |
IconReconciler = new InteractIconReconciler(this); | |
} | |
void FixedUpdate() | |
{ | |
InteractMode = GetComponentInChildren<InteractMode>(true); | |
var interactables = FindObjectsOfType<Interactable>() | |
.Select(i => new { interactable = i, sqDistance = (i.transform.position - Player.transform.position).sqrMagnitude }) | |
.Where(i => i.sqDistance < IconVisibleRange * IconVisibleRange); | |
IconReconciler.Reconcile(interactables.Select(i => i.interactable)); | |
} | |
void OnDestroy() | |
{ | |
IconReconciler.Clear(); | |
} | |
[System.Serializable] | |
class InteractIconReconciler : BaseReconciler<Interactable, InteractIcon> | |
{ | |
private InteractIconManager parent; | |
public InteractIconReconciler(InteractIconManager parent) | |
{ | |
this.parent = parent; | |
} | |
public override InteractIcon Create(Interactable key) | |
{ | |
var icon = Instantiate(parent.InteractIconPrefab, key.transform.position, Quaternion.identity) as InteractIcon; | |
icon.transform.position = key.transform.position; | |
icon.Interactable = key; | |
return icon; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment