Среда, 04 Декабря 2024, 22:31

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

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
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, спасибо за код smile

Добавлено (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)
А Вам я советую почитать какие-нибудь книги по программированию с нуля

так и делаю.

не знаю, быть может вы неправильно поняли, но я второй скрипт вызываю в первом, а не наоборот. biggrin
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
был не раз
Сейчас нет на сайте
Да, теперь намного понятней. Спасибо большое biggrin
  • Страница 1 из 1
  • 1
Поиск:

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