problem understanding return statement

Hi! Please help me understand where exactly does it return true within CanPlayerBeSeen() function. To me it looks like there is another check within the return statement on line 7., to return only when PlayerHiddenByObstacles is false. If both previous checks are true and one within? the return statement is false, does it return true on line 7? Or CanPLayerBeSeen() returns True somewhere else? Hopefully that makes sense… Thank you!

bool CanPlayerBeSeen()
    {
        // we only need to check visibility if the player is within the enemy's visual range
        if (playerInRange)
        {
            if (PlayerInFieldOfView())
                return (!PlayerHiddenByObstacles());  
            else
                return false;

        }
        else
        {
            // always false if the player is not within the enemy's range
            return false;
        }

        //return playerInRange;

    }

Here is the whole script just in case:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class EnemySenses : MonoBehaviour
{

    // Use this for initialization
    public bool playerInRange; // is the player within the enemy's sight range collider (this only checks if the enemy can theoretically see the player if nothing is in the way)
    //public bool playerIsSeen;
    private Animator anim;

    [SerializeField]
    SpriteRenderer spr;


    [SerializeField]
    Transform lineOfSightEnd;
    Transform player; // a reference to the player for raycasting

    void Awake()
    {
        anim = GetComponentInParent<Animator>();
    }

    void Start()
    {
        playerInRange = false;
        player = GameObject.Find("Player").transform;
    }


 
    void FixedUpdate()
    {
        if (CanPlayerBeSeen())
        {
            //playerIsSeen = true;
            //Debug.Log ("player can be seen");
            anim.SetBool ("Alerted", true);
            SendMessageUpwards ("PlayerInSight");
        }
        else
            //playerIsSeen = false;
            anim.SetBool ("Alerted", false);
            //Debug.Log ("player cant be seen");
    }


    bool CanPlayerBeSeen()
    {
        // we only need to check visibility if the player is within the enemy's visual range
        if (playerInRange)
        {
            if (PlayerInFieldOfView())
                return (!PlayerHiddenByObstacles());  
            else
                return false;

        }
        else
        {
            // always false if the player is not within the enemy's range
            return false;
        }

        //return playerInRange;

    }
    void OnTriggerStay2D(Collider2D other)
    {
        // if 'other' is player, the player is seen
        // note, we don't really need to check the transform tag since the collision matrix is set to only 'see' collisions with the player layer
        if (other.transform.tag == "Player")
            playerInRange = true;
    }

    void OnTriggerExit2D(Collider2D other)
    {
        // if 'other' is player, the player is seen
        // note, we don't really need to check the transform tag since the collision matrix is set to only 'see' collisions with the player layer
        if (other.transform.tag == "Player")
            playerInRange = false;
    }

    bool PlayerInFieldOfView()
    {
        // check if the player is within the enemy's field of view
        // this is only checked if the player is within the enemy's sight range

        // find the angle between the enemy's 'forward' direction and the player's location and return true if it's within 65 degrees (for 130 degree field of view)
        Vector2 directionToPlayer = player.position - transform.position; // represents the direction from the enemy to the player   
        Debug.DrawLine(transform.position, player.position, Color.magenta); // a line drawn in the Scene window equivalent to directionToPlayer
       
        Vector2 lineOfSight = lineOfSightEnd.position - transform.position; // the centre of the enemy's field of view, the direction of looking directly ahead
        Debug.DrawLine(transform.position, lineOfSightEnd.position, Color.yellow); // a line drawn in the Scene window equivalent to the enemy's field of view centre
       
        // calculate the angle formed between the player's position and the centre of the enemy's line of sight
        float angle = Vector2.Angle(directionToPlayer, lineOfSight);
       
        // if the player is within 65 degrees (either direction) of the enemy's centre of vision (i.e. within a 130 degree cone whose centre is directly ahead of the enemy) return true
        if (angle < 65)
            return true;
        else
            return false;
    }

    bool PlayerHiddenByObstacles()
    {

        float distanceToPlayer = Vector2.Distance(transform.position, player.position);
        RaycastHit2D[] hits = Physics2D.RaycastAll(transform.position, player.position - transform.position, distanceToPlayer);
        Debug.DrawRay(transform.position, player.position - transform.position, Color.blue); // draw line in the Scene window to show where the raycast is looking
        List<float> distances = new List<float>();
    
        foreach (RaycastHit2D hit in hits)
        {          
            // ignore the enemy's own colliders (and other enemies)
            if (hit.transform.tag == "Enemy")
                continue;
           
            // if anything other than the player is hit then it must be between the player and the enemy's eyes (since the player can only see as far as the player)
            if (hit.transform.tag != "Player")
            {
                return true;
            }
        }

        // if no objects were closer to the enemy than the player return false (player is not hidden by an object)
        return false;

    }

}

So working with your first block of code…

First it checks if playerInRange… if it is true, then it will execute lines 6-9… if playerInRange is false, it would execute line 15 instead.

So if it’s true…, it then checks PlayerInFIeldOfView… if THAT returns true… it will return tothe calling function, the value that is the OPPOSITE of what is returned by PlayerHiddenByObstacles() (that’s what !PlayerHiddenByObstacles() means… ex. if PlayerHiddenByObstacles() evaluates to true… return false).

I don’t know if any of that code makes sense, I only took a quick look… but that’s the gist of it.

The “!” operator means NOT, which you can kind of think of as opposite of. That’s an oversimplification though. I’d suggest reading up on various operators, as well as conditions. This isn’t a “Unity thing”, but a “fundamental coding thing”

1 Like

Thank you so much! That is the explanation I was looking for. First time I have encountered this (in my limited coding experience), and I couldn’t wrap my head around that line, but I believe I get it now! <3

No problem! Conditionals (IF/ELSE, etc.), loops (for, while, foreach, do/while, etc.), and logical operators (AND/&&, OR/||, NOT/!, etc.) are the fundamentals of any programming language. You’ll definitely want to have a good understanding of these before you get too involved in programming. A lack of knowledge on these can cause you to write some pretty bad, confusing, and/or over-complicated code.

Best of luck with your game programming!