Генератор фрустумов

Инструменты для разработки

Генератор фрустумов

Сообщение beatlecore 10 сен 2014, 01:19

написал генератор фрустумов, может кому пригодится

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

[RequireComponent(typeof(MeshCollider))]
[ExecuteInEditMode]
public class MeshFrustum : MonoBehaviour
{
    public float NearPlaneHeight { get; set; }
    public float NearPlaneWidth { get; set; }
    public float FarPlaneHeight { get; set; }
    public float FarPlaneWidth { get; set; }
    public float Lenght { get; set; }

    public bool Convex { get; set; }

    public bool IsTrigger { get; set; }

    private MeshCollider _cachedCollider;
    private Mesh _meshInstance;

    private Vector3[] _vertices =
    {
        // forward face     x       y       z
        new Vector3(        0.5f,   0.2f,   3),
        new Vector3(       -0.5f,   0.2f,   3),
        new Vector3(        0.5f,  -0.2f,   3),
        new Vector3(       -0.5f,  -0.2f,   3),

        // backward face    x       y       z
        new Vector3(        0.2f,   0.2f,   0),
        new Vector3(       -0.2f,   0.2f,   0),
        new Vector3(        0.2f,  -0.2f,   0),
        new Vector3(       -0.2f,  -0.2f,   0),
    };

    private int[] _triangles =
    {
        // front face
        0, 1, 2,
        1, 2, 3,

        // back face
        4, 5, 6,
        5, 6, 7,

        // left face
        3,1,5,
        3,1,7,

        // right face
        0, 2, 4,
        0, 2, 6,

        // top face
        0, 1, 4,
        0, 1, 5,

        // bottom face
        2, 3, 6,
        2, 3, 7
    };

    private void OnEnable()
    {
        _cachedCollider = GetComponent<MeshCollider>();
        _cachedCollider.convex = Convex;
        _cachedCollider.isTrigger = IsTrigger;

        _meshInstance = new Mesh
        {
            name = "Frustum Collider",
            vertices = _vertices,
            triangles = _triangles
        };

        _meshInstance.RecalculateBounds();
        _meshInstance.RecalculateNormals();

        _cachedCollider.sharedMesh = _meshInstance;
    }

    public void Recalculate()
    {
        // update far plane
        _vertices[0].x = FarPlaneWidth / 2;
        _vertices[1].x = -FarPlaneWidth / 2;
        _vertices[2].x = FarPlaneWidth / 2;
        _vertices[3].x = -FarPlaneWidth / 2;

        _vertices[0].z =
            _vertices[1].z =
                _vertices[2].z =
                    _vertices[3].z = Lenght;

        // update near plane
        _vertices[4].x = NearPlaneWidth / 2;
        _vertices[5].x = -NearPlaneWidth / 2;
        _vertices[6].x = NearPlaneWidth / 2;
        _vertices[7].x = -NearPlaneWidth / 2;

        // update height
        _vertices[4].y =
            _vertices[5].y = NearPlaneHeight / 2;
        _vertices[6].y =
            _vertices[7].y = -NearPlaneHeight / 2;

        _vertices[0].y =
            _vertices[1].y = FarPlaneHeight / 2;
        _vertices[2].y =
            _vertices[3].y = -FarPlaneHeight / 2;

        _meshInstance = new Mesh
        {
            name = "Frustum Collider",
            vertices = _vertices,
            triangles = _triangles
        };

        _meshInstance.RecalculateBounds();
        _meshInstance.RecalculateNormals();

        _cachedCollider.sharedMesh = _meshInstance;

        _cachedCollider.convex = Convex;
        _cachedCollider.isTrigger = IsTrigger;
    }
}
 


едитор к нему
Синтаксис:
Используется csharp
using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(MeshFrustum))]
public class MeshFrustumEditor : Editor
{
    private float _nph = 0.3f;
    private float _nphMin = 0.1f;
    private float _nphMax = 1f;

    private float _npw = 0.3f;
    private float _npwMin = 0.1f;
    private float _npwMax = 1f;

    private float _fph = 1f;
    private float _fphMin = 0.1f;
    private float _fphMax = 10f;

    private float _fpw = 1f;
    private float _fpwMin = 0.1f;
    private float _fpwMax = 10f;

    private float _l = 3f;
    private float _lMin = 0.1f;
    private float _lMax = 20f;

    private MeshFrustum _target;

    public override void OnInspectorGUI()
    {
        _target = (MeshFrustum)target;

        // near plane height
        GUILayout.BeginHorizontal();
        GUILayout.Label("Min", GUILayout.Width(30));
        GUILayout.Label("Near Plane Height");
        GUILayout.Label("Max", GUILayout.Width(30));
        GUILayout.EndHorizontal();

        GUILayout.BeginHorizontal();
        _nphMin = EditorGUILayout.FloatField(_nphMin, GUILayout.Width(30));
        _nph = EditorGUILayout.Slider(_nph, _nphMin, _nphMax);
        _nphMax = EditorGUILayout.FloatField(_nphMax, GUILayout.Width(30));
        GUILayout.EndHorizontal();

        EditorGUILayout.Separator();

        // near plane width
        GUILayout.BeginHorizontal();
        GUILayout.Label("Min", GUILayout.Width(30));
        GUILayout.Label("Near Plane Width");
        GUILayout.Label("Max", GUILayout.Width(30));
        GUILayout.EndHorizontal();

        GUILayout.BeginHorizontal();
        _npwMin = EditorGUILayout.FloatField(_npwMin, GUILayout.Width(30));
        _npw = EditorGUILayout.Slider(_npw, _npwMin, _npwMax);
        _npwMax = EditorGUILayout.FloatField(_npwMax, GUILayout.Width(30));
        GUILayout.EndHorizontal();

        EditorGUILayout.Separator();

        // far plane height
        GUILayout.BeginHorizontal();
        GUILayout.Label("Min", GUILayout.Width(30));
        GUILayout.Label("Far Plane Height");
        GUILayout.Label("Max", GUILayout.Width(30));
        GUILayout.EndHorizontal();

        GUILayout.BeginHorizontal();
        _fphMin = EditorGUILayout.FloatField(_fphMin, GUILayout.Width(30));
        _fph = EditorGUILayout.Slider(_fph, _fphMin, _fphMax);
        _fphMax = EditorGUILayout.FloatField(_fphMax, GUILayout.Width(30));
        GUILayout.EndHorizontal();

        EditorGUILayout.Separator();

        // far plane width
        GUILayout.BeginHorizontal();
        GUILayout.Label("Min", GUILayout.Width(30));
        GUILayout.Label("Far Plane Width");
        GUILayout.Label("Max", GUILayout.Width(30));
        GUILayout.EndHorizontal();

        GUILayout.BeginHorizontal();
        _fpwMin = EditorGUILayout.FloatField(_fpwMin, GUILayout.Width(30));
        _fpw = EditorGUILayout.Slider(_fpw, _fpwMin, _fpwMax);
        _fpwMax = EditorGUILayout.FloatField(_fpwMax, GUILayout.Width(30));
        GUILayout.EndHorizontal();

        EditorGUILayout.Separator();

        // lenght
        GUILayout.BeginHorizontal();
        GUILayout.Label("Min", GUILayout.Width(30));
        GUILayout.Label("Frustum Lenght");
        GUILayout.Label("Max", GUILayout.Width(30));
        GUILayout.EndHorizontal();

        GUILayout.BeginHorizontal();
        _lMin = EditorGUILayout.FloatField(_lMin, GUILayout.Width(30));
        _l = EditorGUILayout.Slider(_l, _lMin, _lMax);
        _lMax = EditorGUILayout.FloatField(_lMax, GUILayout.Width(30));
        GUILayout.EndHorizontal();

        EditorGUILayout.Separator();

        // convex
        _target.Convex = EditorGUILayout.Toggle("Convex", _target.Convex);

        EditorGUILayout.Separator();

        // IsTrigger
        _target.IsTrigger = EditorGUILayout.Toggle("Is Trigger", _target.IsTrigger);

        _target.NearPlaneHeight = _nph;
        _target.FarPlaneHeight = _fph;
        _target.NearPlaneWidth = _npw;
        _target.FarPlaneWidth = _fpw;
        _target.Lenght = _l;

        _target.Recalculate();
    }
}
 


как все выглядит
Скрытый текст:
Изображение
Аватара пользователя
beatlecore
Старожил
 
Сообщения: 965
Зарегистрирован: 05 фев 2013, 21:26
Откуда: Sun Crimea
Skype: beatlecore

Re: Генератор фрустумов

Сообщение gnoblin 10 сен 2014, 02:07

:)
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Генератор фрустумов

Сообщение burovalex 12 сен 2014, 10:34

Извиняюсь за нубство, а для чего нужны фрустумы? И почему нельзя собрать такую модель в 3д максе?
Аватара пользователя
burovalex
UNец
 
Сообщения: 41
Зарегистрирован: 22 янв 2013, 19:08

Re: Генератор фрустумов

Сообщение beatlecore 13 сен 2014, 14:47

burovalex писал(а):Извиняюсь за нубство, а для чего нужны фрустумы? И почему нельзя собрать такую модель в 3д максе?

мы используем для конусов стрельбы, так же можно использовать для поля зрения врагов и прочих ии, почему не макс, потому то для каждого конкретного угла обзора пришлось бы делать новую модель, а тут все настраивается ползунками прямо в редакторе
Аватара пользователя
beatlecore
Старожил
 
Сообщения: 965
Зарегистрирован: 05 фев 2013, 21:26
Откуда: Sun Crimea
Skype: beatlecore

Re: Генератор фрустумов

Сообщение burovalex 03 окт 2014, 21:06

Спасибо за очень полезную инфу, про обзор понятно, а вот про стрельбу не очень, для стрельбы фрустум наверное нужен только для визуального понимания куда враг попадет с определенного расстояния?
Аватара пользователя
burovalex
UNец
 
Сообщения: 41
Зарегистрирован: 22 янв 2013, 19:08

Re: Генератор фрустумов

Сообщение beatlecore 03 окт 2014, 23:30

burovalex писал(а):Спасибо за очень полезную инфу, про обзор понятно, а вот про стрельбу не очень, для стрельбы фрустум наверное нужен только для визуального понимания куда враг попадет с определенного расстояния?

в основном рейкаст, но есть оружие довольно специфическое, для которого нужно проверять находится ли враг в "конусе поражения", огнемет - вот отличный пример, в купе с рейкастом разумеется =)
Аватара пользователя
beatlecore
Старожил
 
Сообщения: 965
Зарегистрирован: 05 фев 2013, 21:26
Откуда: Sun Crimea
Skype: beatlecore

Re: Генератор фрустумов

Сообщение burovalex 04 окт 2014, 09:45

Спасибо, очень полезно! :-bd
Аватара пользователя
burovalex
UNец
 
Сообщения: 41
Зарегистрирован: 22 янв 2013, 19:08


Вернуться в Инструментарий

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

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