Unity 2D。不同类型的敌人==对他们的不同类型的伤害?

时间:2018-10-15 16:06:55

标签: c# unity3d

我正在制作2D平台游戏,需要帮助。我没有使用Unity的任何框架来制作游戏,所以我想了解Unity的简单选项。

精华。我制造了一个使我的玩家昏迷的敌人,它冲向我并造成dmg(当然我还没有玩家健康系统)。但是我也使斯凯尔顿成为了一个敌人,这个敌人具有动画效果并且正在用剑攻击。

我想制造骷髅来从玩家身上获得伤害。我为他所做的与为冲动的敌人所做的事完全相同,但是我得到了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)

抢敌脚本:

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 :(得分:0)

我认为从Physics2D.OverlapCircleAll返回的所有Collider2D都将附加SkeletonScript的假设是错误的。

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

在确定GameObject是否附加了“ SkeletonScript”组件之前,最好先获取Collider2D组件所附加的父GameObject。