Hi all, I am making a turn based CCG for fun and educational purposes. At the moment I have a system in place for creating card effects, it is usable but not up to the standard I would like to have.
Current System:
Each effect contains 3 main properties:
- A list of triggers
A trigger is an event in the game world
Example: When a card is played
- A list of conditions
Conditions are the necessary states needed in order to execute the effect action
Example: If the player has more than x life
- A list of effect actions
An effect action alters the state of the game/player/card in some way
Example: Deal x damage to the opponent
The problem with the current system:
This system requires me to create a new game object for each card effect. There is no need for this to be a game object. Also, any trigger,condition or effect action that the card uses must be attached to the game object. This can lead to a very cluttered inspector view on more complex effects.
As previously stated, this works but I feel it can be improved upon and can’t seem to figure out how.
Alternatives:
I have played around with scriptable objects without much success. For example, if I had an EffectAction class called DealDamageToPlayer, anytime I want to use this class on an effect; I would need to create a new instance because it would alter the original value. This would leave me with multiple copies of the same class all with different values. Also, I understand that this also occurs with the current system, when I attach the same script to multiple effect game objects. The difference is that it is not visible in the project explorer and does not result in clutter.
Similar Questions:
My original system was inspired by this question ‘What is the most effective way to structure Card Effects in a Single Player game?’ They ran into the same issue I mentioned in the alternatives section with regards to scriptable objects.
This question: ‘Card Game, cards as ScriptableObject, card effects as ScriptableObjects, effects have different parameters. How to make an inspector UI support this structure?’ includes the type of UI I am after. However, because they use scriptable objects there will be many duplicate instances.
If anything I said is incorrect, please do correct me.
Any and all assistance would be greatly appreciated.
Scripts:
Trigger.cs
public abstract class Trigger : MonoBehaviour
{
public abstract void SubscribeToEvent(Action<EventInfo> checkConditions);
public abstract void UnsubscribeFromEvent(Action<EventInfo> checkConditions);
}
Condition.cs
public abstract class Condition : MonoBehaviour
{
public abstract bool Requirement(EventInfo eventInfo);
}
EffectAction.cs
public abstract class EffectAction : MonoBehaviour
{
public abstract void ApplyEffectAction();
}
Effect.cs
public class Effect : MonoBehaviour
{
[Header("WHEN")]
public List<Trigger> triggers;
[Header("IF")]
public List<Condition> conditions;
[Header("DO")]
public EffectAction effectAction;
public void SetUpTriggers()
{
foreach (Trigger trigger in triggers)
{
trigger.SubscribeToEvent(CheckConditions);
}
}
public void RemoveTriggers()
{
foreach (Trigger trigger in triggers)
{
trigger.UnsubscribeFromEvent(CheckConditions);
}
}
public void CheckConditions(EventInfo eventInfo)
{
if (conditions.Count != 0)
{
foreach (Condition condition in conditions)
{
if (!condition.Requirement(eventInfo))
{
Debug.Log("CheckConditions: false");
return;
}
}
}
effectAction.ApplyEffectAction();
}
}