简体   繁体   English

Unity 2D Platformer-使我的敌人看不到墙

[英]Unity 2D Platformer - making my enemy not see through walls

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. 我已经做了一个简单的Game Object(矩形)来指出它的视线,它可以正常工作,但是我想对其进行一些改进。

To make it quckier... i just want to make my enemies attack me but to not seen me througth walls 为了使它更加怪异……我只想让敌人攻击我,却不让我穿过墙壁

Some code: 一些代码:

[DamageFromEnemy.cs] [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] [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 一些Gif反馈

At last gifs frames you can see that it bugs sometimes. 在最后的gif帧中,您可以看到它有时会出错。

    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
    }
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. 编辑:这是我按照评论中@ Draco18s的想法整理的代码,如果对您有用,请告诉他谢谢您。 i just thought it made enough sense he should have put it as an answer 我只是认为这很有意义,他应该把它当作答案

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM