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

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

СообщениеДобавлено: 10 сен 2014, 01:19
beatlecore
написал генератор фрустумов, может кому пригодится

компонент:
Синтаксис:
Используется 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();
    }
}
 


как все выглядит
Скрытый текст:
Изображение

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

СообщениеДобавлено: 10 сен 2014, 02:07
gnoblin
:)

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

СообщениеДобавлено: 12 сен 2014, 10:34
burovalex
Извиняюсь за нубство, а для чего нужны фрустумы? И почему нельзя собрать такую модель в 3д максе?

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

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

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

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

СообщениеДобавлено: 03 окт 2014, 21:06
burovalex
Спасибо за очень полезную инфу, про обзор понятно, а вот про стрельбу не очень, для стрельбы фрустум наверное нужен только для визуального понимания куда враг попадет с определенного расстояния?

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

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

в основном рейкаст, но есть оружие довольно специфическое, для которого нужно проверять находится ли враг в "конусе поражения", огнемет - вот отличный пример, в купе с рейкастом разумеется =)

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

СообщениеДобавлено: 04 окт 2014, 09:45
burovalex
Спасибо, очень полезно! :-bd