-
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
GITBOOK-24: change request with no subject merged in GitBook
- Loading branch information
1 parent
4aaed1b
commit 5dfb674
Showing
4 changed files
with
169 additions
and
0 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
--- | ||
layout: | ||
title: | ||
visible: true | ||
description: | ||
visible: false | ||
tableOfContents: | ||
visible: true | ||
outline: | ||
visible: false | ||
pagination: | ||
visible: true | ||
--- | ||
|
||
# Avoiding Prop Drilling | ||
|
||
Prop Drilling is a problem that occurs when within a hierarchy a specific data must be passed from one point to another | ||
|
||
<figure><img src="../.gitbook/assets/main-qimg-212a32ca0d74c300fdeb2c6a6e751769.png" alt=""><figcaption><p>(1) Need to send a message to (6)</p></figcaption></figure> | ||
|
||
{% code fullWidth="true" %} | ||
```csharp | ||
using UnityEngine; | ||
using UnityEngine.UI; | ||
public class GameManager : MonoBehaviour | ||
{ | ||
[SerializeField] private int playerScore = 100; | ||
[SerializeField] private UIManager uiManager; | ||
private void Start() | ||
{ | ||
uiManager.SetPlayerScore(playerScore); | ||
} | ||
} | ||
public class UIManager : MonoBehaviour | ||
{ | ||
[SerializeField] private UIPlayerScoreController uiPlayerScore; | ||
private void SetPlayerScore(int score) | ||
{ | ||
uiPlayerScore.SetScore = score; | ||
} | ||
} | ||
public class UIPlayerScoreController : MonoBehaviour | ||
{ | ||
[SerializeField] private Text text_score; | ||
private void SetScore(int score) | ||
{ | ||
text_score.text = score.ToString(); | ||
} | ||
} | ||
``` | ||
{% endcode %} | ||
|
||
The problem with this approach is the implication of having to pass a piece of data through many methods and classes to complete its function. | ||
|
||
Now let's do a test handling it with States: | ||
|
||
{% code fullWidth="true" %} | ||
```csharp | ||
using UnityEngine; | ||
using UnityEngine.UI; | ||
using UniFlux; | ||
public class GameManager : MonoBehaviour | ||
{ | ||
[SerializeField] private int playerScore = 100; | ||
private void Start() | ||
{ | ||
"PlayerScore".Dispatch(PlayerScore); | ||
} | ||
} | ||
public class UIManager : MonoBehaviour | ||
{ | ||
// Nothing here required. | ||
} | ||
public class UIPlayerScoreController : MonoFlux | ||
{ | ||
[SerializeField] private Text text_score; | ||
[StateFlux("PlayerScore")] private void SetScore(int state) | ||
{ | ||
text_score.text = score.ToString(); | ||
} | ||
} | ||
``` | ||
{% endcode %} | ||
|
||
Note that in this example UIManager is no longer required, and you can have fewer variables and dependencies. In this example we have used StateFlux instead of MethodFlux, this means that if another subscribed to the "PlayerScore" it would automatically take the last state without depending on all the information being sent to it again. |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
--- | ||
layout: | ||
title: | ||
visible: true | ||
description: | ||
visible: false | ||
tableOfContents: | ||
visible: true | ||
outline: | ||
visible: false | ||
pagination: | ||
visible: true | ||
--- | ||
|
||
# Messaging Alternative | ||
|
||
A common case in event handling is usually the use of UnityEvents or Actions (in case you use them by System) | ||
|
||
Here is an example introduction: | ||
|
||
```csharp | ||
using System; | ||
using UnityEngine; | ||
public class Element : MonoBehaviour | ||
{ | ||
public Action<Element> OnInteract; | ||
private void Start() | ||
{ | ||
Interact(); | ||
} | ||
private void Interact() | ||
{ | ||
OnInteract?.Invoke(this); | ||
} | ||
} | ||
public class Manager : MonoBehaviour | ||
{ | ||
[SerializeField] private Element[] elements; | ||
private void OnEnable() | ||
{ | ||
for (int i = 0; i < elements.Length; i++) | ||
{ | ||
elements[i].OnInteract += OnInteract; | ||
} | ||
} | ||
private void OnDisable() | ||
{ | ||
for (int i = 0; i < elements.Length; i++) | ||
{ | ||
elements[i].OnInteract -= OnInteract; | ||
} | ||
} | ||
private void OnInteract(Element element) | ||
{ | ||
// Something Happens | ||
} | ||
} | ||
``` | ||
|
||
In the case that the communication that we want to implement can be treated as global, an event like this can be created directly: | ||
|
||
```csharp | ||
using System; | ||
using UnityEngine; | ||
using UniFlux; | ||
public class Element : MonoBehaviour | ||
{ | ||
private void Interact() | ||
{ | ||
"OnInteract".Dispatch(this); | ||
} | ||
} | ||
public class Manager : MonoFlux | ||
{ | ||
[MethodFlux("OnInteract")] private void OnInteract(Element element) | ||
{ | ||
// Something Happens | ||
} | ||
} | ||
``` | ||
|
||
In this example we avoid having direct dependencies and we also do not have to maintain variables with the list of elements |