0

So I'm currently refactoring this "CardElement" system that had logic related to "When claim button is clicked, lockIcon object deactivates" but i want to split up this CardElement logic make a ClaimButton component class and a LockIcon component class and inject them into CardElement. But I want to make the components agnostic of each other but I still need their interaction.

What would be the best way to communicate the LockIcon component that the ClaimButton component has been clicked?

Lets say we had this Card class with a method that was called through a Unity3D button and made a reaction over ClaimButton and LockIcon, disabling them both.

public class Card {
 
 [SerializeField] private GameObject claimButton;
 [SerializeField] private GameObject lockIcon;

 public void OnClaimButtonClicked() {
  claimButton.SetActive(false);
  lockIcon.SetActive(false);
 }
}

But we want to use composite to split the logic for both claimButton and lockIcon into their own classes like so:

ClaimButton

public class ClaimButtonComponent : IComponent {
 [SerializeField] private GameObject claimButton;

 public event Action ButtonClickedEvent;

 public void ButtonClicked() {
  claimButton.SetActive(false);
  ButtonClickedEvent;
 }

LockIcon:

public class LockIconComponent : IComponent {
 [SerializeField] private GameObject lockIcon;

 public void Toggle() {
  lockIcon.SetActive(false);
 }

Making this, components do not know of each other.

The problem comes when I want to make it so we keep the logic related to, when clicking claimButton, lockIcon reacts accordingly without having a direct reference of lockIconComponent in claimButtonComponent.

I have thought something like storing the components through the IComponent abstraction and then, through runtime checkings, check if the Card has the specific components (since we want to make the card agnostic of what cards it has) and then, based on the ones it has, stablish the interactions between components. (I have thought out a more complex system using interaction registries and factories but this is as simple as i could get it to explain the main issue.

public Class Card {
 
 private List<IComponent> components = new List<IComponent>();

 public void Initialize() {
  var claimButton = new ClaimButtonComponent();
  components.add(claimButton);
  var lockIcon = new LockIconComponent();
  components.add(lockIcon);

  HandleComponentInteractions();
 }
 
 private void HandleComponentInteractions() {
   
  if(RetrieveComponent<ClaimButtonComponent>() != null &&
     RetrieveComponent<LockIconComponent>() != null) {
   HandleClaimButtonAndLockIconInteraction();
 }

 private T RetrieveComponent<T>() {
  
  foreach(var component in components) {
   if(component is T) {
    return component;
   }
  return null; 
 }

private void HandleClaimButtonAndLockIconInteraction() {
 
 var claimButton = RetrieveComponent<ClaimButtonComponent>();
 var lockIcon = RetrieveComponent<LockIconComponent>();
 
 claimButton.ButtonClickedEvent += lockIcon.Toggle;
}

My question is, does this way of handling composite components interactions make sense or there is a cleaner way of handling this scenario.

3
  • could you post some your code? Commented Jul 21, 2022 at 7:04
  • Please provide enough code so others can better understand or reproduce the problem. Commented Jul 21, 2022 at 12:17
  • @StepUp I think I have encapsulated the issue within the simplest code example i could now. Commented Jul 21, 2022 at 15:43

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.