Смена спрайтов персонажа в зависимости от положения курсора.

Форум для самых маленьких, а так же тех, кому недосуг читать справку самостоятельно.

Смена спрайтов персонажа в зависимости от положения курсора.

Сообщение DreameR 15 май 2022, 21:08

Привет! Есть игровой персонаж, у него есть 8 разных спрайтов по ракурсам, которые смотрят в разные стороны света, в частности, на Север, Северо-Восток, Восток, Юго-Восток, Юг, Юго-запад, Запад, Северо-Запад. Изменяться спрайты должны в зависимости от положения курсора относительно самого игрока, ибо камера не привязана к игроку. Курсор мыши над игроком, спрайт меняется и он смотрит на Север и т.д. с другими направлениями. Сам проект в 2д, имеется некий код, но он работает только на 4 направления, а мне нужно 8. Предполагаю, что методом векторов и сравнения, куда ближе вектор под курсором, как реализовано в коде ниже, сделать в 8 ракурсов нереально. Есть у кого-то предложения, как это можно реализовать по-другому? Заранее спасибо и извиняюсь за много буковок.
Синтаксис:
Используется csharp
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class RotationToMouse : MonoBehaviour
{
    // в этот масиив в инспекторе перетаскиваю нужные спрайты, чтобы их порядок совпадал с массивом _derections
    public Sprite[] sprites = new Sprite[0];

    //  Vector2.up, Vector2.one, Vector2.right, new Vector2(1,-1),  Vector2.down, new Vector2(-1,-1), Vector2.left, new Vector2(-1,1)
        //  Vector2.up, Vector2.down, Vector2.left, Vector2.right
        //  new Vector2(1,1), new Vector2(1,-1), new Vector2(-1,-1), new Vector2(-1,1)
        //new Vector2(0.4f,1), new Vector2(1,0.4f), new Vector2(1,-0.4f), new Vector2(0.4f,-1), new Vector2(-0.4f,-1), new Vector2(-1,-0.4f), new Vector2(-1,0.4f), new Vector2(-0.4f,1)
    // массив сторон
    private Vector2[] _directions = new Vector2[] {Vector2.up, Vector2.down, Vector2.left, Vector2.right};

    // текущее направление
    private Vector2 _currentDirection;

    // сюда закешируем спрайтРендерер
    private SpriteRenderer _spriteRend;

    // при запуске игры кешируем спрайтРендерер
    private void Start()
    {
        _spriteRend = GetComponent<SpriteRenderer>();
    }

    // постоянно обновляем направление и спрайт
    void Update()
    {
        updateDirectionAndSprite();
    }


    private void updateDirectionAndSprite()
    {
        // временная переменная для обнаружения более близкого скалярного произведения
        float maxDot = -1;
        // направление от персонажа к курсору мыши
        // перевод координаты персонажа в экранные координаты
        Vector2 mouseToPlayerDirection = (Input.mousePosition - Camera.main.WorldToScreenPoint(transform.position)).normalized;
        Vector2 tempDirection = Vector2.zero;

        // находим наиболее близкое направление из массива направлений к текущему направлению персонажа к курсору
        foreach (Vector2 direction in _directions)
        {
            float currentDot = Vector2.Dot(mouseToPlayerDirection, direction);
            if (currentDot > maxDot)
            {
                maxDot = currentDot;
                tempDirection = direction;
            }
        }

        // только если направление изменилось, то запоминаем это направление и меняем спрайт
        if (_currentDirection != tempDirection)
        {
            _currentDirection = tempDirection;
            _spriteRend.sprite = sprites[Array.IndexOf(_directions, _currentDirection)];
        }
    }

}
DreameR
UNец
 
Сообщения: 2
Зарегистрирован: 14 май 2022, 23:29

Re: Смена спрайтов персонажа в зависимости от положения курсора.

Сообщение 1max1 15 май 2022, 22:01

как реализовано в коде ниже, сделать в 8 ракурсов нереально

А так не работает?

Синтаксис:
Используется csharp
    private Vector2[] _directions = new Vector2[]
    {
        Vector2.up,
        Vector2.down,
        Vector2.left,
        Vector2.right,
        Vector2.up + Vector2.right,
        Vector2.up + Vector2.left,
        Vector2.down + Vector2.right,
        Vector2.down + Vector2.left
    };


Еще можно вот так:

Синтаксис:
Используется csharp
    void Update()
    {
        var delta = Input.mousePosition - Camera.main.WorldToScreenPoint(transform.position);
        var angle = Mathf.Atan2(delta.y, delta.x) * Mathf.Rad2Deg + 22.5f;
        var index = (int)(Mathf.Repeat(angle, 360.0f) / 360.0f * 8);

        print(index);
    }
Аватара пользователя
1max1
Адепт
 
Сообщения: 5505
Зарегистрирован: 28 июн 2017, 10:51

Re: Смена спрайтов персонажа в зависимости от положения курсора.

Сообщение DreameR 16 май 2022, 18:10

1max1 писал(а):
как реализовано в коде ниже, сделать в 8 ракурсов нереально

А так не работает?

Синтаксис:
Используется csharp
    private Vector2[] _directions = new Vector2[]
    {
        Vector2.up,
        Vector2.down,
        Vector2.left,
        Vector2.right,
        Vector2.up + Vector2.right,
        Vector2.up + Vector2.left,
        Vector2.down + Vector2.right,
        Vector2.down + Vector2.left
    };


Еще можно вот так:

Синтаксис:
Используется csharp
    void Update()
    {
        var delta = Input.mousePosition - Camera.main.WorldToScreenPoint(transform.position);
        var angle = Mathf.Atan2(delta.y, delta.x) * Mathf.Rad2Deg + 22.5f;
        var index = (int)(Mathf.Repeat(angle, 360.0f) / 360.0f * 8);

        print(index);
    }

Привет. Потестил предложенные тобой варианты и хочу сказать спасибо.

Если просто закинуть 8 векторов, выходит совершенно не то, что ожидалось, уже пробовал как-то работать с этим кодом. Что выходит, если закинуть просто 8 векторов, я приложу ниже. Да и в комментариях кода, кстати, можно заметить, что я уже вписывал именно эти-же вектора, только не в виде констант. https://prnt.sc/XtQ-gRvTsanC

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

Еще раз спасибо за помощь, пойду постигать азы ГеймДев'а дальше)

Тут, на форуме, можно как-то функционально закрыть тему, если вопрос в ней решен?
DreameR
UNец
 
Сообщения: 2
Зарегистрирован: 14 май 2022, 23:29


Вернуться в Почемучка

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

Сейчас этот форум просматривают: GoGo.Ru [Bot] и гости: 22