Страница 1 из 2

Проблема со считыванием урона двумя объектами друг у друга

СообщениеДобавлено: 07 апр 2021, 22:23
Aderom
Здравствуйте, столкнулся с проблемой, что выстрел лазера сносит все объекты на пути. Обмен уроном выглядит так:
Синтаксис:
Используется csharp
Take_damage(other.GetComponent<ClassBody>().Damage());
 

В обоих скриптах.
По моим наблюдениям, а так же NullReferenceException, предполагаю, что один объект успевает считать урон быстрее и умирает, а второй не может считать урон т.к. первый уже удален со сцены.
С этим возникает вопрос, как гарантировать считывание параметра урона обоими объектами, после чего произвести уничтожение оных при достаточном количестве полученного урона
Условие на смерть: Hp() <= 0
Скину любой участок кода который понадобится в разборе, просто не вижу причины захломлять это сообщение непонятно чем.

P.s Не знаю что произошло, но внезапно эта проблема осталась только с определенным видом противника. У которого код обработки урона одинаковый с другими противниками о_О. Что происходит :((

Re: Проблема со считыванием урона двумя объектами друг у друга

СообщениеДобавлено: 07 апр 2021, 22:54
1max1
Проблема в чем? В NullReferenceException? К слову, кидай участок кода, где эта ошибка появляется.

Re: Проблема со считыванием урона двумя объектами друг у друга

СообщениеДобавлено: 07 апр 2021, 23:06
Aderom
1max1 писал(а):Проблема в чем? В NullReferenceException? К слову, кидай участок кода, где эта ошибка появляется.

Я же прозрачно написал. NullReference появляется при считывании этой строчки
Синтаксис:
Используется csharp
Take_damage(other.GetComponent<ClassBody>().Damage());


https://skr.sh/s7SXueWFzVl

При столкновении 1 и 2
1 не может прочитать сколько урона получит от 2, т.к. 2 уже прочитал от 1 и этого хватило, чтобы умереть 2-му, следовательно при считывании получается 0, ведь gameObject 2-го не существует.
И 1 летит дальше сталкивается с другими, так же их минусует пока не вылетит за границу карты или не умрет от другого типа объекта с идентичным кодом на считывание урона (prefab другой)

Выстрел:
Синтаксис:
Используется csharp
private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Player") || other.CompareTag("Border") || other.CompareTag("PlayerShoot"))
            return;
        Take_damage(other.GetComponent<ClassBody>().Damage());
    }

Противник:
Синтаксис:
Используется csharp
 private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Enemy") || other.CompareTag("Border") || other.CompareTag("EnemyShoot"))
            return;
        Take_damage(other.GetComponent<ClassBody>().Damage());
    }

Re: Проблема со считыванием урона двумя объектами друг у друга

СообщениеДобавлено: 07 апр 2021, 23:07
Alkos26Rus
Aderom писал(а):просто не вижу причины захломлять это сообщение непонятно чем.

Ну ты молодец, а причин захламлять пост просьбами скинуть скрипт не видишь? Кидай код, мы же не экстрасенсы, да и какую часть кода кинуть ты должен сам знать, это же твой код.

Re: Проблема со считыванием урона двумя объектами друг у друга

СообщениеДобавлено: 07 апр 2021, 23:20
Aderom
Alkos26Rus писал(а):
Aderom писал(а):просто не вижу причины захломлять это сообщение непонятно чем.

Ну ты молодец, а причин захламлять пост просьбами скинуть скрипт не видишь? Кидай код, мы же не экстрасенсы, да и какую часть кода кинуть ты должен сам знать, это же твой код.

Я скинул все что посчитал нужным, человек попросил пояснить, я ничего нового сюда не прислал, задача уже поставлена, второе мое сообщение лишь уточнение.

Re: Проблема со считыванием урона двумя объектами друг у друга

СообщениеДобавлено: 07 апр 2021, 23:22
Alkos26Rus
Aderom писал(а):
Alkos26Rus писал(а):
Aderom писал(а):просто не вижу причины захломлять это сообщение непонятно чем.

Ну ты молодец, а причин захламлять пост просьбами скинуть скрипт не видишь? Кидай код, мы же не экстрасенсы, да и какую часть кода кинуть ты должен сам знать, это же твой код.

Я скинул все что посчитал нужным, человек попросил пояснить, я ничего нового сюда не прислал, задача уже поставлена, второе мое сообщение лишь уточнение.

Скинь еще методы Take_damage и Damage;

Re: Проблема со считыванием урона двумя объектами друг у друга

СообщениеДобавлено: 07 апр 2021, 23:24
Aderom
Синтаксис:
Используется csharp
public class ClassBody : MonoBehaviour
{
    private float hp;
    private float damage;
    public float Hp() { return hp; }
    public float Damage() { return damage; }
    public void Hp(float value) { hp = value; }
    public void Damage(float value) { damage = value; }
    public float Take_damage(float value) { hp -= value; return hp; }

Re: Проблема со считыванием урона двумя объектами друг у друга

СообщениеДобавлено: 07 апр 2021, 23:27
Alkos26Rus
Так а где у тебя происходит удаление объекта после того как жизнь кончилась?

Re: Проблема со считыванием урона двумя объектами друг у друга

СообщениеДобавлено: 07 апр 2021, 23:35
Aderom
Alkos26Rus писал(а):Так а где у тебя происходит удаление объекта после того как жизнь кончилась?

:)
Синтаксис:
Используется csharp
if (Hp() <= 0)
        {
            Destroy(gameObject);
        }

Re: Проблема со считыванием урона двумя объектами друг у друга

СообщениеДобавлено: 07 апр 2021, 23:37
Alkos26Rus
И еще вопрос, ты точно дал полный код в OnTriggerEnter? Или решил дать только часть кода. Потому что непонятно как у тебя выдает такую ошибку, как будто other перестало существовать посреди метода OnTriggerEnter. Удаление происходит на следующем кадре, поэтому если OnTriggerEnter сработало то other ни куда не денется и можно запрашивать урон, удаление произойдет на следующий кадр. Вобщем либо ты что то недоговариваешь либо хз, это вобще единственная ошибка которая выходит?

Re: Проблема со считыванием урона двумя объектами друг у друга

СообщениеДобавлено: 07 апр 2021, 23:47
Aderom
Alkos26Rus писал(а):И еще вопрос, ты точно дал полный код в OnTriggerEnter? Или решил дать только часть кода. Потому что непонятно как у тебя выдает такую ошибку, как будто other перестало существовать посреди метода OnTriggerEnter. Удаление происходит на следующем кадре, поэтому если OnTriggerEnter сработало то other ни куда не денется и можно запрашивать урон, удаление произойдет на следующий кадр. Вобщем либо ты что то недоговариваешь либо хз, это вобще единственная ошибка которая выходит?

Нет, я скинул все полностью. В этом и волшебство, что проблема только с одним префабом. Ладно, закидаю тебя всяким хламом, может поможет разобраться.
Синтаксис:
Используется csharp
 using System.Collections;
using System.Collections.Generic;
using UnityEngine;

Проблемный противник:
public class XEnemyScript : ClassBody
{
    public GameObject LazerShoot;
    public Transform LazerGun;
    public Transform LazerGun_2;
    public Transform <img src="./images/smilies/unmarked.gif" alt="[]" title="Запланировано" />Destination;
    public float shootDelay;
    public float tilt;
    public float Zmax, Zmin, Xmax, Xmin;
    public float hp_value;
    public float damage_value;
    float nextShootTime;
    int NumDestination = 0;
   

    void Start()
    {
        Hp(hp_value);
        Damage(damage_value);
        nextShootTime = Time.time + 0.5f;
        NumDestination = GameObject.Find("EnemySpawner").GetComponent<EnemySpawnerScript>().countDestination -1;
        NumDestination %= 15;
        if (Destination[NumDestination].position.x > 0)
            Xmax = Destination[NumDestination].position.x;
        else
            Xmin = Destination[NumDestination].position.x;
        Zmin = Destination[NumDestination].position.z;

    }
    void Update()
    {
        if (NumDestination < 5)
            transform.Translate(Destination[NumDestination].position.x * Time.deltaTime * 2, 0, Destination[NumDestination].position.z * Time.deltaTime * 2);
        if (NumDestination < 10)
            transform.Translate(Destination[NumDestination].position.x * Time.deltaTime * 10, 0, Destination[NumDestination].position.z * Time.deltaTime * 2);
        if (NumDestination < 15)
            transform.Translate(Destination[NumDestination].position.x * Time.deltaTime * 50, 0, Destination[NumDestination].position.z * Time.deltaTime * 2);

        float Xclamep = Mathf.Clamp(transform.position.x, Xmin, Xmax);
        float Zclamep = Mathf.Clamp(transform.position.z, Zmin, Zmax);
        transform.position = new Vector3(Xclamep, 0, Zclamep);

        if (Time.time > nextShootTime)
        {
            Instantiate(LazerShoot, LazerGun.position, Quaternion.identity);
            Instantiate(LazerShoot, LazerGun_2.position, Quaternion.identity);
            nextShootTime = Time.time + shootDelay;
        }
        if (Hp() <= 0) {
            Destroy(gameObject);
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Enemy") || other.CompareTag("Border") || other.CompareTag("EnemyShoot"))
            return;
        Take_damage(other.GetComponent<ClassBody>().Damage());
    }


Правильно дохнущий противник:
Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ZEnemyScript : ClassBody
{
    Rigidbody ship;
    public GameObject LazerShoot;
    public Transform LazerGun;
    public Transform LazerGun_2;
    public float shootDelay;
    public float speed;
    public float tilt;
    public float Zmax, Zmin, Xmax, Xmin;
    public float hp_value;
    public float damage_value;
    float nextShootTime;
   

    void Start()
    {
        Hp(hp_value);
        Damage(damage_value);
        nextShootTime = Time.time + 0.5f;
        ship = GetComponent<Rigidbody>();
    }
    void Update()
    {
        float moveVertical = Random.Range(speed / 1.5f, speed);

        ship.velocity = new Vector3(0, 0, -moveVertical);

        float Xclamep = Mathf.Clamp(ship.position.x, Xmin, Xmax);
        float Zclamep = Mathf.Clamp(ship.position.z, Zmin, Zmax);

        ship.position = new Vector3(Xclamep, 0, Zclamep);

        if (Time.time > nextShootTime) {
            Instantiate(LazerShoot, LazerGun.position, Quaternion.identity);
            Instantiate(LazerShoot, LazerGun_2.position, Quaternion.identity);
            nextShootTime = Time.time + shootDelay;
        }
        if (Hp() <= 0)
        {
            Destroy(gameObject);
        }
    }

        private void OnTriggerEnter(Collider other)
        {
            if (other.CompareTag("Enemy") || other.CompareTag("Border") || other.CompareTag("EnemyShoot"))
                return;
            Take_damage(other.GetComponent<ClassBody>().Damage());
        }
}


Выстрел:
Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerLazerScript : ClassBody
{
    public float speed;
    public float damage_value;
    public float hp_value;

    void Start()
    {
        Hp(hp_value);
        Damage(damage_value);
        GetComponent<Rigidbody>().velocity = new Vector3(0, 0, speed);
    }
    private void Update()
    {
        if (Hp() <= 0)
        {
            Destroy(gameObject);
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Player") || other.CompareTag("Border") || other.CompareTag("PlayerShoot"))
            return;
        Take_damage(other.GetComponent<ClassBody>().Damage());
    }
}
 


и вид префаба (не знаю зачем)
Не работающий:
https://skr.sh/s7Scak5puh6
Работающий:
https://skr.sh/s7SvWEdbLN9
Ошибка:
https://skr.sh/s7SGgpKz1Y1

Отличие в месте где храниться в файловом древе коллайдер, мне кажется, это вообще влиять не должно.

Re: Проблема со считыванием урона двумя объектами друг у друга

СообщениеДобавлено: 07 апр 2021, 23:53
Saltant
При дестрое геймобжекта в апдейте, OnTriggerEnter может ваще не сработать как я понимаю.

Re: Проблема со считыванием урона двумя объектами друг у друга

СообщениеДобавлено: 07 апр 2021, 23:54
Aderom
Saltant писал(а):При дестрое геймобжекта в апдейте, онКолижен может ваще не сработать как я понимаю.

А как дестрой произойдет без активации снижения здоровья в онКолижен?

Re: Проблема со считыванием урона двумя объектами друг у друга

СообщениеДобавлено: 07 апр 2021, 23:55
Saltant
Aderom писал(а):
Saltant писал(а):При дестрое геймобжекта в апдейте, онКолижен может ваще не сработать как я понимаю.

А как дестрой произойдет без активации снижения здоровья в онКолижен?

Потому что это в 1 методе делается. Например в OnTriggerEnter снижаешь хп и сразу же если hp <= 0 то дестроишь.

Re: Проблема со считыванием урона двумя объектами друг у друга

СообщениеДобавлено: 07 апр 2021, 23:58
Alkos26Rus
Почему у тебя нет коллайдера у противника на котором висит скрипт XEnemyScript? Как по твоему должен сработать OnTriggerEnter. Ты же дамажишь только самого себя во всех твоих скриптах, так как же должен удалится проблемный противник на котором висит скрипт XEnemyScript?