0

basicly i'm searching for an idea. How to make my Enemy patroling, but when it reaches the Player - it rush and deal damage, but in the same time when it reach the wall and player is standing behind the wall it Don't attack. You know - i don't want to let them see through walls.

I have made simple Game Object (rectangle) to point it's sight, it is working correctly but i want to improve some of it.

To make it quckier... i just want to make my enemies attack me but to not seen me througth walls

Some code:

[DamageFromEnemy.cs]

private void FixedUpdate()
{
    isThatPlayer = Physics2D.OverlapBox(PlayerDetector.position, new Vector2(playerDetectX, playerDetectY), 0, PlayerLayer);

    isThatWall = Physics2D.OverlapBox(PlayerDetector.position, new Vector2(playerDetectX, playerDetectY), 0, gameObject.GetComponent<EnemyScript>().WallLayer);

    if (isThatWall == true && gameObject.GetComponent<EnemyScript>().movingRight == true)
    {
        PlayerDetector.transform.Translate(new Vector3(changePosX, 0, 0));

        //playerDetectX -= PlayerDetector.transform.position.x; // Lowering size. Not Working

        changePosX = (playerDetectX / 2) * (1 / enemyScaleX) + (enemyScaleX / 2) * (1 / enemyScaleX);

        Debug.Log("pozycja x: " + changePosX);
    }

    if (isThatWall == true && gameObject.GetComponent<EnemyScript>().movingRight == false)
    {
        PlayerDetector.transform.Translate(new Vector3(- changePosX, 0, 0));

        //playerDetectX -= PlayerDetector.transform.position.x; // Lowering size. Not Working

        changePosX = (playerDetectX / 2) * (1 / enemyScaleX) + (enemyScaleX / 2) * (1 / enemyScaleX);

        Debug.Log("pozycja x: " + changePosX);
    }

    DetectPlayer();

    AttackTimer();
}
void OnDrawGizmosSelected()
{
    Gizmos.color = Color.blue;
    Gizmos.DrawWireCube(PlayerDetector.position, new Vector3(playerDetectX, playerDetectY));
}

[EnemyScript.cs]

void Update ()
{
    trap = Physics2D.OverlapCircle(ColideDetector.position, detectorRadius, TrapLayer);
    otherEnemy = Physics2D.OverlapCircle(ColideDetector.position, detectorRadius, EnemyLayer);

    if (health <= 0)
    {
        Destroy(gameObject);
    }

    transform.Translate(Vector2.right * speed * Time.deltaTime );

    RaycastHit2D groundInfo = Physics2D.Raycast(groundDetection.position, Vector2.down, distance);

    RaycastHit2D wallInfoR = Physics2D.Raycast(wallDetection.position, Vector2.right, distance, WallLayer);

    RaycastHit2D wallInfoL = Physics2D.Raycast(wallDetection.position, Vector2.left, -distance, WallLayer);


    if (groundInfo.collider == false || trap == true || otherEnemy == true || wallInfoR == true || wallInfoL == true)
    {
        if(movingRight == true)
        {
            transform.eulerAngles = new Vector3(0, -180, 0);
            movingRight = false; 
        }
        else
        {
            transform.eulerAngles = new Vector3(0, 0, 0);
            movingRight = true;
        }
    }
}

Some Gif Feedback

At last gifs frames you can see that it bugs sometimes.

    public PlayerControls player;
public LayerMask WallLayer;

player = FindObjectOfType<PlayerControls>();
        RaycastHit2D checkWallsToHero = Physics2D.Raycast(wallToHeroRay.position, player.transform.position, 150,WallLayer);

    if (checkWallsToHero == true)
    {
        playerCheck = false;
    }

    void OnDrawGizmosSelected()
{
    Gizmos.color = Color.blue;
    Gizmos.DrawWireCube(PlayerDetector.position, new Vector3(playerDetectX, playerDetectY));
    Gizmos.DrawLine(wallToHeroRay.position, player.transform.position);
}

[New Code sample - propably wrong]:

isThatPlayer = Physics2D.OverlapBox(PlayerDetector.position, new Vector2(playerDetectX, playerDetectY), 0, PlayerLayer);

    isThatWall = Physics2D.OverlapBox(PlayerDetector.position, new Vector2(playerDetectX, playerDetectY), 0, gameObject.GetComponent<EnemyScript>().WallLayer);


    RaycastHit2D checkWallsToHero = Physics2D.Raycast(wallToHeroRay.position, player.transform.position, 0, gameObject.GetComponent<EnemyScript>().WallLayer);

    if (checkWallsToHero.collider != true /*&& isThatPlayer == true*/)
    {
        Debug.Log("Pierwszy state");
        Debug.Log(checkWallsToHero.collider);

        //Debug.Log(isThatPlayer);
        //Debug.Log("Hit: " + checkWallsToHero.collider.gameObject.name);

        playerCheck = false;
        enemyAttackReady = false;
        coolDownTimer = 0;

        enemyAttackCD = 0;
    }
    else if (checkWallsToHero.collider == true && isThatPlayer == true)
    {
        Debug.Log(checkWallsToHero.collider);
        Debug.Log("Drugi state");
        ReadyToAttack(); //charging enemy
        DetectPlayer(); //bool to true when OverlapBox hits player

        AttackTimer(); //cd between enemy attacks
    }
K_Leszczynski
  • 15
  • 1
  • 8
  • 3
    ...raycast from the enemy to the player and see if you *hit the player* instead of a wall? – Draco18s no longer trusts SE Oct 12 '18 at 14:36
  • Okey, thanks for replay i'll try that idea – K_Leszczynski Oct 12 '18 at 15:01
  • I edited my orginal question, could someone check it out? It didn't seem to work well – K_Leszczynski Oct 12 '18 at 15:41
  • Also i'm getting error like this in Unity: NullReferenceException: Object reference not set to an instance of an object DamageFromEnemy.OnDrawGizmosSelected () (at Assets/Scripts/Enemy/DamageFromEnemy.cs:102) UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr) it sends me to: void OnDrawGizmosSelected()... – K_Leszczynski Oct 12 '18 at 15:53
  • @Draco18s that was very good idea works very well. Thank You. I have got questions to that NullReferenceException... if any one know what can i do about it pleas tell (other than comment whole line - because commenting solves the problem) – K_Leszczynski Oct 12 '18 at 16:12
  • Something is null. Use your tools to figure out what and why. That exception, when asked as a question, gets closed as a duplicate of [this question](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – Draco18s no longer trusts SE Oct 12 '18 at 16:13
  • Besides as i thought... something is not right. Think i am doing something wrong... could someone help (code in main message) – K_Leszczynski Oct 12 '18 at 19:02
  • `checkWallsToHero.collider != true` makes no sense. I think you wanted `null` here, not `true` (and to switch `==` and `!=`). You're also not comparing the `checkWallsToHero.collider` value to see if that value *is the player.* – Draco18s no longer trusts SE Oct 12 '18 at 19:54
  • Okey, i changed that `null`s also switched between symbols, but could you pleas tell me how to correctly compare `checkWallsToHero.collider` to values? – K_Leszczynski Oct 12 '18 at 20:15

1 Answers1

1
if (Physics2D.Raycast2D
(wallToHeroRay.position,player.transform.position,out hit,10)
 &&hit.transform.gameObject.tag == "Player") 
     {                       
         RayHit = true;  
     }
else {             
         RayHit = false;
     }

to use this you will have to tag your player as 'Player' then your ray will only give you a hit if it hits the player itself, and not a wall

Edit: this is code i threw together following @Draco18s's idea in the comments, if it works for you, tell him thank you. i just thought it made enough sense he should have put it as an answer

Technivorous
  • 1,682
  • 2
  • 16
  • 22
  • Mostly right: you have a `RaycastHit` object (`hit`) used, but you never passed it to the raycast method as an `out` object. – Draco18s no longer trusts SE Oct 12 '18 at 20:50
  • as always you are the man. do you think i need to mention `RayHit` is itself a bool? lol. i figured it would be inferred, but sometimes i'm in too big of a hurry to answer. – Technivorous Oct 12 '18 at 21:00
  • I had to change it to something like: `if (Physics2D.Raycast(wallToHeroRay.position, player.transform.position, 10) && player.transform.gameObject.tag == "Player")`. There is no exisiting Raycast2D, and i changed `hit.` to `player.`. After creating bools for RayHit to test it, there is always true statement – K_Leszczynski Oct 12 '18 at 21:02
  • you have colliders on the walls right? lol. try reducing the 10, thats the range if im not mistaken. what is wall to hero ray? like where are you casting your ray from? it should be from the transform of the enemy itself, i.e enemy.position, that variable makes it seem like your casting it from the wall – Technivorous Oct 12 '18 at 21:08
  • @Vanethrane to make it more complex: https://pastebin.com/D321EduL https://giphy.com/gifs/fjxcnpCSpHQvDoqMoD >There are 2 links btw, and yes i have colliders, also reduced range. As you can see ray is coming from 'enemy' strictly to player. – K_Leszczynski Oct 12 '18 at 21:38
  • @K_Leszczynski Changing `hit.` to `player.` causes the code to simplify down to `if(raycast() && true)` which isn't helpful. You need to use the return value of the raycast (2D works differently than 3D; 3D returns a true/false with more detail in an `out RaycastHit` object, 2D just returns the `RaycastHit2D` object directly). – Draco18s no longer trusts SE Oct 12 '18 at 23:03
  • So i have to make NOT void function with RaycastHit2D. Call sth like`RaycastHit2D hit = new RaycastHit2D();` and then used code @Vanethrane's code? Sorry for that many questions, im basicly new to programming, i just don't get it... yet. – K_Leszczynski Oct 12 '18 at 23:26
  • If there is anyone who can help about it i would appreciate - its so annoying watching them trying to break throught wall while they cant – K_Leszczynski Oct 13 '18 at 09:38