Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailemVyřešeno Unity 3D a C#

Hraju si s unity 3D, mám jednoduchou plošinovku s charakterem, šipkama se běhá, skáče, mezerníkem seká do nepřátel. Vtip je v tom, že to funguje, ovšem jen někdy :D

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

public class PlayerAttack : MonoBehaviour {

    private float timeBtwAttack;
    public float startTimeBtwAttack;

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

    private Shake shake;

    public GameObject bloodEffect;

    void Start (){
        shake = GameObject.FindGameObjectWithTag("ScreenShake").GetComponent<Shake>();
    }

    void Update(){

        if(timeBtwAttack <=0){
            // then you can attack
            if(Input.GetKey(KeyCode.Space)){
                Collider2D[] enemiesToDamage = Physics2D.OverlapCircleAll(attackPos.position, attackRange, whatIsEnemies);
                for (int i = 0; i < enemiesToDamage.Length; i++) {
                    enemiesToDamage[i].GetComponent<Enemy>().TakeDamage(damage);
                    /*shake cam a animace utoku*/ 
                    shake.CamShake();
                    Instantiate(bloodEffect, transform.position, Quaternion.identity);
                    Debug.Log("Cakance krve!!!!!!");                 
                }
            }
        if(Input.GetKey(KeyCode.Space)){
            timeBtwAttack = startTimeBtwAttack;        
        } else {
            timeBtwAttack -= Time.deltaTime;
        }
    }

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

a enemy je


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

public class Enemy : MonoBehaviour {    

    public int health;
    public float speed;
    private float dazedTime;
    public float startDazedTime;

    private Animator anim;
    /*public GameObject bloodEffect;*/

    void Start(){
        //anim = GetComponent<Animator>();
        //anim.SetBool("isRunning", true);
    }
    
    void Update(){

        if(dazedTime <= 0){
            speed = speed;
        } else {
            speed = 0;
            dazedTime -=Time.deltaTime;
        }

        if(health <= 0){
            Destroy(gameObject);
        }

        transform.Translate(Vector2.left * speed * Time.deltaTime);
    }

    public void TakeDamage(int damage){
        // play a hurt sound
       /* Instantiate(bloodEffect, transform.position, Quaternion.identity);*/ 
        health -= damage;
        Debug.Log("damage TAKEN");
    }
}

Jak říkám, v podstatě to nějak funguje, ale občas je nepříteli udělen dmg 1-6 jindy nula. Vůbec nechápu kde se bere ta náhodnost.
Dostávám chybovou hlášku :

NullReferenceException: Object reference not set to an instance of an object
PlayerAttack.Update () (at Assets/Scripts/PlayerAttack.cs:30)

což by mělo být konkrétně

  enemiesToDamage[i].GetComponent<Enemy>().TakeDamage(damage);

Ale netuším co je na tom špatně.

Rád bych poprosil o pomoc, věřím, že někomu kdo umí programovat to bude jasné, ale hraju si s tím teprve pár dní, tak prosím o shovívavost:)

Řešení:

Jen abych doplnil řešení, krom drobné chyby v kódu byl problém způsoben tím, že při přiřazování vrstvy "Enemy" hernímu objektu "Enemy" se mě to zeptalo zda chci přiřadit layer i všem objektům v hierarchii - tzn assetu a pod. Což jsem v dobré víře odsouhlasil a pochopitelně asset s vrstvou enemy neměl script "enemy", takže nebylo odkud odečítat životy a podobné operace...Proto to failovalo.

Předmět Autor Datum
V Unity nedělám, takže jenom hádám: enemiesToDamage nejspíš obsahuje i jiné objekty než jenom typu E…
Wikan 29.09.2019 19:29
Wikan
no, mě možná nedochází jak je to enemiesToDamage definováno. Myslel jsem že to definuje tohle Coll…
Redsnake 29.09.2019 19:34
Redsnake
Je možné, že pokud je tam více objektů, že vrátí výsledek random?
Redsnake 29.09.2019 19:36
Redsnake
Jak jsem psal. V Unity nedělám, takže netuším.
Wikan 29.09.2019 19:44
Wikan
Jen abych doplnil řešení, krom drobné chyby v kódu byl problém způsoben tím, že při přiřazování vrst…
Redsnake 30.09.2019 14:50
Redsnake
Takže jsem to vlastně tipnul správně. Bralo ti to "neEnemy" objekty :-)
Wikan 30.09.2019 14:52
Wikan
Přesně tak, bralo to objekty s layerem enemy bez fcí enemy. Takže fail. nechápu jak se dle mého ubo… poslední
Redsnake 30.09.2019 14:54
Redsnake

no, mě možná nedochází jak je to enemiesToDamage definováno. Myslel jsem že to definuje tohle

 Collider2D[] enemiesToDamage = Physics2D.OverlapCircleAll(attackPos.position, attackRange, whatIsEnemies);

Kdy whatIsEnemies je vlastně

public LayerMask whatIsEnemies;

Ale možná plácám hlouposti, fakt moc netuším:)

Jen abych doplnil řešení, krom drobné chyby v kódu byl problém způsoben tím, že při přiřazování vrstvy "Enemy" hernímu objektu "Enemy" se mě to zeptalo zda chci přiřadit layer i všem objektům v hierarchii - tzn assetu a pod. Což jsem v dobré víře odsouhlasil a pochopitelně asset s vrstvou enemy neměl script "enemy", takže nebylo odkud odečítat životy a podobné operace...Proto to failovalo.

Zpět do poradny Odpovědět na původní otázku Nahoru