Среда, 13 Ноября 2019, 02:30

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
Модератор форума: beril  
Форум игроделов » Движки для разработки игр и сложные системы разработки » Unity » Вопрос-[ответ] по Unity. (Задаём свои вопросы.)
Вопрос-[ответ] по Unity.
QWER56Дата: Понедельник, 09 Августа 2010, 10:58 | Сообщение # 1
старожил
Сейчас нет на сайте
Вопрос-[Ответ] по Unity3d

  • База скриптов Unity3d
  • Курс Уроков по Unity 3D от Alcatraz

    ConsMark - поисковик по интернет магазинам.

    Сообщение отредактировал QWER56 - Вторник, 26 Июля 2011, 20:54
  • Павел_С_ФДата: Суббота, 26 Мая 2018, 15:27 | Сообщение # 8561
    был не раз
    Сейчас нет на сайте
    Всем доброго времени суток! Я изучаю юнити и столкнулся с проблемой, наверняка ее обмусолили несколько раз но я просто не могу правильно сформулировать тег для поиска, есть 3d игра аналог 2D галакси не могу застсвить взаимодействовать клонов на уровне скриптов.
    есть два типа прифабов Astr астероиды и Gun префаб оружия. вот скрипты от них.
    Код
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public class EnemyData : MonoBehaviour
    {
        public float Speed;
        public float LiveTime;
        public int LiveHp;
        public int DamageEnemy;
        private int Live=1;
        private int damagGun;
        private int damagGunn;
        public float DistTach;
        public int Score;
        public GameObject Gun;
        public GameObject Enemy;
        // Use this for initialization
        void Start ()
        {
      Destroy(gameObject,LiveTime);
      //Gun=GetComponent<GunData>().Damage;
      Gun=GameObject.Find("Gun01");
      //Debug.Log("Live= "+Live+"LiveHp= "+LiveHp+"damagGunn= "+damagGunn);
        }
        
        // Update is called once per frame
        void Update ()
        {
      transform.Translate(Vector3.forward*Time.deltaTime*Speed);
      if(Gun)
      {
       if(Vector3.Distance(Gun.transform.position,transform.position)<DistTach)
       {
        damagGunn=GetComponent<GunData>().Damage;
                   Live=LiveHp-GetComponent<GunData>().Damage;
          Debug.Log("++++++++");
       }
       Debug.Log("Gun!!!");
      }
      if(Live<1)
      {
       Destroy(Enemy);
      }
        }
    }



    Код

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public class GunData : MonoBehaviour
    {
        public float Speed;
        public float LiveTime;
        public int Damage;
        private int Pos;

        // Use this for initialization
        void Start ()
        {
      Destroy(gameObject,LiveTime);
        }
        
        // Update is called once per frame
        void Update ()
        {
      transform.Translate(Vector3.forward*Time.deltaTime*Speed);
      //Pos=transform.Translate(Vector3.forward*Time.deltaTime*Speed);
        }
    }
    Ma0ooДата: Воскресенье, 27 Мая 2018, 18:08 | Сообщение # 8562
    уже был
    Сейчас нет на сайте
    Здравствуйте, мне тут надо создать что-то вроде небольшого дебаг лога. Но я не знаю как получить имя объекта, уже находящегося в сцене, чтобы потом его запихнуть в UI текст. Мне нужно что-то вроде этого -
    Код
    string nameObject = имя объекта;
    drcrackДата: Воскресенье, 27 Мая 2018, 18:11 | Сообщение # 8563
    старожил
    Сейчас нет на сайте
    gameObject.name
    НезНaлДата: Среда, 30 Мая 2018, 09:03 | Сообщение # 8564
    частый гость
    Сейчас нет на сайте
    я застрял на животреплощущем вопросе -
    в какой (бесплатной) программе лучше всего лепить человеческий 3д песронаж
    (со встроенным скелетом и с прикрепленными к телу волосами и одеждой),
    что бы с наименьшей головной болью перенести его в Unity
    с возможностью в последующем им управлять?

    этот же вопрос я задал на форум Unity 3D
    ответ - полное молчание


    кратко о себе
    в прогах дуб липовый


    Сообщение отредактировал НезНaл - Среда, 30 Мая 2018, 09:09
    andarkyДата: Среда, 30 Мая 2018, 09:08 | Сообщение # 8565
    старожил
    Сейчас нет на сайте
    НезНaл, ну это же ясно уже давно, ответ один = BLENDER
    правда научиться в нем работать сможет далеко не каждый



    Моя страничка по дизайну
    GameDev//Design//3D
    НезНaлДата: Среда, 30 Мая 2018, 09:15 | Сообщение # 8566
    частый гость
    Сейчас нет на сайте
    Цитата andarky ()
    ... BLENDER
    правда научиться в нем работать сможет далеко не каждый

    что-то я в нем подзастрял, возможно из-за сложноватого интерфейса.
    наверное, по BLENDERу на форуме стоит тему замутить


    кратко о себе
    в прогах дуб липовый


    Сообщение отредактировал НезНaл - Среда, 30 Мая 2018, 09:17
    andarkyДата: Среда, 30 Мая 2018, 09:29 | Сообщение # 8567
    старожил
    Сейчас нет на сайте
    НезНaл, он нестандартный. Очень корявый GUI...
    но из бесплатного - это единственное толковое



    Моя страничка по дизайну
    GameDev//Design//3D
    drcrackДата: Среда, 30 Мая 2018, 14:29 | Сообщение # 8568
    старожил
    Сейчас нет на сайте
    да вы че, какой блендер :D чтобы там персонажа сделать нормального это надо полгода учиться терпению
    для новичка тока генераторы типа makehuman или fuse
    а если нормально лепить то это zbrush и тд
    не уверен что это тебе надо если ты не собираешься стать моделлером
    Павел_С_ФДата: Среда, 30 Мая 2018, 23:03 | Сообщение # 8569
    был не раз
    Сейчас нет на сайте
    zbrush и несколько уроков внимательно смотреть. My WebPage начни с этого

    Добавлено (30 Мая 2018, 22:28)
    ---------------------------------------------
    а вот мне никто не помог
    Код
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;

    public class EnemyData : MonoBehaviour
    {
        public float Speed;
        public float LiveTime;
        public static int LiveShipTranslation;
        public int DamageEnemy,HpShip=100;
        private int Live=1;
        public float DistTach;
        public int Score;
        public GameObject Ship;
        public GameObject Enemy;
        
        void Start ()
        {
      Destroy(gameObject,LiveTime);
      Ship=GameObject.Find("Ship01");
      HpShip=HPShip.LiveShip;
      LiveShipTranslation=HpShip;
      //for(int i=5; i>0; i--){Debug.Log("EnemyData.step__"+i);}
      Debug.Log("EnemyData.HpShip_"+HpShip);
      Debug.Log("EnemyData.LiveShipTranslation__"+LiveShipTranslation);
        }
        

        void Update ()
        {
      transform.Translate(Vector3.forward*Time.deltaTime*Speed);
      Debug.Log("HpShip_"+HpShip);
      Debug.Log("LiveShipTranslation__"+LiveShipTranslation);
      if(Ship)
      {
       if(Vector3.Distance(Ship.transform.position,transform.position)<DistTach)
       {
                   HpShip-=DamageEnemy;
         //Debug.Log("+EnemyData+HpShip+"+HpShip);
         LiveShipTranslation=HpShip;
          Destroy(Enemy);
       }
      }
      
      
      if(Live<1)
      {
       Destroy(Enemy);
      }
        }
    }

    Код
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;

    public class HPShip : MonoBehaviour
    {
        public static int LiveShip;
        public int LiveShipe;
        public GameObject Ship;
        public Slider Slider;
        
        void Start ()
        {
      LiveShip=10;
      Ship=GameObject.Find("Ship01");
      LiveShip=LiveShipe;
      Debug.Log("HPShip.LiveShipe_"+LiveShipe);
      Debug.Log("HPShip.LiveShip_"+LiveShip);
      
        }
        
        
        void Update ()
        {
      //LiveShip=EnemyData.LiveShipTranslation;
      //Debug.Log("=*LiveHp*="+LiveShip);
      if(LiveShip<1)
      {
       Destroy(Ship);
       Application.LoadLevel("GameOver");
      }
      Slider.value=LiveShip;
        }
    }

    вот что выдает
    EnemyData.HpShip_0
    UnityEngine.Debug:Log(Object)
    EnemyData:Start() (at Assets/Scripts/EnemyData.cs:25)

    EnemyData.LiveShipTranslation__0
    UnityEngine.Debug:Log(Object)
    EnemyData:Start() (at Assets/Scripts/EnemyData.cs:26)

    HPShip.LiveShipe_100
    UnityEngine.Debug:Log(Object)
    HPShip:Start() (at Assets/Scripts/HPShip.cs:18)

    HPShip.LiveShip_100
    UnityEngine.Debug:Log(Object)
    HPShip:Start() (at Assets/Scripts/HPShip.cs:19)

    HpShip_0
    UnityEngine.Debug:Log(Object)
    EnemyData:Update() (at Assets/Scripts/EnemyData.cs:33)

    LiveShipTranslation__0
    UnityEngine.Debug:Log(Object)
    EnemyData:Update() (at Assets/Scripts/EnemyData.cs:34)

    не пойму почему принимает нули...
    ну почему LiveShipTranslation__0 принимает ноль понятно а почему EnemyData.HpShip_0 принимает 0 разобраться не могу. я даже притормаживал скрипт эними. там строка исключена пофиг, все равно к нулю приходит.

    Добавлено (30 Мая 2018, 23:03)
    ---------------------------------------------
    я уж как только не кручусь, мне установку жизний надо сделать в юнити, передать это другому скрипту обработать и вернуть первому, так как на этом скрипте будет висеть разные объекты с разными параметрами. вот еще эксперементы. можно конечно сразу присвоить значение в скрипте...

    Код
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;

    public class HPShip : MonoBehaviour
    {
        public int LiveShipe;
        public static int LiveShip=100;
        public GameObject Ship;
        public Slider Slider;
        
        
        void Start ()
        {
      LiveShip=10;
      Ship=GameObject.Find("Ship01");
      LiveShip=LiveShipe;
      //Debug.Log("HPShip.LiveShipe_"+LiveShipe);
      Debug.Log("HPShip.LiveShip_"+LiveShip);
      
        }
        
        
        void Update ()
        {
      //LiveShip=EnemyData.LiveShipTranslation;
      //Debug.Log("=*LiveHp*="+LiveShip);
      if(LiveShip<1)
      {
       Destroy(Ship);
       Application.LoadLevel("GameOver");
      }
      Slider.value=LiveShip;
        }
    }

    Код
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;

    public class EnemyData : MonoBehaviour
    {
        public float Speed;
        public float LiveTime;
        public static int LiveShipTranslation;
        public int DamageEnemy,HpShip=100;
        private int Live=1;
        public float DistTach;
        public int Score;
        public GameObject Ship;
        public GameObject Enemy;
        
        void Start ()
        {
      for(int i=5; i>0; i--){Debug.Log("EnemyData.step__"+i);}
      Destroy(gameObject,LiveTime);
      Ship=GameObject.Find("Ship01");
      HpShip=HPShip.LiveShip;
      LiveShipTranslation=HpShip;
      Debug.Log("EnemyData.HpShip_"+HpShip);
      //Debug.Log("EnemyData.LiveShipTranslation__"+LiveShipTranslation);
        }
        

        void Update ()
        {
      transform.Translate(Vector3.forward*Time.deltaTime*Speed);
      Debug.Log("HpShip_"+HpShip);
      Debug.Log("LiveShipTranslation__"+LiveShipTranslation);
      if(Ship)
      {
       if(Vector3.Distance(Ship.transform.position,transform.position)<DistTach)
       {
                   HpShip-=DamageEnemy;
         //Debug.Log("+EnemyData+HpShip+"+HpShip);
         LiveShipTranslation=HpShip;
          Destroy(Enemy);
       }
      }
      
      
      if(Live<1)
      {
       Destroy(Enemy);
      }
        }
    }

    вот данные консоли
    Код

    EnemyData.step__5
    UnityEngine.Debug:Log(Object)
    EnemyData:Start() (at Assets/Scripts/EnemyData.cs:20)

    EnemyData.step__4
    UnityEngine.Debug:Log(Object)
    EnemyData:Start() (at Assets/Scripts/EnemyData.cs:20)

    EnemyData.step__3
    UnityEngine.Debug:Log(Object)
    EnemyData:Start() (at Assets/Scripts/EnemyData.cs:20)

    EnemyData.step__2
    UnityEngine.Debug:Log(Object)
    EnemyData:Start() (at Assets/Scripts/EnemyData.cs:20)

    EnemyData.step__1
    UnityEngine.Debug:Log(Object)
    EnemyData:Start() (at Assets/Scripts/EnemyData.cs:20)

    EnemyData.HpShip_100
    UnityEngine.Debug:Log(Object)
    EnemyData:Start() (at Assets/Scripts/EnemyData.cs:25)

    HPShip.LiveShip_100
    UnityEngine.Debug:Log(Object)
    HPShip:Start() (at Assets/Scripts/HPShip.cs:20)

    HpShip_100
    UnityEngine.Debug:Log(Object)
    EnemyData:Update() (at Assets/Scripts/EnemyData.cs:33)

    LiveShipTranslation__100
    UnityEngine.Debug:Log(Object)
    EnemyData:Update() (at Assets/Scripts/EnemyData.cs:34)

    да, я добился своего только не тем способом!((


    Сообщение отредактировал Павел_С_Ф - Среда, 30 Мая 2018, 22:31
    drcrackДата: Четверг, 31 Мая 2018, 04:53 | Сообщение # 8570
    старожил
    Сейчас нет на сайте
    Цитата
    а вот мне никто не помог

    потому что мало желающих копаться в 2 экранах плохо написанного кода, уж извини.)
    BBLДата: Четверг, 31 Мая 2018, 14:40 | Сообщение # 8571
    уже был
    Сейчас нет на сайте
    Весьма глупый вопрос (может я тупой) не могу допереть как мне сделать что бы анимация двигала персонажа
    http://skrinshoter.ru/s/310518/tSnpIWo5 в нижнем окне
    дело в том что я делаю движение анимацией и если Humanoid скелетом все ясно , то с Generic не понятно как сделать что бы персонаж (лошадь) двигалась анимацией
    Подскажите буду весьма признателен!
    Заранее Спасибо
    WiteДата: Четверг, 31 Мая 2018, 15:34 | Сообщение # 8572
    участник
    Сейчас нет на сайте
    Apply root node галка в аниматоре, в анимации галка generate root node.
    Павел_С_ФДата: Четверг, 31 Мая 2018, 23:17 | Сообщение # 8573
    был не раз
    Сейчас нет на сайте
    Цитата drcrack ()
    потому что мало желающих копаться в 2 экранах плохо написанного кода, уж извини.)

    Можно вопрос. А у тебя коды с первой попытки сразу стали хорошо написаны? Я ни разу не заявил что программист вот помощи и прошу. будь я специалистом то такие вопросы не задавал.

    Добавлено (31 Мая 2018, 23:17)
    ---------------------------------------------
    я специалист в другой области. не будем обсуждать в какой, если коллега начинает косячить я подайду и предупрежу что в итоге у него будет, даже если и не просят помоч, так как можно попасть на деньги. а тут обратился к спецам а вместо ответа пальцы веером.

    pixeyeДата: Четверг, 31 Мая 2018, 23:32 | Сообщение # 8574
    Red Winter Software
    Сейчас нет на сайте
    Павел, копаться в чужом коде все равно что копаться в чужой голове - та еще хрень. Одно дело помогать с какими-то настройками в юнити или общими вопросами по программированию
    другое дело влезать в твою реализацию логики.

    Пока мне вообще трудно понять что у тебя происходит.
    У тебя например класс EnemyData - что наталкивает на мысль о контейнере с переменными но там же сразу идет какая-то логика причем с совершенно для меня убийственным
    Код
        void Start () { Destroy(gameObject,LiveTime);}
    - ну для эффекта я это понимаю, а enemyData тут причем?


    ACTORS - мой фреймворк на Unity3d



    Сообщение отредактировал pixeye - Четверг, 31 Мая 2018, 23:33
    Павел_С_ФДата: Пятница, 01 Июня 2018, 01:52 | Сообщение # 8575
    был не раз
    Сейчас нет на сайте
    Цитата pixeye ()
    Код
    void Start () { Destroy(gameObject,LiveTime);}
    - ну для эффекта я это понимаю, а enemyData тут причем?

    да все верно это контейнер данных с обработкой, я учусь по видеоурокам так как нет нормальных источников по юнити, в видео такой пример был, на их сайте только общие данные я не спец что бы в них разобраться, поэтому такая каша void Start () { Destroy(gameObject,LiveTime);} эта строчка что бы не переполнять память то есть в начале создания объекта ему выделено некое время после чего он удаляется. время выставляется для каждого прифаба свое, разные рпифабы разное время, тип прифабов один, скрипт на них на всех один.


    Сообщение отредактировал Павел_С_Ф - Пятница, 01 Июня 2018, 01:53
    НезНaлДата: Пятница, 01 Июня 2018, 02:30 | Сообщение # 8576
    частый гость
    Сейчас нет на сайте
    по совету
    возник встречный воопросс -
    чем zbrush лучше таких конструкторов графики как
    (ниже перечислен длиииинный список конкурентов)
    Blender (бесплатный), Maya и 3D Max
    ???


    кратко о себе
    в прогах дуб липовый


    Сообщение отредактировал НезНaл - Пятница, 01 Июня 2018, 02:51
    drcrackДата: Пятница, 01 Июня 2018, 04:23 | Сообщение # 8577
    старожил
    Сейчас нет на сайте
    он ничем не лучше, он их дополняет. сначала скульптят в zbrush, потом дорабатывают в одном из перечисленных. чаще всего в майке

    Сообщение отредактировал drcrack - Пятница, 01 Июня 2018, 04:23
    НезНaлДата: Пятница, 01 Июня 2018, 07:59 | Сообщение # 8578
    частый гость
    Сейчас нет на сайте
    то есть, если в бесплатном Blenderе появилась человеческая скуль турная примочка, то в платном zbrush необходимость отпадает.
    ОК



    кратко о себе
    в прогах дуб липовый


    Сообщение отредактировал НезНaл - Пятница, 01 Июня 2018, 08:13
    OtinagiДата: Пятница, 01 Июня 2018, 08:36 | Сообщение # 8579
    постоянный участник
    Сейчас нет на сайте
    Добры день. Есть ли какие-нибудь уроки для Юнити по созданию нормального динамического освещения с тенями от 100500 источников света на карте? Чтобы в итоге все не глючыло, не тормозило и не мерцало. Как в Сталкере, например. Там от каждой лампочки идёт тень и порой в комнате с учётом солнца по 3-4 тени от объекта и всё отлично работает. И на Юнити видел всякие инди игры с норм тенями и светом, но сам как ни кручу - всегда ерунда выходит. Спасибо.

    «Смерти меньше всего боятся те люди, чья жизнь имеет наибольшую ценность.»
    Иммануил Кант
    pixeyeДата: Пятница, 01 Июня 2018, 09:31 | Сообщение # 8580
    Red Winter Software
    Сейчас нет на сайте
    Цитата Павел_С_Ф ()
    да все верно это контейнер данных с обработкой, я учусь по видеоурокам так как нет нормальных источников по юнити, в видео такой пример был, на их сайте только общие данные я не спец что бы в них разобраться, поэтому такая каша void Start () { Destroy(gameObject,LiveTime);} эта строчка что бы не переполнять память то есть в начале создания объекта ему выделено некое время после чего он удаляется. время выставляется для каждого прифаба свое, разные рпифабы разное время, тип прифабов один, скрипт на них на всех один.


    Переполнять память? Я 6 лет назад на третий айфон так не запаривался делая игры, а уж на комп и подавно.
    Aбстрактный совет : излишняя оптимизация - зло.

    Если уж на то пошло и у тебя много однотипных объектов которые должны создаваться/удаляться используй пул объектов.
    В любом случае это от контекста зависит. У меня похожее было на эффектах.

    Код

        LiveShip=10;
        Ship=GameObject.Find("Ship01");
        LiveShip=LiveShipe;
        


    Нет смысла прописывать LiveShip дважды.

    1) Не рекомендую использовать монобехейверы для дата компонентов. Используй обычные C# классы.
    2) Разделяй UI и логику. У тебя там в классе здоровья корабля UI
    3) Хорошо если твой класс выполняет 1 задачу. Это может быть не буквально 1 задача, но относиться к решению 1 задачи. Это повышает читабельность и гораздо легче править.
    4) Если игра слишком мелкая для деления на классы поведений то все равно можно структурно разделять методами задачи.
    5) Не юзай GameObject Find без особой нужды ( на самом деле он хоть и медленный но если всего мало то без разницы )

    Я кину тебе простой пример архитектуры. Тебе не обязательно его повторять просто подумай в этом направлении.

    Код

    // сериалайзабл позволит видеть переменные обычного класса в инспекторе
        [System.Serializable]
        public class DataHP
        {
      public int val;
        }


    Код


    // База для всех твоих монобехейверов и контейнер.
        public class MonoBase : MonoBehaviour
        {
      public Dictionary<int, object> container = new Dictionary<int, object>();

      // добавляем в контейнер объект определенного типа
      public void Add<T>(T o)
      {
       container.Add(typeof(T).GetHashCode(), o);
      }
      // вытаскиваем из контейнера объект определенного типа
      public T Get<T>()
      {
       object val;
       if (container.TryGetValue(typeof(T).GetHashCode(), out val))
       {
        return (T) val;
       }

       return default(T);
      }
        }


    Код


        // ленивый синглтон только для примера.
        public  class DataSession
        {
      public static DataSession Default = new DataSession();
      public MonoBase player;
      public List<MonoBase> enemies = new List<MonoBase>();
        }



    Код

        // наследуем от монобейза
        public class PlayerShip : MonoBase
        {
      [SerializeField]
      private DataHP dataHP;

      // добавляем дату
      private void Awake()
      {
       Add(dataHP);
      }

      public void Update()
      {
       HandleInput();
       HandleMove();
       HandleDestroy();
      }

      void HandleInput()
      {
       
      }

      void HandleMove()
      {
       
      }

      void HandleDestroy()
      {
       
      }
      // добавляем в данные
      private void OnEnable()
      {
       DataSession.Default.player = this;
      }

      private void OnDisable()
      {
       DataSession.Default.player = null;
      }
      
        }


    Код


        // наследуем от монобейза    
        public class EnemyShip : MonoBase
        {
      [SerializeField]
      private DataHP dataHP;

      private void Awake()
      {
       Add(dataHP);
      }

      public void Update()
      {
       HandleAI();
       HandleMove();
       HandleAttack();
       HandleDestroy();
      }

      void HandleAI()
      {
       
      }

      void HandleMove()
      {
       
      }

      void HandleAttack()
      {
       DataSession.Default.player.Get<DataHP>().val--;
      }
      
      void HandleDestroy()
      {
       
      }

      private void OnEnable()
      {
       DataSession.Default.enemies.Add(this);
      }

      private void OnDisable()
      {
       DataSession.Default.enemies.Remove(this);
      }
      
      
        }


    Что в итоге. Без труда можно любому понять контекст. Это корабль игрока и у него несколько методов - получения управления, движения , уничтожения. У него есть одна дата - здоровье.
    Есть корабль противника. У него одна дата- здоровье и есть AI, движение, атака и уничтожение.
    Есть дата которая хранит сессию куда мы добавляем врагов и героя.
    Так как все они наследуются от одной нашей обертки ( MonoBase ) то нам необязательно знать ТИП сущности чтобы к ней обратиться. Мы предполагаем, что у сущности которую мы обозвали переменной игрока есть DataHP и обращаемся к ней напрямую через MonoBase

    Размышляя в таком русле ты можешь построить игру на компонентах и никогда не задаваться вопросами как общаться между сущностями : )


    ACTORS - мой фреймворк на Unity3d



    Сообщение отредактировал pixeye - Пятница, 01 Июня 2018, 09:46
    Форум игроделов » Движки для разработки игр и сложные системы разработки » Unity » Вопрос-[ответ] по Unity. (Задаём свои вопросы.)
    Поиск:

    Все права сохранены. GcUp.ru © 2008-2019 Рейтинг