Question about Portals?

Hi, i was wondering if there is a way that portal only works/take player to another scene once you’ve defeated the enemy boss?

Hi, i dont remember off the top of my head how the portal works,
but i guess it was by collision?
The simplest way i can think of, if its only 1 boss per level.
You could put a serializefield for a gameobject in the portal where you drag the boss in;

    [SerializeField] GameObject bossToDefeat;

and put this before the portal starts executing stuff

        if(bossToDefeat != null){return;}

If you dont drag anything in the serializefield, nothing happens,
if you drag in a boss, the portal wont work, untill the gameobject is destroyed,
since a missing gameobject(destroyed) becomes null.
Brian will probably come with a prettier solution tho! gl with your game.

1 Like

They’re not always prettier.

The method for implementing this depends on which of the other courses you’ve taken. If you’re just in the Core Combat course, then @RustyNail has the right idea, but we’re going to use the Boss’s Health component instead (because destroying the boss means he won’t be saved as Dead when you transition!)

[SerializeField] Health bossToDefeat; 

void OnTriggerEnter(Collider other)
{
    if(bossToDefeat!=null || bossToDefeat isAlive()) return;

If you’ve taken Dialogues and Quests, then you could set up a Condition that needs to be met before the portal would work. This gives you the flexibility of also having things like unable to pass without a key or a Sword of the Holy McGuffin.
The tricky part is determining if the Boss has been killed within a Condition.

Warning: This next part of the reponse assumes you've taken the aforementioned courses

So we need a way to test a condition of whether or not a particular boss is dead. The best place to check that is within Health, but of course we need a hook to that particular character's health, and typically, we search the players PredicateEvaluators for this... So here's my not so pretty solution: We need to make the SaveableEntity an IPredicateEvaluator, so we can compare the tag of the enemy to it's SaveableEntity, but we also don't want SaveableEntity to rely on Attributes.

First, in SaveableEntity:

        public bool? Evaluate(string predicate, string[] parameters)
        {
            if (predicate == "IsEnemyAlive")
            {
                foreach (SaveableEntity entity in FindObjectsOfType<SaveableEntity>())
                {
                    if (entity.uniqueIdentifier == parameters[0])
                    {
                        foreach (IPredicateEvaluator evaluator in entity.GetComponents<IPredicateEvaluator>())
                        {
                            bool? test = evaluator.Evaluate("IsAlive", parameters);
                            if (test != null) return test;
                        }
                    }
                }
            }
            return null;
        }

Then in Health, which will also need to be an IPredicateEvaluator:

public bool? Evaluate(string predicate, string[] parameters)
{
     if(predicate=="IsAlive") return currentHealth>0;
     return null;

Now in Portal, you can add a Condition to the Portals serialized fields:
[SerializedField] Condition condition;

And then start your OnTriggerEnter like this:

if(!other.gameObject.CompareTag("Player")) return;
if(condition!=null && condition.Evaluate(other.gameObject.GetComponents<IPredicateEvaluator>()==false) return;

And @RustyNail thought my solution would be prettier. HA!

2 Likes

@RustyNail @Brian_Trotter Thank you both for replying. I’ll try these suggestions.