我正在制作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);
}
}
}
}
答案 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。