Как установить разные переменные значения для каждого игрового объекта, используя один и тот же скрипт в Unity3d

Я новичок в Unity и пытаюсь создать три разных объекта с одним скриптом и установить переменную value для каждого экземпляра.

Я перетащил скрипт к трем объектам в моей сцене и установил из переменной значения слотов единства пользовательского интерфейса разные значения для каждого объекта!

Текущий код выглядит так:

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


public class DragBall : MonoBehaviour {

    public GameObject gameObjectToDrag;
    public Text txt;


    public int value;

    public Vector3 GOcenter;
    public Vector3 touchPosition;
    public Vector3 offset;
    public Vector3 newGOcenter;

    RaycastHit hit;

    public bool draggingMode = false;

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {
        if (Input.GetMouseButtonDown(0)) {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            if (Physics.Raycast(ray, out hit))
            {
                gameObjectToDrag = hit.collider.gameObject;
                GOcenter = gameObjectToDrag.transform.position;
                touchPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
                offset = touchPosition - GOcenter;
                draggingMode = true;
            }
        }

        if (Input.GetMouseButton(0)) {
            if (draggingMode) {
                touchPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
                newGOcenter = touchPosition - offset;
                gameObjectToDrag.transform.position = new Vector3(newGOcenter.x, 3, newGOcenter.z); // 0 means Y axis , so let the ball go horizontally only
            }
        }

        if (Input.GetMouseButtonUp(0)) {
            draggingMode = false;
        }

        Debug.Log(this.value);
        txt.text = this.value + "";
    }
}

Отредактированный код:

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


public class DragBall : MonoBehaviour {

    public GameObject gameObjectToDrag;

    public Text txt;

    public Vector3 GOcenter;
    public Vector3 touchPosition;
    public Vector3 offset;
    public Vector3 newGOcenter;

    RaycastHit hit;

    public int value;

    public bool draggingMode = false;

    // Use this for initialization
    void Start () {
        if (this.gameObjectToDrag.name == "Ball1")
        {
            this.value = 1;
        }
        else if (this.gameObjectToDrag.name == "Ball2")
        {
            this.value = 2;
        }
        else if (this.gameObjectToDrag.name == "Ball3")
        {
            this.value = 3;
        }
    }

    // Update is called once per frame
    void Update () {

        if (Input.GetMouseButtonDown(0)) {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            if (Physics.Raycast(ray, out hit))
            {
                this.gameObjectToDrag = hit.collider.gameObject;
                GOcenter = this.gameObjectToDrag.transform.position;
                touchPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
                offset = touchPosition - GOcenter;
                draggingMode = true;
            }
        }

        if (Input.GetMouseButton(0)) {
            if (draggingMode) {
                touchPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
                newGOcenter = touchPosition - offset;

                if (this.gameObjectToDrag.name == "Ball1") {
                    this.gameObjectToDrag.transform.position = new Vector3(newGOcenter.x, 1, newGOcenter.z); // 0 means Y axis , so let the ball go horizontally only
                }
                else if (this.gameObjectToDrag.name == "Ball2")
                {
                    this.gameObjectToDrag.transform.position = new Vector3(newGOcenter.x, 2, newGOcenter.z); // 0 means Y axis , so let the ball go horizontally only
                }
                else if (this.gameObjectToDrag.name == "Ball3")
                {
                    this.gameObjectToDrag.transform.position = new Vector3(newGOcenter.x, 3, newGOcenter.z); // 0 means Y axis , so let the ball go horizontally only
                }

            }
            txt.text = this.value + "";
        }

        if (Input.GetMouseButtonUp(0)) {
            draggingMode = false;
        }
    }
}

Я хотел бы, чтобы для каждого объекта, к которому я прикасаюсь мышью, отображалась переменная текущего значения. Сейчас показывает 0 для всех.

Должен ли я создавать разные сценарии для каждого объекта и назначать сценарий каждому объекту отдельно? это не просто звучит правильно для меня, не знаю почему, но что-то должно быть!


person Mizlul    schedule 29.03.2018    source источник


Ответы (2)


Вы не инициализировали переменную value, поэтому она становится 0 при присоединении к 3 объектам. Даже если вы инициализируете его числом, оно все равно будет таким в каждом экземпляре.

Вам нужен способ инициализировать переменную значения для каждого GameObject. Для этого вам также нужен способ отличить каждый из GameObject. Это можно сделать, сравнив текущее имя GameObject, тега, слоя или экземпляра GameObject.

В приведенном ниже примере используется имя GameObject для инициализации переменной value в функции Start. Допустим, они называются «Obj1», «Obj2» и «Obj3»:

void Start()
{
    //Use 1 for Object 1
    if (this.gameObject.name == "Obj1")
    {
        value = 1;
    }
    //Use 3 for Object 2
    else if (this.gameObject.name == "Obj2")
    {
        value = 2;
    }
    //Use 3 for Object 3
    else if (this.gameObject.name == "Obj3")
    {
        value = 3;
    }
}
person Programmer    schedule 29.03.2018
comment
Я добавил именно так, как вы сказали, все еще не работает, теперь я сомневаюсь, правильно ли я настроил скрипт для каждого объекта, ну, что я и сделал, я просто перетащил файл скрипта на каждый объект и присвоил каждому объекту gameObjectToDrag и установил значение переменная разная для каждого объекта, все равно без разницы - person Mizlul; 29.03.2018
comment
Это очень просто сделать. Почему бы не сделать скриншоты каждого из трех игровых объектов, а затем опубликовать ссылки здесь, в разделе комментариев. Я хочу взглянуть на это. Также сделайте еще один снимок экрана журнала вкладки «Консоль», который показывает, что он все еще показывает 0. Наконец, обновите свой вопрос и отредактируйте его, а затем включите новый код, который показывает вашу реализацию из моего ответа. Не удаляйте исходный код. Просто добавьте EDIT + ваш новый код. Вы делаете что-то не так, но мне нужно это, чтобы понять, что это такое. - person Programmer; 29.03.2018
comment
Я думаю, что вы правы, мне просто нужно было переместить ваш код в метод update(), чтобы теперь я мог видеть, что текстовая метка меняется на значение в зависимости от того, какой объект я перетаскиваю! Я проверю ваш ответ как правильный! Спасибо за помощь в этом1 - person Mizlul; 29.03.2018
comment
Это лучше в функции Start, иначе вы столкнетесь с проблемами, когда попытаетесь изменить ее позже, потому что функция Update будет продолжать работать. Этот код должен запускаться один раз. Рад, что у вас все заработало! - person Programmer; 29.03.2018
comment
Я получаю, когда это переместилось в start () UnassignedReferenceException: переменная gameObjectToDrag DragBall не была назначена. Вероятно, вам нужно назначить переменную gameObjectToDrag скрипта DragBall в инспекторе. DragBall.Start() (в Assets/Scripts/DragBall.cs:26) - person Mizlul; 29.03.2018
comment
Это Start, а не start. - person Programmer; 29.03.2018
comment
извините, на самом деле это уже Start (), но та же ошибка сообщения, похоже, что что-то нужно инициализировать, прежде чем я буду использовать gameObjectToDrag - person Mizlul; 29.03.2018
comment
Это совершенно другая проблема, которая не имеет ничего общего с вашим первоначальным вопросом. Я предлагаю вам создать новый вопрос с вашим последним кодом. Также дважды щелкните по ошибке, и вы перейдете к строке кода, вызывающей эту ошибку. Покажите также код этой строки кода, и я посмотрю, смогу ли я ответить на это. Я просто не хочу перетаскивать это в другую тему. - person Programmer; 29.03.2018
comment
на самом деле это строка: if (this.gameObjectToDrag.name == Ball1) { this.value = 1; } - person Mizlul; 29.03.2018
comment
добавит отдельный вопрос для этого! большое спасибо! - person Mizlul; 29.03.2018
comment
Вам не нужно создавать новый вопрос, если у вас нет дополнительных вопросов или этот комментарий, который я собираюсь сделать, не решил его. Заключите три похожих утверждения if (this.gameObjectToDrag.name == "Ball1") { this.value = 1; } в if(this.gameObjectToDrag != null). Это гарантирует, что gameObjectToDrag не является null перед использованием this.gameObjectToDrag.name.... - person Programmer; 29.03.2018

Если вы установите другое значение в инспекторе, этот скрипт должен работать и показывать другое число в вашем журнале. Я вижу, что вы запускаете txt.text = this.value каждое обновление. Если у вас есть одно текстовое поле, подключенное ко всем экземплярам вашего мяча, оно всегда будет показывать одно и то же значение. Если вы хотите, чтобы в текстовом поле отображался текущий перетаскиваемый мяч, вы должны поместить эту строку кода в свой оператор if следующим образом:

    if (Input.GetMouseButtonDown(0)) {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray, out hit))
        {
            //Add line here
            txt.text = this.value + "";
            gameObjectToDrag = hit.collider.gameObject;
            GOcenter = gameObjectToDrag.transform.position;
            touchPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            offset = touchPosition - GOcenter;
            draggingMode = true;
        }
    }

Если вы установили это значение по-разному для каждого мяча, оно должно работать.

введите здесь описание изображения

person Steffan Venema    schedule 29.03.2018