Я делаю 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);
}
}
}
}