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

UI указатель 3D пространства[Решено][с костылём 100%]

СообщениеДобавлено: 17 июл 2018, 15:25
I-Dgt
Понадобилось сделать на экранный маркер(указатель), так как я в гугол не смог написал скрипт, который перемещает 3D объект перед камерой. Скрипт я переписал под UI, а оригинал для 3D объекта потерян, так что далее будет лишь реставрация(скрипт внизу).
Изображение
Скрытый текст:
Изображение
Изображение

Скрипт который использую сейчас:
Синтаксис:
Используется csharp
using UnityEngine;

public class Marker : MonoBehaviour {
        public Transform target;
        public RectTransform marker;
        public RectTransform arrow;
        Vector3 _t;
        public Vector2 _d;
        public Vector2 _b;
        public float _w;
        public float _h;
        public float soot;
        Quaternion arrowZero;
        public bool X;
        public bool Y;
        void Start () {
                arrowZero = arrow.rotation;
        }
        void LateUpdate () {
                _t = transform.InverseTransformVector (target.position - transform.position);
                if (!Mathf.Approximately(_t.z, 0)) {
                        _w = Screen.width / 2;
                        _h = Screen.height / 2;
                        _w -= 50;
                        _h -= 50;
                        _d.x = _t.x;
                        _d.y = _t.y;
                        _d /= Mathf.Abs (_t.z);
                        _d.x = _d.x * soot;
                        _d.y = _d.y * soot + 50;
                        _b.x = Mathf.Clamp (_d.x, - _w, _w);
                        _b.y = Mathf.Clamp (_d.y, - _h, _h);
                }
                marker.anchoredPosition = _b;
                X = !Mathf.Approximately (_d.x, _b.x);
                Y = !Mathf.Approximately (_d.y, _b.y);
                if (X || Y) {
                        arrow.rotation = Quaternion.LookRotation (Vector3.forward, - _d);
                } else {
                        arrow.rotation = arrowZero;
                }
        }
}

А теперь проблемы моей реализации:
1)Если развернуться на 180, то маркер будет показывать в пустоту(эта проблема как в 1ой версии скрипта, так и во 2ой).
Скрытый текст:
Изображение

2)В скрипте для UI, есть некое значение soot(возможно ругательная аббревиатура, я уже не помню), методом научного тыка было получено значение 666 для разрешения экрана 1024x768. Но при этом в оригинальном скрипте такого не было, при реставрации такого результата не удалось достичь, там так же 666.
Скрытый текст:
Изображение

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

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

public class Marker3D : MonoBehaviour {
        public Transform target;
        public Transform marker;
        Vector3 _t;
        public Vector3 _d;
        public Vector3 _b;
        public float _w;
        public float _h;
        void LateUpdate () {
                _t = transform.InverseTransformVector (target.position - transform.position);
                if (!Mathf.Approximately(_t.z, 0)) {
                        _w = Screen.width / 2;
                        _h = Screen.height / 2;
                        _w -= 50;
                        _h -= 50;
                        _w /= 666;
                        _h /= 666;
                        _d.x = _t.x;
                        _d.y = _t.y;
                        _d.z = 1;
                        _d /= Mathf.Abs (_t.z);
                        _d.x = _d.x;
                        _d.y = _d.y + 0.075f;
                        _b.x = Mathf.Clamp (_d.x, - _w, _w);
                        _b.y = Mathf.Clamp (_d.y, - _h, _h);
                        _b.z = 1;
                }
                marker.localPosition = _b;
        }
}

Если кто знает как гуглить или другие решение(а лучше и то и то), дайте знать.

Re: UI указатель 3D пространства

СообщениеДобавлено: 17 июл 2018, 15:51
Cr0c
Там же можно просто переводить мировые в экранные и ставить туда маркер.

Re: UI указатель 3D пространства

СообщениеДобавлено: 17 июл 2018, 16:19
I-Dgt
Cr0c писал(а):Там же можно просто переводить мировые в экранные и ставить туда маркер.

Ещё бы понимать как это и чем отличается от моего метода.

Re: UI указатель 3D пространства

СообщениеДобавлено: 17 июл 2018, 16:26
Cr0c
Синтаксис:
Используется csharp
Vector3 guiPos = Camera.main.WorldToScreenPoint(mark.position);
markImage.position = guiPos;
 

mark - трансформ метки в сцене
markImage - трансформ картинки метки на канвасе

Re: UI указатель 3D пространства

СообщениеДобавлено: 17 июл 2018, 16:30
I-Dgt
Cr0c писал(а):
Синтаксис:
Используется csharp
Vector3 guiPos = Camera.main.WorldToScreenPoint(mark.position);
markImage.position = guiPos;
 

mark - трансформ метки в сцене
markImage - трансформ картинки метки на канвасе

Делал так, маркер гдет в углу, сейчас попробую пошаманить(думал раз не работает поищу другой метод, ну раз посоветовал, буду проводить эксперименты).

Re: UI указатель 3D пространства

СообщениеДобавлено: 17 июл 2018, 16:33
I-Dgt
I-Dgt писал(а):Делал так, маркер гдет в углу, сейчас попробую пошаманить(думал раз не работает поищу другой метод, ну раз посоветовал, буду проводить эксперименты).

Нашёл, marker.anchoredPosition = _b; исправил на marker.position = _b;

Re: UI указатель 3D пространства[50%Решено]

СообщениеДобавлено: 17 июл 2018, 16:35
I-Dgt
Всё равно если повернутся на 180, то маркер в пустоту показывает.

Re: UI указатель 3D пространства[50%Решено]

СообщениеДобавлено: 17 июл 2018, 18:03
Cr0c
Так выключай маркер, когда он по XZ угол к forward имеет больше fov'а камеры

Re: UI указатель 3D пространства[50%Решено]

СообщениеДобавлено: 17 июл 2018, 18:25
1max1
Так выключай маркер, когда он по XZ угол к forward имеет больше fov'а камеры

гениально))
Всё равно если повернутся на 180, то маркер в пустоту показывает.

Придется делать костыли, по другому никак)

Re: UI указатель 3D пространства[50%Решено]

СообщениеДобавлено: 17 июл 2018, 19:02
I-Dgt
1max1 писал(а):Придется делать костыли, по другому никак)

К этому же пришёл, сделаю выложу.

Re: UI указатель 3D пространства[100%Решено]

СообщениеДобавлено: 17 июл 2018, 23:54
I-Dgt
Cr0c писал(а):

1max1 писал(а):

Спс за помощь, хоть я и приходил к тем же умозаключениям, вы устраняли колебания во мне.
(3A4OT)
Вот код если кому понадобится:
Синтаксис:
Используется csharp
using UnityEngine;

public class Marker : MonoBehaviour {
        public Transform target;
        public RectTransform marker;
        public RectTransform arrow;
        Vector3 _t;
        Vector2 _d;
        Vector2 _b;
        float _w;
        float _h;
        Quaternion arrowZero;
        bool X;
        bool Y;
        public Camera cam;
        float angX;
        float angY;
        public float _size = 50;
        void Start () {
                arrowZero = arrow.rotation;
        }
        void LateUpdate () {
                _t = cam.WorldToScreenPoint (target.position);
                _w = Screen.width / 2;
                _h = Screen.height / 2;
                _t.x -= _w;
                _t.y -= _h;
                _w -= _size / 2;
                _h -= _size / 2;
                _b = _t;
                _d.x = _t.y;
                _d.y = _t.x;
                angX = Vector2.Angle(Vector2.right, _t);
                angY = Vector2.Angle(Vector2.right, _d);
                angX -= 90;
                angY -= 90;
                Vector2 _v = _b;
                _v.y += _size;
                if (_t.z > 0) {
                        bool _ooo = ((_b.x > _w) | (_b.y > _h));
                        bool _too = ((_b.x < -_w) | (_b.y < -_h));
                        bool _foo = (_ooo | _too);
                        if (_foo) {
                                if (Mathf.Abs (angX) > Mathf.Abs (angY)) {
                                        if (Mathf.Sign (angX) > 0) {
                                                _v.x = -_w;
                                        } else {
                                                _v.x = _w;
                                        }
                                        _v.y = Mathf.Clamp(Mathf.Tan (angY * Mathf.Deg2Rad) * - _w, -_h, _h);
                                } else {
                                        if (Mathf.Sign (angY) > 0) {
                                                _v.y = -_h;
                                        } else {
                                                _v.y = _h;
                                        }
                                        _v.x = Mathf.Clamp(Mathf.Tan (angX * Mathf.Deg2Rad) * - _h, -_w, _w);
                                }
                        }
                } else {
                        if (Mathf.Abs (angX) > Mathf.Abs (angY)) {
                                if (Mathf.Sign (angX) > 0) {
                                        _v.x = _w;
                                } else {
                                        _v.x = -_w;
                                }
                                _v.y = Mathf.Clamp(Mathf.Tan (angY * Mathf.Deg2Rad) * _w, -_h, _h);
                        } else {
                                if (Mathf.Sign (angY) > 0) {
                                        _v.y = _h;
                                } else {
                                        _v.y = -_h;
                                }
                                _v.x = Mathf.Clamp(Mathf.Tan (angX * Mathf.Deg2Rad) * _h, -_w, _w);
                        }
                }
                _b = _v;
                marker.anchoredPosition = _b;
                X = !Mathf.Approximately (_t.x, _b.x);
                Y = !Mathf.Approximately (_t.y + _size, _b.y);
                if (X || Y) {
                        if (_t.z > 0) {
                                arrow.rotation = Quaternion.LookRotation (Vector3.forward, -_t);
                        } else {
                                arrow.rotation = Quaternion.LookRotation (Vector3.forward, _t);
                        }
                } else {
                        arrow.rotation = arrowZero;
                }
        }
}

Re: UI указатель 3D пространства[Решено][с костылём 100%]

СообщениеДобавлено: 18 июл 2018, 21:17
Cr0c
Вообще-то тут намного меньше кода
Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MouseControl : MonoBehaviour {

    public float mouseSensitive = 2f;
    public Transform controlled;

    public Transform target;
    public Transform uiMarker;
    private Camera cam;

        void Start () {
        cam = Camera.main;
        }
       
        void Update () {
        if (controlled != null && Input.GetMouseButton(0))
        {
            float mx = Input.GetAxis("Mouse X") * mouseSensitive;
            float my = Input.GetAxis("Mouse Y") * mouseSensitive;
            controlled.Rotate(Vector3.up, mx, Space.World);
            controlled.Rotate(Vector3.left, my, Space.Self);
        }
        if (target != null && uiMarker != null)
        {
            Vector3 targetXZpos = target.position;
            targetXZpos.y = controlled.position.y;
            float angle = Vector3.Angle(controlled.forward, targetXZpos - controlled.position);
            if (angle <= cam.fieldOfView)
            {
                if (!uiMarker.gameObject.activeSelf)
                    uiMarker.gameObject.SetActive(true);
                Vector3 uiPos = cam.WorldToScreenPoint(target.position);
                uiMarker.position = uiPos;
            }
            else
            {
                if (uiMarker.gameObject.activeSelf)
                    uiMarker.gameObject.SetActive(false);
            }
        }
    }
}