Определение коллизий: ЧЯДНТ?

Общие вопросы о Unity3D

Определение коллизий: ЧЯДНТ?

Сообщение KetB 04 дек 2018, 22:23

Здравствуйте!

История такая -- понастроил я тут боксколлайдеров (го), всем поставил галку на IsTrigger, повесил на них скрипт-обработчик (StepBCDHandler) выделением всех ГО и перетаскиванием на них скрипта (может быть, важно), а потом создал пустышку с навешенным на неё скриптом-подписчиком (MainIntelligenceDirectorate, почему так странно — потому что все боксколлайдеры помечены тегом spy, Скрипали ж), вроде как всё замечательно работает, ошыбок не выдает, всякую нумерологию в виде таблиц из мануала по коллайдерам изучил, проверил, а всё равно — Орден "Ноль", ничего не выдает, лист на единицы не увеличивается.

Грешу на код, но вопрос остается -- ЧЯДНТ?

Код шпиона:

Синтаксис:
Используется csharp
using System;
using UnityEngine;
using System.Collections.Generic;
public class StepBCDHandler : MonoBehaviour
{
    #region Events
    /// <summary>
    /// Вызывается, когда срабатывает OnTriggerEnter
    /// </summary>
    public EventHandler<StepBCDHandlerArgs> TriggerEnter = delegate { };
    /// <summary>
    /// Вызывается, когда срабатывает OnTriggerExit
    /// </summary>
    #endregion

    private void OnTriggerEnter(Collider other)
    {
        TriggerEnter(this, new StepBCDHandlerArgs { Collider = other, Coordinates = transform.position });
    }

    public class StepBCDHandlerArgs : EventArgs
    {
        public Collider Collider { get; set; }
        public Vector3 Coordinates { get; set; }
    }
}
 


Код собирателя инфы со шпионов:

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

public class MainIntelligenceDirectorate : MonoBehaviour
{
    [SerializeField] private StepBCDHandler _handler;
    [SerializeField] GameObject[] _massiveBCD;

    void Awake()
    {
        _handler.TriggerEnter += OnHandlerTriggerEntered;
        foreach (var item in _massiveBCD)
 {
            _handler.TriggerEnter += OnHandlerTriggerEntered;
        }
    }


    private void OnHandlerTriggerEntered(object sender, EventArgs args)
    {
        var arg = (StepBCDHandlerArgs)args;
        var item = arg.Collider.transform.position;
    }

   public class StepBCDHandlerArgs : EventArgs
    {
        public Collider Collider { get; set; }
        public Vector3 Coordinates { get; set; }
    }
}


Сам БоксКоллайдер:

Скрытый текст:
Изображение


Тестовая сфера для определения работы скриптов (будет заменена на крипа с кинематикой)

Скрытый текст:
Изображение


Скриптхолдер с собирателем инфы с шпионов:

Скрытый текст:
Изображение


А вот как это искусство выглядит при игре, в скрипихолдере собирателя Size дает мне орден:

Скрытый текст:
Изображение


Для справки:

Вся эта затея затевается для того, чтобы поворачивать бошку мортиры к цели (чтобы снаряд летел по параболе).

Вместе с тем, чтобы не растекаться по темам, так как вопрос связанный, что лучше, пускать луч Рейкаста к крипам, или оставить такими вот плитками?
Последний раз редактировалось KetB 04 дек 2018, 23:08, всего редактировалось 1 раз.
KetB
UNец
 
Сообщения: 5
Зарегистрирован: 04 дек 2018, 21:51

Re: Определение коллизий: ЧЯДНТ?

Сообщение Anonymyx 04 дек 2018, 22:47

Не используйте спойлер для кода. Тогда может быть кто-то код прочтет. Просто тэга CS достаточно.
Аватара пользователя
Anonymyx
Адепт
 
Сообщения: 1934
Зарегистрирован: 05 апр 2015, 15:55

Re: Определение коллизий: ЧЯДНТ?

Сообщение KetB 04 дек 2018, 23:12

Anonymyx писал(а):Не используйте спойлер для кода. Тогда может быть кто-то код прочтет. Просто тэга CS достаточно.


Спасибо, конечно, но по существу вопроса писать тоже надо
KetB
UNец
 
Сообщения: 5
Зарегистрирован: 04 дек 2018, 21:51

Re: Определение коллизий: ЧЯДНТ?

Сообщение Anonymyx 05 дек 2018, 00:34

А как что-то писать по существу если код еле читаем?

Не сразу понял в чем прикол кода...
Синтаксис:
Используется csharp
    void Awake()
    {
        _handler.TriggerEnter += OnHandlerTriggerEntered;
        foreach (var item in _massiveBCD)
 {
            _handler.TriggerEnter += OnHandlerTriggerEntered;
        }
    }

особенно тут... А так, у вас метод не подписан на делегат. Непонятно откуда берется значение переменной _handler.
Аватара пользователя
Anonymyx
Адепт
 
Сообщения: 1934
Зарегистрирован: 05 апр 2015, 15:55

Re: Определение коллизий: ЧЯДНТ?

Сообщение KetB 05 дек 2018, 07:09

Anonymyx писал(а):А как что-то писать по существу если код еле читаем?

Не сразу понял в чем прикол кода...
Синтаксис:
Используется csharp
    void Awake()
    {
        _handler.TriggerEnter += OnHandlerTriggerEntered;
        foreach (var item in _massiveBCD)
 {
            _handler.TriggerEnter += OnHandlerTriggerEntered;
        }
    }

особенно тут... А так, у вас метод не подписан на делегат. Непонятно откуда берется значение переменной _handler.


Про этот момент тоже думаю,

Честно говоря, сам немного не понял, потому что всё это было забрано и переделано из другого кода, а там, как мне объяснили, нотация Microsoft

ЛевКонтроллер:

Синтаксис:
Используется csharp
using System.Collections.Generic;
using Ru.A.B.C;

namespace Ru.A.B.C
{
    using UnityEngine;

    /// <summary>
    /// Главный управляющий класс уровня
    /// </summary>
    public class LevelController : MonoBehaviour
    {
        [SerializeField] private LevelConstructor _levelConstructor;
        [SerializeField] private MarkerController _markerController;
        [SerializeField] private LevelInfoAsset   _levelInfo;
        [SerializeField] private Tower[]          _towers;
        private                  List<Tile>       _tiles;
        /// <summary>
        ///
        /// </summary>
        private readonly         List<Tower>      _anchoredTowers = new List<Tower>();

        private void Start()
        {
            // генерируем уровень на основе LevelInfo
            _tiles = _levelConstructor.Construct(_levelInfo);

            // подписываемся на евенты тайла
            foreach (var tile in _tiles)
            {
                tile.TriggerEnter += OnTileTriggerEnter;
                tile.TriggerExit  += OnTileTriggerExit;
            }

            // подписываемся на евенты башни
            foreach (var tower in _towers)
            {
                tower.OnHealthPointChanged += OnTowerHPChanged;
            }
        }

        private void OnTowerHPChanged(Tower tower, int hp) { }

        private void OnTileTriggerExit(object sender, Tile.TileEventArgs args)
        {
            // временное решение проблемы со срабатыванием коллизий при старте
            if (Time.realtimeSinceStartup < 10) return;
            Debug.Log(string.Format("{0} has trigger exited {1}", args.Tile.name, args.Collider.name));

            var tower = args.Collider.GetComponentInParent<Tower>();
            if (tower != null) // проверяем, что коллизия произошла с башней и устанавливаем ей цвет по молчанию
            {
                tower.SetDefaultColor();
            }
        }

        private void OnTileTriggerEnter(object sender, Tile.TileEventArgs args)
        {
            // временное решение проблемы со срабатыванием коллизий при старте
            if (Time.realtimeSinceStartup < 10) return;
            Debug.Log(string.Format("{0} has trigger enter {1}", args.Tile.name, args.Collider.name));

            var tower = args.Collider.GetComponentInParent<Tower>();
            if (tower != null) // проверяем, что коллизия произошла с башней, отвязываем от маркера и задаем цвет
            {
                var tile = args.Tile;
                if (tile.Type == Tile.TileType.Grass && !_anchoredTowers.Contains(tower))
                {
                    _markerController.SetContentAnchored(tower.gameObject, false);
                    tower.SetErrorColor();
                    tower.SetPosition(tile.Anchor.position);
                    tower.SetRotation(tile.Anchor.rotation);
                    _anchoredTowers.Add(tower);
                }
            }
        }
    }
}


ТригХэндлер

Синтаксис:
Используется csharp
 using System;

namespace Ru.A.B.C
{
    using UnityEngine;

    /// <summary>
    /// Компонент позволяюющий передать вверх по иерархии обработку коллизий
    ///
    /// Component allowing to pass the collisions up on the hierarchy
    /// </summary>
    public class TriggerHandler : MonoBehaviour
    {
        #region Events

        /// <summary>
        /// Вызывается, когда срабатывает OnTriggerEnter
        /// </summary>
        public EventHandler<TriggerHandlerArgs> TriggerEnter = delegate { };
        /// <summary>
        /// Вызывается, когда срабатывает OnTriggerExit
        /// </summary>
        public EventHandler<TriggerHandlerArgs> TriggerExit = delegate { };

        #endregion

        private void OnTriggerEnter(Collider other)
        {
            TriggerEnter(this, new TriggerHandlerArgs {Collider = other});
        }

        private void OnTriggerExit(Collider other)
        {
            TriggerExit(this, new TriggerHandlerArgs {Collider = other});
        }

        public class TriggerHandlerArgs : EventArgs
        {
            public Collider Collider { get; set; }
        }
    }
}


Конструктор:

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

namespace Ru.A.B.C
{
    using UnityEngine;

    /// <summary>
    /// TODO
    ///
    /// About Hex https://www.redblobgames.com/grids/hexa ... oordinates
    ///
    /// Algorithms - http://pcg.wikidot.com/category-pcg-algorithms
    /// </summary>
    public class LevelConstructor : MonoBehaviour
    {
        [SerializeField] private GameObject _riverPrefab;
        [SerializeField] private GameObject _grassPrefab;
        [SerializeField] private Transform  _battleFieldRoot;

        /// <summary>
        /// Конструируем уровень на основе LevelInfo и возвращаем лист тайлов
        /// </summary>
        /// <param name="asset"></param>
        /// <returns></returns>
        public List<Tile> Construct(LevelInfoAsset asset)
        {
            List<Tile> result = new List<Tile>();

            float globalXOffset = -asset.BattleFieldWidth  / 2f;
            float globalZOffset = -asset.BattleFieldHeight / 2f;
            for (int x = 0; x < asset.BattleFieldWidth; x++)
            {
                for (int z = 0; z < asset.BattleFieldHeight; z++)
                {
                    var   coordinates = new LevelInfoAsset.Coordinates() {x = x, y = z};
                    float xOffset     = (z % 2 == 0) ? 0.5f : 0f;
                    bool  isRiver     = asset.HasPositionInWayPoints(coordinates);
                    var   prefab      = isRiver ? _riverPrefab : _grassPrefab;
                    var instance =
                        Instantiate(prefab,              new Vector3(x + xOffset + globalXOffset, 0, z + globalZOffset),
                                    Quaternion.identity, _battleFieldRoot);
                    instance.name = string.Format("Tile [{0}:{1}]", x, z);
                    var tile = instance.GetComponent<Tile>();
                    tile.Coordinates = coordinates;
                    tile.Type        = isRiver ? Tile.TileType.River : Tile.TileType.Grass;
                    result.Add(tile);
                }
            }

            return result;
        }
    }
}


Пытаясь делать код в соответствии с этими вышеприведенными кодами, я все равно получил (полная Ж), поэтому ЧЯДНТ остается открытым
KetB
UNец
 
Сообщения: 5
Зарегистрирован: 04 дек 2018, 21:51

Re: Определение коллизий: ЧЯДНТ?

Сообщение KetB 05 дек 2018, 07:12

И да, я тугой в C#, поэтому тапками кидаться не надо, сам пытаюсь понять
KetB
UNец
 
Сообщения: 5
Зарегистрирован: 04 дек 2018, 21:51

Re: Определение коллизий: ЧЯДНТ?

Сообщение Anonymyx 05 дек 2018, 13:47

Просто объясните поподробнее, что должен делать код. Что куда должно передавать и что должно пополняться.
Аватара пользователя
Anonymyx
Адепт
 
Сообщения: 1934
Зарегистрирован: 05 апр 2015, 15:55

Re: Определение коллизий: ЧЯДНТ?

Сообщение KetB 05 дек 2018, 22:19

Anonymyx писал(а):Просто объясните поподробнее, что должен делать код. Что куда должно передавать и что должно пополняться.

StepBCDHandler делает делегат на функцию, MainIntelligenceDirectorate делает подписку на события из StepBCDHandler и собирает координаты коллайдеров, на которые наступили, в массив.
KetB
UNец
 
Сообщения: 5
Зарегистрирован: 04 дек 2018, 21:51

Re: Определение коллизий: ЧЯДНТ?

Сообщение Anonymyx 06 дек 2018, 13:33

StepBCDHandler делает делегат на функцию, MainIntelligenceDirectorate делает подписку на события из StepBCDHandler

Зачем все это? Очень кривой подход...
Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections.Generic;
public class StepBCDHandler : MonoBehaviour
{

    private void OnTriggerEnter(Collider other)
    {
       MainIntelligenceDirectorate.inst.AddColliderToList(other);
    }
}
 


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

public class MainIntelligenceDirectorate : MonoBehaviour
{
    public static MainIntelligenceDirectorate inst;

    [SerializeField] List<Vector3> _massiveBCD;

    void Awake()
    {
    inst = this;
    _massiveBCD = new List<GameObject>();
    }


    public void AddColliderToList(Collider collider)
    {
       _massiveBCD.Add(collider.transform.position);
    }

}
Аватара пользователя
Anonymyx
Адепт
 
Сообщения: 1934
Зарегистрирован: 05 апр 2015, 15:55


Вернуться в Общие вопросы

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8