Я в шоке, не получается, весь день бьюсь(
using UnityEngine;
using System.Collections;
public class TestScript1 : MonoBehaviour {
//public TestScript2 ts2;
public GameObject go;
public float number1 = 0f;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
number1++;
}
}
второй скрипт на втором объекте
using UnityEngine;
using System.Collections;
public class TestScript2 : MonoBehaviour {
//вариант 1
//public TestScript1 ts1;
//вариант2
public GameObject go;
public float number2 = 0f;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
//вариант1
//number2 = ts1.number1;
//вариант2
number2 = go.GetComponent<TestScript1> ().number1;
Debug.Log (number2);
}
}
Еще пробовал делать геттеры и сеттеры, результат такой же. Короче, мне нужно, чтобы number2 из второго скрипта принимала значение number1 из первого. И все. Сейчас она всегда принимает значение 0 (при этом в первом скрипте я могу написать public float number1 = 9000f;
, и все равно number2 будет 0. Еще во втором скрипте могу запихнуть ее в Start() и сделать number2 = 9000f
или в самом начале public float number2 = 9000f
, и во всех этих случаях она остается равной 0). Что вообще происходит и что я делаю неправильно? и как правильно?
В сами пребафы я запихнул те, которые нужны (в первый - второй, во второй - первый)
После экспериментов расширяю вопрос.
В TestScript2
если сделать так, то number2
становится равной number1
(той number1
, которая была при старте)
void Start () {
//number2 = go.GetComponent<TestScript1> ().number1;
//number2 = ts1.number1;
}
Работает любая из этих строк. Если их запихнуть в void Update ()
, то number2
НЕ изменяется так же, как number1
, она остается той, которая была при старте.
Получается, GameObject1
пытается взять значение у префаба GameObject
, который находится в папке Assets, а не у того, который находится на сцене. Я правильно понял? Если я делаю так, то он берет number1
у GameObject
, который находится на сцене, и number2
меняет свое значение в соответствии с number1
void Update () {
var myObject = GameObject.Find("GameObject0");
number2 = myObject.GetComponent<TestScript1> ().number1;
Debug.Log (number2);
}
Но это ведь плохое решение? var myObject = GameObject.Find("GameObject0");
в void Start ()
не позволяет использовать myObject
в void Update ()
. Плюс, если все же использовать это решение, то возникают очень большие проблемы - у меня будет много объектов со скриптом TestScript1
и столько же объектов с TestScript2
(последние динамически создаются) и мне нужно, чтобы они попарно брали значения друг у друга.
Обновление 2. Я уже ниего не понимаю(( На сцене создал объект со скриптом (CounterManager):
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class CounterManagerScript : MonoBehaviour {
public int maxObjects = 0;
public List<float> counterList; // тут хранятся счетчики
// позиция по Y и "граница" бокс коллайдера по Y
public List<float> objectPositionY;
public List<float> objectBoundsY;
public List<float> stickPositionY;
public List<float> stickBoundsY; // тут нет коллайдера, ее высчитываю по спрайту
public DeliveryStickMoveScript deliveryStick; // сюда засунул объект со скриптом из префаба (палка)
public DeliveryObjectScript deliveryOS; // аналогично, но тут объект ИКС
// тут я присваиваю объектам индексы, так скрипт узнает, куда отправить счетчик
public int counterofObject = -1;
public int counterOfStick = -1;
public void doCounter(){
for (int i = counterOfStick; i < maxObjects; i++)
counterList.Add (stickPositionY[i] - stickBoundsY[i]/2 -
objectPositionY[i] + objectBoundsY[i]/2);
}
}
Теперь как я присваиваю значения:
public class DeliveryStickMoveScript : MonoBehaviour {
public GameObject deliveryObject;
public int indexOfObject = -1;
public bool canMove = true;
public float counter = 0f;
public float objectBoundY = 0f;
public bool canToGive = true;
// суть этого всего - код добавляет значения в List, затем там увеличивает 1 параметр на единицу и присваивает его себе (как бы индекс)
public void Start () {
SpriteRenderer sr = GetComponent<SpriteRenderer> ();
objectBoundY = sr.bounds.size.y;
onScreen = true;
GameObject go = GameObject.Find ("CounterManager");
go.GetComponent<CounterManagerScript> ().stickPositionY.Add (gameObject.transform.position.y);
go.GetComponent<CounterManagerScript> ().stickBoundsY.Add (objectBoundY);
go.GetComponent<CounterManagerScript> ().counterOfStick++;
go.GetComponent<CounterManagerScript> ().maxObjects++;
go.GetComponent<CounterManagerScript> ().doCounter ();
indexOfObject = go.GetComponent<CounterManagerScript> ().counterOfStick;
//if (indexOfObject == go.GetComponent<CounterManagerScript> ().counterOfStick)
counter = go.GetComponent<CounterManagerScript> ().counterList [indexOfObject];
//counter = go.GetComponent<CounterManagerScript> ().objectPositionY [indexOfObject];
}
public void Update () {
if (canMove) {
counter -= 1 * Time.deltaTime;
if (counter >=0)
gameObject.transform.position = new Vector3 (gameObject.transform.position.x,
gameObject.transform.position.y - 1 * Time.deltaTime,
gameObject.transform.position.z);
else
gameObject.transform.position = new Vector3 (gameObject.transform.position.x,
gameObject.transform.position.y + 1 * Time.deltaTime,
gameObject.transform.position.z);
}
}
}
И первый объект (выше был второй): public class DeliveryObjectScript : MonoBehaviour {
public int indexOfObject = -1;
public Transform deliveryStick;
private bool canCreateStick = true;
public bool startCounter = false; // запустить таймер
public float objectBoundY = 0f;
public float counter = 0f;
public bool onScreen = false; // если true, то CounterManager возьмет параметры
// суть этого всего - код добавляет значения в List, затем там увеличивает 1 параметр на единицу и присваивает его себе (как бы индекс)
public void giveParams(){
GameObject go = GameObject.Find ("CounterManager");
go.GetComponent<CounterManagerScript> ().objectPositionY.Add (gameObject.transform.position.y);
go.GetComponent<CounterManagerScript> ().objectBoundsY.Add (objectBoundY);
go.GetComponent<CounterManagerScript> ().counterofObject++;
//go.GetComponent<CounterManagerScript> ().doCounter ();
indexOfObject = go.GetComponent<CounterManagerScript> ().counterofObject;
//if (indexOfObject == go.GetComponent<CounterManagerScript> ().counterofObject)
counter = go.GetComponent<CounterManagerScript> ().counterList [indexOfObject];
//counter = go.GetComponent<CounterManagerScript> ().stickPositionY [indexOfObject];
onScreen = true;
}
// Use this for initialization
void Start () {
SpriteRenderer sr = GetComponent<SpriteRenderer> ();
objectBoundY = sr.bounds.size.y;
}
// Update is called once per frame
public void Update () {
if (gameObject.GetComponent<ObjectChooserScript> ().canMove == true) {
gameObject.GetComponent<Rigidbody>().useGravity = false;
gameObject.GetComponent<BoxCollider>().enabled = false;
if (canCreateStick) {
Instantiate(deliveryStick, new Vector3(gameObject.transform.position.x
,20
, gameObject.transform.position.z),
Quaternion.identity);
canCreateStick = false;
if (canCreateStick == false && onScreen == false)
giveParams();
startCounter = true;
}
if (startCounter)
counter -= 1 * Time.deltaTime;
if (counter <=0)
gameObject.transform.position = new Vector3(
gameObject.transform.position.x,
gameObject.transform.position.y + 1 * Time.deltaTime,
gameObject.transform.position.z);
}
}
}
В общем, это дичайшая дичь. Тут он мне выдает ArgumentOutOfRangeException: Argument is out of range.
в DeliveryObjectScript.giveParams () (at Assets/Scripts/DeliveryObjectScript.cs:25)
DeliveryObjectScript.Update () (at Assets/Scripts/DeliveryObjectScript.cs:63)
. Но самое интересное, что в CounterManager юнити мне показывает, что все параметры принимаются. А, похоже, что DeliveryObjectScript
"не видит" значения DeliveryStick
, замена counter = go.GetComponent<CounterManagerScript> ().counterList [indexOfObject];
на counter = go.GetComponent<CounterManagerScript> ().stickPositionY [indexOfObject];
выдает тот же результат, а вот наоборот все норм (т.е палка все видит)
получается, GameObject1 пытается взять значение у префаба GameObject, который находится в папке Assets, а не у того, который находится на сцене. Я правильно понял?
Да. Так ты хранишь ссылку на префаб, а не на объект на сцене. Изначально нужно продумать логику нахождения нужного тебе объекта при инициализации. Из твоего скрипта:
TestScript1 myObject;
void Update () {
if(myObject == null)
myObject = GameObject.Find("GameObject0").GetComponent<TestScript1> ();
number2 = myObject.number1;
Debug.Log (number2);
}
Или:
void Start () {
myObject = GameObject.Find("GameObject0").GetComponent<TestScript1> ();
}
Но не безопасно искать по имени, так как объектов может быть много и у него скорей всего будет окончание (Clone). Нужно реализовать поиск иначе.
ЗдравствуйтеСоздал хранимую процедуру для более быстрого получения списка друзей(для 25 пользователей одновременно) и записи их ID в массив
Есть сервер, у которого 20-30 активных подключенийИ одно подключение к другому серверу(машина куда надо отправлять обработанные данные)
Необходимо получить звук с микрофона, выводя его частоту и громкость в данный момент