Единство 2D.Другой тип врагов == другой тип урона для них? - PullRequest
0 голосов
/ 15 октября 2018

Я делаю 2D платформер и мне нужна помощь.Я не использую какие-либо фреймворки для Unity, чтобы сделать свою игру. Я хочу получить представление о простых опциях Unity.

To Essence.Я сделал врага, который оглушает моего игрока, он бросается на меня и наносит урон (ну, пока у меня нет системы здоровья игрока).Но я также сделал врага-скелтона, у которого есть анимация, и он атакует мечом.

Я хочу сделать этот скелет, чтобы получить урон от моего игрока.Я сделал для него то же самое, что и previus для этих стремительных врагов, но я получил исключение NullRefrenceException ... которое отправляет меня в сценарий "Врежущий враг", а не в сценарий скелета.Должен сказать, я очень смущен этим.

Ниже я вставлю исключение и скрипты.

NullReferenceException: Object reference not set to an instance of an object DamageDeal.DealDmg () (at Assets/Scripts/DamageDeal.cs:37) CombatBehavior.FixedUpdate () (at Assets/Scripts/CombatBehavior.cs:92)

Скрипт Rushing Enemy:

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

public class EnemyScript : MonoBehaviour {

    public float speed;
    public float distance;

    public int health;

    public bool movingRight = true;

    public Transform groundDetection;
    public Transform wallDetection;

    public bool otherEnemy;
    public bool trap;

    public LayerMask EnemyLayer;
    public LayerMask TrapLayer;
    public LayerMask WallLayer;

    public Transform ColideDetector;
    public float detectorRadius;

    public BoxCollider2D CheckHeadBounce;

    // Use this for initialization
    void Start ()
    {
       //float distanceY = groundDetection.position.y + distance;
    }

    // Update is called once per frame
    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  || 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;
            }
        }
    }

    void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.green;
        Gizmos.DrawLine(new Vector3(groundDetection.position.x, groundDetection.position.y), new Vector3(groundDetection.position.x, groundDetection.position.y + (-distance)));

        if (movingRight == true)
        {
            Gizmos.DrawLine(new Vector3(wallDetection.position.x, wallDetection.position.y), new Vector3(wallDetection.position.x + distance, wallDetection.position.y));

        }else if (movingRight == false)
        {
            Gizmos.DrawLine(new Vector3(wallDetection.position.x, wallDetection.position.y), new Vector3(wallDetection.position.x - distance, wallDetection.position.y));
        }
    }

    public void HeadBounce()
    {

    }

    public void TakeDmg(int damage)
    {
        health -= damage;

        Debug.Log("damage TAKEN!");
    }
}

Скрипт для нанесения урона атакующему врагу:

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

public class DamageDeal : MonoBehaviour {

    public Transform attackPos;
    public float attackRange;
    public LayerMask whatIsEnemy;
    public int damage;

    void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(attackPos.position, attackRange);
    }

    public void ChooseOne() // this script was desperation move.
    {
        if (gameObject.tag == "Enemy")
        {
            Debug.Log("Rushing Enemy DMG");
            DealDmg();
        }
    }

    public void DealDmg()
    {
        if (attackPos.gameObject.activeSelf == true)
        {
            Collider2D[] enemiesToDamage = Physics2D.OverlapCircleAll(attackPos.position, attackRange, whatIsEnemy);
            for (int i = 0; i < enemiesToDamage.Length; i++)

            {
                EnemyScript enemyScript = enemiesToDamage[i].GetComponent<EnemyScript>();

                enemyScript.TakeDmg(damage);

                if (gameObject.GetComponent<PlayerControls>().facingRight == true)
                {
                    enemyScript.GetComponent<Rigidbody2D>().AddForce(new Vector2(15f, 15f), ForceMode2D.Impulse);
                }
                else if (gameObject.GetComponent<PlayerControls>().facingRight == false)
                {
                    enemyScript.GetComponent<Rigidbody2D>().AddForce(new Vector2(-15f, 15f), ForceMode2D.Impulse);
                }
                attackPos.gameObject.SetActive(false);
            }
        }
    }
}

Скелетный скрипт:

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

public class SkeletonScript : MonoBehaviour {

    public float speed;
    public float distance;

    public int health;

    private Rigidbody2D skeletonRB;

    public bool movingRight = true;

    public Transform groundDetection;
    public Transform wallDetection;

    public bool otherEnemy;
    public bool trap;

    public LayerMask EnemyLayer;
    public LayerMask TrapLayer;
    public LayerMask WallLayer;

    public Transform ColideDetector;
    public float detectorRadius;

    public PlayerControls player;

    public Animator skeletonAnim;

    // Use this for initialization
    void Start ()
    {
        skeletonRB = GetComponent<Rigidbody2D>();
        player = FindObjectOfType<PlayerControls>();
    }

    // Update is called once per frame
    void Update ()
    {
        MoveSkeleton();
        SkeletonDeath();
    }

    void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.green;
        Gizmos.DrawLine(new Vector3(groundDetection.position.x, groundDetection.position.y), new Vector3(groundDetection.position.x, groundDetection.position.y + (-distance)));

        if (movingRight == true)
        {
            Gizmos.DrawLine(new Vector3(wallDetection.position.x, wallDetection.position.y), new Vector3(wallDetection.position.x + distance, wallDetection.position.y));

        }
        else if (movingRight == false)
        {
            Gizmos.DrawLine(new Vector3(wallDetection.position.x, wallDetection.position.y), new Vector3(wallDetection.position.x - distance, wallDetection.position.y));
        }
    }

    public void MoveSkeleton()
    {
        skeletonRB.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 || 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;
            }
        }
    }

    public void TakeDmgSkeleton(int damageToSkeleton)
    {
        health -= damageToSkeleton;

        Debug.Log("damage TAKEN!");
    }

    public void SkeletonDeath()
    {
        if (health <= 0)
        {
            skeletonAnim.Play("Skeleton_Dead", 0);
        }
    }
}

Повреждение скелета Скрипт:

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

public class DamageDealToSkeleton : MonoBehaviour {

    public Transform attackPos1;
    public float attackRange;
    public LayerMask whatIsEnemy;
    public int damageToSkeleton;

    void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(attackPos1.position, attackRange);
    }

    public void ChooseOne()// this script was desperation move.
    {
        if (gameObject.tag == "Skeleton")
        {
            Debug.Log("Skeleton DMG");
            DealDmgToSkeleton();
        }
    }


    public void DealDmgToSkeleton()
    {
        if (attackPos1.gameObject.activeSelf == true)
        {
            Collider2D[] skeletonToDamage = Physics2D.OverlapCircleAll(attackPos1.position, attackRange, whatIsEnemy);
            for (int i = 0; i < skeletonToDamage.Length; i++)
            {
                SkeletonScript skeletonScript = skeletonToDamage[i].GetComponent<SkeletonScript>();

                skeletonScript.TakeDmgSkeleton(damageToSkeleton);

                if (gameObject.GetComponent<PlayerControls>().facingRight == true)
                {
                    skeletonScript.GetComponent<Rigidbody2D>().AddForce(new Vector2(15f, 15f), ForceMode2D.Impulse);
                }
                else if (gameObject.GetComponent<PlayerControls>().facingRight == false)
                {
                    skeletonScript.GetComponent<Rigidbody2D>().AddForce(new Vector2(-15f, 15f), ForceMode2D.Impulse);
                }
                attackPos1.gameObject.SetActive(false);
            }
        }
    }
}

1 Ответ

0 голосов
/ 15 октября 2018

Я думаю, что предположение о том, что все Collider2D, возвращенные из Physics2D.OverlapCircleAll, будут иметь прикрепленный SkeletonScript, ошибочно.

Collider2D[] skeletonToDamage = Physics2D.OverlapCircleAll(attackPos1.position,attackRange, whatIsEnemy);
        for (int i = 0; i < skeletonToDamage.Length; i++)
        {
            SkeletonScript skeletonScript = skeletonToDamage[i].GetComponent<SkeletonScript>();

Было бы лучше получить родительский GameObject, к которому прикреплен компонент Collider2D, прежде чем определять, имеет ли к этому GameObject компонент SkeletonScript.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...