Понедельник, 23 Декабря 2024, 02:49

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

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Странности в связке выделение плюс перемещение
polousДата: Вторник, 26 Августа 2014, 14:13 | Сообщение # 1
частый гость
Сейчас нет на сайте
Ребята, вновь возникла непонятная для меня ситуация. Нуждаюсь в вашей подсказке.
Вот относительно простенький скрипт, в котором из массива объектов с определенным тэгом производится выделение нужного объекта либо путем нажатия мышки на объект, либо по кнопке на гуи. В Update помимо прочего сидит метод для поворота и перемещения выделенного тем или иным образом объекта из массива по клику мышки. И все вроде как замечательно, но происходит 3 такие вот неприятные вещи: 1) когда я кликаю по террейну и выделенный объект поворачивается и двигается в указанную точку, по завершению движения объект почему-то вновь поворачивается в направлении ОZ; 2) когда я делаю выделение другого объекта (по кнопке на гуи), выделяемый объект с чего-то вдруг передвигается в точку, где стоит объект ранее выделенный, хотя конечно, ничего происходить не должно, должно быть просто выделение объекта, а получается будто объект ранее выделенный становится таргетом для перемещения... при этом выделяемый объект еще и вертится в сторону от ранее выделенного игрока; 3) если выделять объект по клику мышки, то выделяемый объект отпалзает на неопределенное расстояние от ранее выделенного, а тот в свою очередь тоже на неизвестное расстояние ползет в сторону выделенного... и так же происходит хаос с поворотом выделяемого объекта. Вот такой вот непонятный процесс... поможете разобраться, что происходит?)
Код

using UnityEngine;
using System.Collections;

public class GameManager : MonoBehaviour {

      public GameObject selectedPlayer; // выделенный юнит игрока (далее кратко "игроки")
      public static GameObject[] players; // массив игроков
      public Vector3 position; // позиция клика мышки, куда будет перемещение/поворот
      bool go = false; // разрешает/запрещает двигаться/поворачиваться
      int index = 0; // индекс в массиве игроков

      void Awake () {
       players = GameObject.FindGameObjectsWithTag("Players"); // игроки - это объекты с тэгом "Players"

       // узнаем индекс для каждого из объектов в массиве players
       foreach (GameObject p in players) {
        p.GetComponent<Player>().indexinmassive = index;
        index = index + 1;
       }
            
       selectedPlayer = players [0]; // на старте выделенным игроком буд
       position = selectedPlayer.transform.position;
      }

           
      void OnGUI () {
       // создаем кнопку для перебора игроков по их индексу в массиве в одну сторону
       if (GUI.Button (new Rect (10, Screen.height - 40, 80, 30), "<<<")) {
        if (i == 0) i= players.Length;
        i--;
        selectedPlayer = players [i]; // выделенный игрок - это текущий игрок из массива
       }
       // создаем кнопку для перебора игроков по их индексу в массиве в другую сторону
       if (GUI.Button (new Rect (100, Screen.height - 40, 80, 30), ">>>")) {
        if (i == players.Length-1) i= -1;
        i++;
        selectedPlayer = players [i]; // выделенный игрок - это текущий игрок из массива
       }

      }

      void Update() {
       // клик по тиррэйну
       if (Input.GetMouseButtonDown(0) && GUIUtility.hotControl == 0) {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit_terrain;
        if (Physics.Raycast(ray, out hit_terrain, 100, 1<<10))    {
         position = hit_terrain.point; // определяем позицию клика
         go = true; // можно двигаться
        }
       }
       // поворот в сторону клика и движение туда же
       if(go) {
        Vector3 direction = new Vector3(position.x - selectedPlayer.transform.position.x, 0, position.z - selectedPlayer.transform.position.z);
        selectedPlayer.transform.rotation = Quaternion.Lerp(selectedPlayer.transform.rotation, Quaternion.LookRotation(direction), Time.deltaTime*selectedPlayer.GetComponent<Player>().rotateSpeed);
        selectedPlayer.transform.position = Vector3.MoveTowards(selectedPlayer.transform.position, position, Time.deltaTime*selectedPlayer.GetComponent<Player>().moveSpeed);
       }
       else {go=false;}

       // выделение игроков по клику мышки
       if(Input.GetMouseButtonDown(0)){      
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);      
        RaycastHit hit_player;      
             
        if(Physics.Raycast(ray, out hit_player, 1000, 1<<11)){      
         selectedPlayer = hit_player.collider.gameObject;
        }      
       }
      }


Сообщение отредактировал polous - Вторник, 26 Августа 2014, 14:20
MANMANAДата: Вторник, 26 Августа 2014, 15:15 | Сообщение # 2
почти ветеран
Сейчас нет на сайте
if(go) {
....
}
else {go=false;}

А чё?

У тебя go всегда true.

И все-таки C# гибче JS, вчера на себе испытал.

Так, например, Ray ray = ... два раза в одной функции JS применять нельзя.
А уж когда я забирал все renderers объекта и пытался их запихнуть в : [] Renderer, то как в C# они нифига не приводятся к Renderer, а, собаки, такие берутся как Component и не хотят приводиться к renderer автоматом. Пришлось сделать вложенный for в другой for для перезаписи в другой массив, что для 21 объекта убило на пару секунд все процессы. Пришлось отказаться.

Добавлено (26.08.2014, 15:15)
---------------------------------------------
А зачем вот это нужно :

Цитата polous ()
foreach (GameObject p in players) {         p.GetComponent<Player>().indexinmassive = index;         index = index + 1;        }

ни разу не понял :/ что-то вроде 0=0, 1=1, 2=2, 3=3 и т.д.?


http://www.3dbuffer.com/ Текстуры, Unity3D, Blender: Эффекты, скрипты, моделирование, текстурирование, скульптинг
VKонтакте 3Dbuffer

Последнее:

Новый раздел "Текстуры"

Как запатентовать, защитить техническое решение, игру, идею
polousДата: Вторник, 26 Августа 2014, 21:40 | Сообщение # 3
частый гость
Сейчас нет на сайте
Во-первых, по поводу "foreach (GameObject p in players) { p.GetComponent<Player>().indexinmassive = index; index = index + 1; }" - это я по клику на любой объект из массива хотел получать его индекс в массиве, вот и написал такую вещь. Но это чисто для себя и никакой нагрузки смысловой оно не несет (просто при клике на объект я вывожу print(индекс)) и будет стерто рано или поздно.

Во-вторых, по поводу "у тебя go всегда true" - это все верно и не суть важно в тех вопросах, что я описал в первом посте. А проблема именно в сквозном клике через объект, который я выделяю, на террейн, на котором в тот же миг определяется точка, куда этому только что выделенному объекту нужно переместиться. А по задумке должно быть так - я кликаю на объект, он выделяется, и уже следующий клик по террейну определяет цель для выделенного объекта. Вот прикладываю картинку.
http://s1.uploadpics.ru/images/W1SSxCVIM.jpg


При чем, если продолжать кликать по уже выделенному объекту в рамках его коллайдера, то на террейне будут возникать разные цели. Я уже выделил для террейна и объектов разные слои для рейкастов, я выделил им свои тэги - не помогает...

Добавлено (26.08.2014, 21:02)
---------------------------------------------
еще я добавил для метода выделения объекта строчку, где позиция цели переопределяется и приравнивается к позиции выделенного объекта, но это переопределение позиции срабатывает после клика по объекту (и увы одновременно по террейну), поэтому в начале происходит то, что я показал на картинке выше, и только затем угол и дистанция становятся нулевыми... хотя этого достаточно, что объект рыпнулся в ненужном направлении...

Добавлено (26.08.2014, 21:40)
---------------------------------------------
может попробовать обработать эти 2 разных события в одном Input.GetMouseButtonDown(0) .... unsure

Сообщение отредактировал polous - Вторник, 26 Августа 2014, 20:54
FirstДата: Вторник, 26 Августа 2014, 22:38 | Сообщение # 4
Уолтер Брайт
Сейчас нет на сайте
Блиин как мог выедает. Как по мне сфмл куда приятнее
polousДата: Вторник, 26 Августа 2014, 22:52 | Сообщение # 5
частый гость
Сейчас нет на сайте
Ну же, люди добрые!) не уж то нет решения?
LertmindДата: Среда, 27 Августа 2014, 01:08 | Сообщение # 6
заслуженный участник
Сейчас нет на сайте
Проект выложи, здесь нет телепатов.

Добавлено (27.08.2014, 01:08)
---------------------------------------------
Вот сделал проект http://rghost.ru/57696771.
Вроде как должно быть, только не делал GUI.
Теги надо называть в единственном числе, в моём проекте Player.
Скрипт для игрока не писал, поэтому нет индексов, а скорости поворота и движения в коде GameManager.
Не использовал layerMask, сам настроишь. Проверял по тегу.
Разворачивался он вперёд, потому что в LookRotation нельзя передавать нулевой вектор.
Код если что:
Код
using UnityEngine;
using System.Collections;

public class GameManager : MonoBehaviour {
     
   public GameObject selectedPlayer; // выделенный юнит игрока (далее кратко "игроки")
   public static GameObject[] players; // массив игроков
   public Vector3 targetPos; // позиция клика мышки, куда будет перемещение/поворот
   bool go = false; // разрешает/запрещает двигаться/поворачиваться
     
   void Awake () {
    players = GameObject.FindGameObjectsWithTag("Player");
    selectedPlayer = players[0];
    targetPos = selectedPlayer.transform.position;
   }
     
   void Update() {
    if (Input.GetMouseButtonDown(0)) {
     Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
     RaycastHit hit;
     if (Physics.Raycast(ray, out hit)) {
      // Выделение игрока
      if (hit.collider.tag == "Player") {
       selectedPlayer.renderer.material.color = Color.white;
       selectedPlayer = hit.collider.gameObject;
       selectedPlayer.renderer.material.color = Color.blue;
       go = false;
      }
      // Поверхность
      else {
       targetPos = hit.point;
       targetPos.y = selectedPlayer.transform.position.y; // Не уходить в пол
       go = true;
      }
     }
    }

    // Поворот в сторону клика и движение туда же
    if(go) {
     float rotateSpeed = 10f;
     float moveSpeed = 5f;
     Vector3 curPos = selectedPlayer.transform.position;
     // Дошли до точки назначения
     if (curPos == targetPos) {
      go = false;
     }
     else {
      Vector3 direction = new Vector3(targetPos.x - curPos.x, 0f, targetPos.z - curPos.z);
      selectedPlayer.transform.rotation = Quaternion.Lerp(selectedPlayer.transform.rotation,
                     Quaternion.LookRotation(direction), Time.deltaTime*rotateSpeed);
      selectedPlayer.transform.position = Vector3.MoveTowards(curPos, targetPos, Time.deltaTime*moveSpeed);
     }
    }
   }
}


Сообщение отредактировал Lertmind - Среда, 27 Августа 2014, 02:09
polousДата: Среда, 27 Августа 2014, 11:08 | Сообщение # 7
частый гость
Сейчас нет на сайте
Эх, я почти сам до этого дошел - уже начал писать все события в одном Input.GetMouseButtonDown(0). Зашел на форум, а тут твой ответ и действительно всё под одним нажатием мышки. Спасибо тебе, Lertmind! Расширил мое понимание)
  • Страница 1 из 1
  • 1
Поиск:

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