OnMouseEnter и GetMouseButton. Задержка выполнения скрипта
| |
ArhipovEvgeniy | Дата: Пятница, 13 Июля 2012, 22:31 | Сообщение # 1 |
был не раз
Сейчас нет на сайте
| Всем привет. Пишу скрипт на C# для головоломки.
У меня возникла проблема проблема: по наведению на объект, нужно нажать на левую кнопку мыши для того, чтобы переместить его. Но дело в том, что перемещение происходит или через пол минуты или вообще не происходит. Скажите пожалуйста в чём проблема? Скрипт C#: using UnityEngine; using System.Collections;
public class changePosition : MonoBehaviour { //первая строчка public Vector3 position1 = new Vector3(1,0,-1); public Vector3 position2 = new Vector3(2,0,-1); public Vector3 position3 = new Vector3(3,0,-1); public Vector3 position4 = new Vector3(4,0,-1); //вторая строчка public Vector3 position5 = new Vector3(1,0,-2); public Vector3 position6 = new Vector3(2,0,-2); public Vector3 position7 = new Vector3(3,0,-2); public Vector3 position8 = new Vector3(4,0,-2); //третья строчка public Vector3 position9 = new Vector3(1,0,-3); public Vector3 position10 = new Vector3(2,0,-3); public Vector3 position11 = new Vector3(3,0,-3); public Vector3 position12 = new Vector3(4,0,-3); //четвёртая строчка public Vector3 position13 = new Vector3(1,0,-4); public Vector3 position14 = new Vector3(2,0,-4); public Vector3 position15 = new Vector3(3,0,-4); public Vector3 position16 = new Vector3(4,0,-4); void Start(){ transform.position = position1; } void OnMouseEnter(){ renderer.material.color = Color.red; Debug.Log("Pressed left click."); if (Input.GetMouseButton(0)){ transform.position = position2; } } void OnMouseExit(){ renderer.material.color = Color.white; Debug.Log(""); } }
|
|
| |
seaman | Дата: Пятница, 13 Июля 2012, 22:49 | Сообщение # 2 |
старожил
Сейчас нет на сайте
| Нельзя проверять клавиши при входе мыши на объект. Кто Вам сказал, что нажатие клавиши и вход произойдет в одном кадре? Нужно разделить подкраску объекта и щелчок мыши по разным функциям. Code void OnMouseEnter() { renderer.material.color = Color.red; } void OnMouseDown() { if (Input.GetMouseButton(0)) transform.position = position2; ) Возможно лучше OnMouseUp
|
|
| |
ArhipovEvgeniy | Дата: Суббота, 14 Июля 2012, 06:10 | Сообщение # 3 |
был не раз
Сейчас нет на сайте
| Спасибо большое! Добавлено (14.07.2012, 06:10) --------------------------------------------- я создаю переменную, в которую входят объекты с одним тегом. К примеру: private GameObject States = FindObjectsWithTag("State")
У меня в наличии 15 объектов с тегом "State". Как обратиться к одному из них?
|
|
| |
SarCasm | Дата: Суббота, 14 Июля 2012, 11:55 | Сообщение # 4 |
заслуженный участник
Сейчас нет на сайте
| К любому с этим тегом? Эм, вместо FindObjectsWithTag написать FindObjectWithTag P.S. как у тебя вообще работает этот скрипт, если FindObjectsWithTag возвращает массив?
Моя игра Gamiron#11 - Тема Скачать
|
|
| |
pixeye | Дата: Суббота, 14 Июля 2012, 12:43 | Сообщение # 5 |
Red Winter Software
Сейчас нет на сайте
| Quote (ArhipovEvgeniy) Спасибо большое! Добавлено (14.07.2012, 06:10) --------------------------------------------- я создаю переменную, в которую входят объекты с одним тегом. К примеру: private GameObject States = FindObjectsWithTag("State")
У меня в наличии 15 объектов с тегом "State". Как обратиться к одному из них?
Code void Start(){
StartCoroutine(coUpdate());
}
IEnumerator coUpdate(){
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; GameObject selected = null;
while(true){
if (Input.GetMouseButtonDown(0)){ ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray,out hit,Mathf.Infinity)) if (hit.collider.CompareTag("State")) selected = hit.collider.gameObject;
}
yield return 0; }
}
Неисключены ошибки в синтаксисе, писал на лету, но в целом так ты можешь выбрать объект на который указывает курсор по нажатию. Лучше всегда делай проверки такого типа + используй один менеджер скрипт, а не проверку во всех объектах.
ACTORS - мой фреймворк на Unity Until We Die - игра над которой работаю
|
|
| |
ArhipovEvgeniy | Дата: Воскресенье, 15 Июля 2012, 11:54 | Сообщение # 6 |
был не раз
Сейчас нет на сайте
| Спасибо pixeye.
зашёл в ступор. Не понимаю как из скрипта обращаться от объекта родитель к объекту потомок (и наоборот). А в частности надо, чтобы потомок задал Тег родителю (скрипт повешен на потомка). Скажите пожалуйста какой командой это сделать? Документацию читал, там несколько команд с родитель-потомок, разобраться в них не получается.Добавлено (15.07.2012, 11:54) --------------------------------------------- Здравствуйте) Вопрос с родителем/потомком отпал
Но возник новый: возможно ли обеспечить плавное перемещение при таком коде:
transform.position = Empty.transform.position; //один объект берёт позицию другого. Tive.deltaTime не помогает, а выразить позицию Empty в виде Vector3 запрещается
|
|
| |
pixeye | Дата: Воскресенье, 15 Июля 2012, 12:01 | Сообщение # 7 |
Red Winter Software
Сейчас нет на сайте
| Quote (ArhipovEvgeniy) Но возник новый: возможно ли обеспечить плавное перемещение при таком коде:
transform.position = Empty.transform.position; //один объект берёт позицию другого. Tive.deltaTime не помогает, а выразить позицию Empty в виде Vector3 запрещается
Да. Возможно, сейчас код скину.
Передвижение по скорости. Code public IEnumerator moveToBySpeed (Transform obTransform, Vector3 end, float speed) { Vector3 start = obTransform.position; float rate = 1.0f / Vector3.Distance (start, end) * speed; float t = 0.0f; while (t < 1.0f) { t += Time.deltaTime * rate; obTransform.position = Vector3.Lerp (start, end, t); yield return 0; } }
Обращение: Code StartCoroutine(moveToBySpeed(Твой_трансформ,конечный вектор, скорость);
Передвижение по времени: Code public IEnumerator moveToByTime (Transform obTransform, Vector3 end, float timer) { Vector3 start = obTransform.position; float t = 0.0f; while (t < 1.0f) { t += Time.deltaTime * (1.0f / timer); obTransform.position = Vector3.Lerp (start, end, t); yield return 0; } }
Обращение: Code StartCoroutine(moveToByTime(Твой_трансформ,конечный вектор, время за которое он должен сменить позицию);
ACTORS - мой фреймворк на Unity Until We Die - игра над которой работаю
|
|
| |
ArhipovEvgeniy | Дата: Понедельник, 16 Июля 2012, 17:41 | Сообщение # 8 |
был не раз
Сейчас нет на сайте
| pixeye, спасибо за код Добавлено (16.07.2012, 17:41) --------------------------------------------- Есть 2 класса: 1. RandomVal 2. SmartChangePosition Они находятся в двух разных файлах (но думаю это не особо важно). В классе RandomVal есть tegest.Tag (объект.член). В этом классе ему присваиваются значения. Затем в классе SmartChangePosition нужно вызватьtegest.Tag.
У меня это получается так(в классе SmartChangePosition): RandomVal tegest = new RandomVal(); А потом я хочу значение teggest.Tag использовать так: GameObject Empty = GameObject.FindWithTag(tegest.Tag);
Но значениеtegest.Tag я не получаю. В чём дело. Где ошибка? Debug делал - сказали ошибок нет.
|
|
| |
seaman | Дата: Понедельник, 16 Июля 2012, 18:07 | Сообщение # 9 |
старожил
Сейчас нет на сайте
| 1. Надеюсь RandomVal не наследуется от MonoBehaviour? 2. В конструкторе RandomVal надеюсь поле Tag инициализируется?
|
|
| |
ArhipovEvgeniy | Дата: Понедельник, 16 Июля 2012, 19:20 | Сообщение # 10 |
был не раз
Сейчас нет на сайте
| я вас не понял - слишком сложные слова)) я лучше оба скрипта покажу
Первый
using UnityEngine; using System.Collections;
public class SmartChangePosition : MonoBehaviour { private float dx, dz; //переменные разницы векторов private GameObject Empty, State; //объекты с одноимёнными тегами private Vector3 polozhenie; private Vector3 polozhenieEmpty; void Start () { } void Update () { } void OnMouseDown(){ RandomVal tegest = new RandomVal(); if (Input.GetMouseButton(0)){ Debug.Log ("Нажата");//при нажатии на ЛКМ происходят следующие действия --> GameObject Empty = GameObject.FindWithTag(tegest.Tag); //объекту Empty приписывается один из 16 тегов Empty.renderer.enabled = false; //Делаем объект Empty невидимым Empty.collider.enabled = false; //активируем коллайдер объекта Empty dx = transform.position.x - Empty.transform.position.x; //вычисляем разницу в "Х" координатах между активным объектом и объектом Empty dz = transform.position.z - Empty.transform.position.z; //вычисляем разницу в "Z" координатах между активным объектом и объектом Empty if (dx == -1) //Если разница "Х" получается отрицательной --> dx *= -1; //то преобразуем её в положительную, для того, чтобы не путаться. Расстояние только положительное if (dz == -1) //Если разница "Z" получается отрицательной --> dz *= -1; //то преобразуем её в положительную, для того, чтобы не путаться. Расстояние только положительное if ((dx == 1)&(dz == 0)){ //условие для последующих действий с объектом (кнопкой). Разрешаем передвигать только //соседние объекты рядом с объектом Empty gameObject.tag = "Untagged"; gameObject.tag = "State"; //задаём активному объекту (Кнопке) тег State GameObject State = GameObject.FindWithTag("State"); //вгоняем активный объект с тегом State в переменную polozhenie = State.transform.position; //приравниваем переменную к позиции активного объекта transform.position = Empty.transform.position; //Кнопка становится на позицию "Empty" Empty.transform.position = polozhenie; //невидимый объект Empty переходит на позицию Кнопки //Т.Е. они ПОМЕНЯЛИСЬ местами gameObject.tag = "Untagged"; //удаляем тег активного объекта (Кнопки), чтобы мы могли назначить его другой кнопке. //если в сцене возникнет два объекта с одинаковыми тегами, скрипт будет работать некорректно } if ((dz == 1)&(dx == 0)){ //условие для последующих действий с объектом (кнопкой). Разрешаем передвигать только //соседние объекты рядом с объектом Empty gameObject.tag = "Untagged"; gameObject.tag = "State"; //задаём активному объекту (Кнопке) тег State GameObject State = GameObject.FindWithTag("State"); //вгоняем активный объект с тегом State в переменную polozhenie = State.transform.position; //приравниваем переменную к позиции активного объекта transform.position = Empty.transform.position; //Кнопка становится на позицию "Empty" Empty.transform.position = polozhenie; //невидимый объект Empty переходит на позицию Кнопки //Т.Е. они ПОМЕНЯЛИСЬ местами gameObject.tag = "Untagged"; //удаляем тег активного объекта (Кнопки), чтобы мы могли назначить его другой кнопке. //если в сцене возникнет два объекта с одинаковыми тегами, скрипт будет работать некорректно } } } }
Второй:
using UnityEngine; using System.Collections;
public class RandomVal : MonoBehaviour { public string Tag; void Start () { RandomVal tegest = new RandomVal(); tegest.Tag ="E" + Random.Range(1, 16); } // Update is called once per frame void Update () {
} }
сцена выглядит вот так:
|
|
| |
seaman | Дата: Понедельник, 16 Июля 2012, 21:17 | Сообщение # 11 |
старожил
Сейчас нет на сайте
| Учите программирование - азы. Вот это - Code void Start () { RandomVal tegest = new RandomVal();
tegest.Tag ="E" + Random.Range(1, 16); } полная лажа. 1. экземпляры скриптов унаследованных от MonoBehaviour нельзя делать с помощью new, их делают с помощью Instantiate 2. делать экземпляр скрипта в (по сути дела) конструкторе любым способом - чревато. 3. переменная tegest существует только внутри Start. Естественно Вы ее нигде вне Start не увидите Code gameObject.tag = "Untagged"; gameObject.tag = "State"; //задаём активному объекту (Кнопке) тег State Ну вот логично подумайте - зачем присваивать "Untagged", если тут же присваиваете другое значение?
Похоже вы считает, что если переменные названы одинаково - значит это одна переменная! Это не так! tegest в SmartChangePosition и tegest в RandomVal - это два совершенно разных объекта!
В общем, сорри, но тут нужно просто все переписывать. Может кто-то на форуме и возьмется. А Вам я советую почитать какие-нибудь книги по программированию с нуля.
|
|
| |
ArhipovEvgeniy | Дата: Понедельник, 16 Июля 2012, 22:27 | Сообщение # 12 |
был не раз
Сейчас нет на сайте
| Quote (seaman) А Вам я советую почитать какие-нибудь книги по программированию с нуля так и делаю.
не знаю, быть может вы неправильно поняли, но я второй скрипт вызываю в первом, а не наоборот.
|
|
| |
seaman | Дата: Понедельник, 16 Июля 2012, 23:56 | Сообщение # 13 |
старожил
Сейчас нет на сайте
| Вы прочитали 1-2-3? Что ответите по пунктам? На всякий случай еще раз: 1. нельзя так: Code RandomVal tegest = new RandomVal(); Если скрипт RandomVal определен так: public class RandomVal : MonoBehaviour Почитайте про наследование и справку Юнити, где говорится о том как делать новые экземпляры MonoBehaviour. 2. ладно, хотя я бы все же не делал в Start, тем более в Awake новый экземпляр того же класса. 3. Вы почитайте про области видимости переменных. Та переменная tegest, которую Вы определили внутри Start класса RandomVal видна будет ТОЛЬКО внутри Start (даже в другой функции того же RandomVal Вы ее не увидите!). Соответственно Tag Вы задаете переменной, к которой ниоткуда не сможете обратиться. Та переменная tegest, которую Вы определяете в SmartChangePosition - это вовсе не та же, что была в RandomVal, а совсем другая! Соответственно у нее не определен Tag! Ну так что? Вам хоть что-то из написанного понятно?
Сообщение отредактировал seaman - Понедельник, 16 Июля 2012, 23:57 |
|
| |
ArhipovEvgeniy | Дата: Вторник, 17 Июля 2012, 04:08 | Сообщение # 14 |
был не раз
Сейчас нет на сайте
| Да, теперь намного понятней. Спасибо большое
|
|
| |
|