| Readme Languages: | ||
| English | Русский | |
This package is a starting point for demonstrating how you can use general purpose MonoBehaviour components that use UnityEvent(-s) so that you don't have to write separate scripts to perform simple and primitive actions.
Have you ever written scripts like:
DisableSpriteRendererOnAwake.cs,SetRawImageColorAlphaWithDelay.cs? These scripts maybe were used only once in the main menu or somewhere else, but they are still in the project and make code navigation and searching in IDE more difficult as their number increases. Previously mentioned scripts work with specific types, and if you need to apply similar logic, for example, not only to sprites, but also to lines, other renderers, or your custom scripts, the number of such scripts will increase, given that it is not always possible to simply specify a base class so that the logic works for all types you work with.I am not an adherent of DRY (Don't Repeat Yourself), and I am not saying that there must be no repeating code in the project, on the contrary, it is ok. But in many cases you can avoid the accumulation of unnecessary garbage scripts by using
UnityEvent(-s), to which you can subscribe most of what you may need.I also hope that, just as with any other programming principles and patterns, you won't blindly attach a given architectural paradigm to everything, but will be able to recognize where it is truly convenient, easy, and appropriate, and where it is worth applying old or other approaches for the sake of optimization or debugging.
- Unity 2021.3 or later
⚠️ After installation, you may need to restart your project so that you can useMonoBehaviourcomponents from this package in the inspector.
Use ONE of two options:
Download a unity package from the latest release.
- Open Package Manager from Window > Package Manager.
- Click the "+" button > Add package from git URL.
- Enter the following URL:
https://github.com/Demexis/Unity-Delegates.git
Alternatively, open Packages/manifest.json and add the following to the dependencies block:
{
"dependencies": {
"com.demegraunt.unitydelegates": "https://github.com/Demexis/Unity-Delegates.git"
}
}1) Check out the list of existing components with a description on the Wiki.
2) Add the necessary components to the game object to execute your game logic, link them together via UnityEvent(-s) if needed.
3) For more complex logic using conditions (if-else), you may need to integrate a custom repository with serializable callbacks, for example, this one: https://github.com/Siccity/SerializableCallback.git
1: Make the sprite used only for work in the editor - invisible in the play mode
2: Spawn a reward with some chance when the object dies
⚠️ SimpleSpawneris just an example of a simple script for spawning a prefab, it is not in this package, but you can easily write one yourself.⚠️ MonoBehaviour.OnDestroy()is not always guaranteed to be called, and is used in this example to simplify the idea. Remember thatOnDestroyis also called when changing a scene, exiting a play mode, or removing script in the editor. Usually each project has its own system of spawning/despawning game objects, and in this case, you could write your own delegate script to avoid the shortcomings ofOnDestroy.
3: A button that plays a sound and redirects to your social networks when clicked
⚠️ InstantiateSoundis just an example of a simple script for playing anAudioClipasset (not included in this package). You can write delegate script for your own audio manager or something similar.
4: Flickering sprite with transparency
5: Toggle for visuals and other things
When creating a game, you may need delegate scripts that allow you to interact with the interface of your systems via
UnityEvent(-s). Although most likely, you could come up with a general-purpose script that is not related to any systems, or you wanted to make a script that allows you to invoke some algorithm viaUnityEventthat interacts with existing components from official Unity packages.
Either way, here are some useful tips for you:
1) All public serializable fields must be auto-properties so that they can be accessed and assigned via UnityEvent(-s).
[field: SerializeField] public float Speed { get; set; } = 1f;2) If the class is not abstract, it should be sealed!
⚠️ In the Unity ecosystem, existing scripts are difficult to rewrite without losing data and method/field references. Don't create inheritance trees where you can safely do without them, even if it requires some code repetition.
3) If you use a custom package that provides serializable callbacks in Unity (similar to System.Func<T>, but with the ability to specify the property/method via the inspector), then you have a great opportunity to separate out pieces of code that might return a value, especially a bool.
[Serializable]
public sealed class BoolCallback : SerializableCallback<bool> { }public sealed class FuncBoolDelegate : MonoBehaviour {
[field: SerializeField] public BoolCallback Callback { get; set; } = new();
[field: SerializeField] public UnityEvent<bool> OnTrigger { get; set; } = new();
[field: SerializeField] public UnityEvent OnTriggerTrue { get; set; } = new();
[field: SerializeField] public UnityEvent OnTriggerFalse { get; set; } = new();
public void Trigger() {
var triggerResult = Callback.Invoke();
OnTrigger.Invoke(triggerResult);
if (triggerResult) {
OnTriggerTrue.Invoke();
} else {
OnTriggerFalse.Invoke();
}
}public sealed class SimplifiedShop : MonoBehaviour {
[field: SerializeField] public int CurrentCurrencyAmount { get; set; }
[field: SerializeField] public int ItemCost { get; set; } = 1;
public bool TryPurchase() {
if (CurrentCurrencyAmount >= ItemCost) {
CurrentCurrencyAmount -= ItemCost;
return true;
}
return false;
}
public void AddAmount(int amount) {
CurrentCurrencyAmount += amount;
}
}




