Форум программистов, компьютерный форум, киберфорум
Unity, Unity3D
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 5.00/8: Рейтинг темы: голосов - 8, средняя оценка - 5.00
3 / 2 / 1
Регистрация: 03.12.2023
Сообщений: 112
1

Привязка объектов сцены в скрипт на префабе

10.12.2023, 17:49. Показов 1520. Ответов 33

Author24 — интернет-сервис помощи студентам
Всепривет!
Назрел такой вопрос, пока ответа не нашел, лучше спрошу.
На сцене лежит куб, на кубе скрипт- если в радиусе 3 есть объект Игрок (targetObject), можно по нажатии кнопки выполнить перемещение этого объекта в руку (Pickup). targetObject и Pickup я могу указать в инспекторе.
Скрипт тут:
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class BoxPickup3 : MonoBehaviour
{
    public Transform targetObject;
    public Transform Pickup;
    public float interactionRadius;
    public void ToggleOn()
    {
        float distance = Vector3.Distance(transform.position, targetObject.position);
        if (distance <= interactionRadius)
        {
            GetComponent<BoxCollider>().enabled = false;
            GetComponent<Rigidbody>().useGravity = false;
            transform.position = Pickup.position;
            transform.parent = GameObject.Find("Pickup").transform;
        }
    }
    public void ToggleOff()
    {
        transform.parent = null;
        GetComponent<Rigidbody>().useGravity = true;
        GetComponent<BoxCollider>().enabled = true;
    }
}


Суть проблемы в том, что куб находится на сцене и всё нормально работает, но в дальнейшем мне нужно будет сделать так, что бы такие-же новые кубы появлялись на сцене, а значит префаб куба должен уже быть с настроенным скриптом, где указан игрок- targetObject и рука- Pickup.
Т.е. на старте в private void start() указать, что targetObject = модель игрока, Pickup = рука игрока..

Пока вижу только такой вариант- прячу настроенный образцовый куб под карту и клонирую его куда надо.

Добавлено через 33 минуты
Но тогда скрипт работает именно на образцовом кубе.
Кнопка на канвасе в режиме toggle, я туда перетянул образцовый куб и функционал этого скрипта, как быть с клонами куба?
Объединить кубы в стэк и скрипт на стэк- так они все возьмутся
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
10.12.2023, 17:49
Ответы с готовыми решениями:

Не работает скрипт в префабе
Создал скрипт, повесил его на префаб и заметил, что не один из паблик переменных не отображается в...

Фиксация объектов сцены
Как зафиксировать объекты сцены (У меня например TextField и Password field ,ну и кнопки) по...

Удаление объектов со сцены
Привет! Есть сцена, на ней клонируются объекты. Нужно: при нажатию левой кнопки по объекту,...

Auto resize объектов сцены
Здравствуйте форумчане. Пишу 2D игру для андроид и ios и столкнулся с такой проблемой, элементы...

33
39 / 32 / 8
Регистрация: 29.03.2020
Сообщений: 184
10.12.2023, 18:59 2
Не всё понял...
Но можно игрока создать префабом, а в скрипте, который на префабе куба, создать public поля (или [SerializeField] поля) для префабов (игрока и т.д.), и заполнить их в инспекторе.

Добавлено через 7 минут
А нет, так не пойдёт.

Добавлено через 1 минуту
Скорее всего надо использовать поиск по имени или по тегу.
1
3 / 2 / 1
Регистрация: 03.12.2023
Сообщений: 112
10.12.2023, 20:45  [ТС] 3
Я думаю переделать и повесить скрипт на игрока.
Указать в нем куб (опять же конкретный).. Как указать не конкретный куб, а каждый куб, склонированый с префаба куба. Или внутри куба создать какой то объект и к нему цепляться? Но вроде тоже самое будет.
Цитата Сообщение от ПСВ Посмотреть сообщение
Скорее всего надо использовать поиск по имени или по тегу.
Точно, по имени лучше будет, как бы это дело правильно указать?
0
1035 / 252 / 139
Регистрация: 30.07.2022
Сообщений: 1,629
Записей в блоге: 4
10.12.2023, 21:09 4
std847, вы по моему пошли от обратного.
сделайте в руках точку размещения оружия. и пусть player, который знает где его руки, размещает оружие в правильном положении. а не оружие ищет куда бы ему деться.
1
3 / 2 / 1
Регистрация: 03.12.2023
Сообщений: 112
10.12.2023, 21:13  [ТС] 5
Для того, что бы все кубы имели скрипт и можно было с ними взаимодействовать, я к кнопке на канвасе привязал префаб куба.
Получаю ошибку, что нельзя перемещать объекты из префаба
Transform resides in a Prefab asset and cannot be set to prevent data corruption

Добавлено через 2 минуты
FindGameObjectsWithTag
Пробую таГ..)

Добавлено через 1 минуту
Цитата Сообщение от ieretsumi Посмотреть сообщение
оружие ищет куда бы ему деться
Тоже верно..
Игрок и куб поменять местами, скрипт на игрока
0
39 / 32 / 8
Регистрация: 29.03.2020
Сообщений: 184
10.12.2023, 21:36 6
Цитата Сообщение от std847 Посмотреть сообщение
если в радиусе 3 есть объект Игрок (targetObject), можно по нажатии кнопки выполнить перемещение этого объекта
Цитата Сообщение от std847 Посмотреть сообщение
Как указать не конкретный куб, а каждый куб, склонированый с префаба куба
Можно для увеличения радиуса создать дочерний к игроку пустой объект, с большим коллайдером-триггером, и на этот объект повесить скрипт, в котором будет проверка OnTriggerStay на пересечение с кубом по тегу и по нажатию клавиши. А "припариванчие" сделать не к этому объекту, а к родителю.
Только я уже знаю, что инпуты лучше проверять в Update, а вот как проверять коллизию в Update, я не знаю, ieretsumi, подскажи =)
0
3 / 2 / 1
Регистрация: 03.12.2023
Сообщений: 112
10.12.2023, 21:59  [ТС] 7
Цитата Сообщение от ieretsumi Посмотреть сообщение
оружие ищет куда бы ему деться
Проблема, тогда игрок теряет rigidbody и вообще остается на месте. Уже скриптом играл туда-сюда.
Скрипт на игрока, если объект куб на расстоянии до 3, то можно запускать скрипт. Это хорошая задумка. Но при выполнении у куба должен отключаеться rigidbody и collider, т.к. мешает игроку перемещаться, либо уносит игрока черт знает куда при подбирании куба. Теперь скрипт висит на игроке и у игрока отключается это всё

Добавлено через 6 минут
Цитата Сообщение от ПСВ Посмотреть сообщение
Можно для увеличения радиуса
радиус увеличивать не надо и у меня public float interactionRadius можно подстроить в инспекторе. Опытным путем установил- 3 норм

Добавлено через 2 минуты
Цитата Сообщение от std847 Посмотреть сообщение
FindGameObjectsWithTag
Пробую таГ..)
Нельзя Transform использовать с FindGameObjectsWithTag

Добавлено через 1 минуту
Цитата Сообщение от ПСВ Посмотреть сообщение
скрипт, в котором будет проверка OnTriggerStay на пересечение с кубом по тегу
Понял, вы имели ввиду, что все кубы, которые влезут в коллайдер можно будет активировать?
0
39 / 32 / 8
Регистрация: 29.03.2020
Сообщений: 184
10.12.2023, 22:14 8
Ну да, все. Или только ближайший. Можно проверить с помощью Vector3.Distance
0
3 / 2 / 1
Регистрация: 03.12.2023
Сообщений: 112
10.12.2023, 22:16  [ТС] 9
Чуть приподзапутался.. Вернусь немного назад.
На скрине инспектор куба на сцене, в Target Object я перетянул игрока из сцены, в Pickup перетянул руку игрока из сцены.
Если открыть куб в префабе, то со сцены ничего тащить нельзя.
Как это сделать в префабе, чтоб он уже сам искал игрока и руку?
Привязка объектов сцены в скрипт на префабе
0
39 / 32 / 8
Регистрация: 29.03.2020
Сообщений: 184
10.12.2023, 22:24 10
Так обычно не делается, нужно скрипт писать для игрока. Я бы сделал как я уже писал. Сделать пустышку с коллайдером-тригером, и по ней проверять пересечение. Кубу назначить уникальный тег, и по нему проверять.
1
3 / 2 / 1
Регистрация: 03.12.2023
Сообщений: 112
10.12.2023, 22:25  [ТС] 11
Цитата Сообщение от ПСВ Посмотреть сообщение
Я бы сделал как я уже писал.
Понял, согласен, пробую переделать..
Просто у меня тогда у игрока коллайдер и риджит пропадает
0
39 / 32 / 8
Регистрация: 29.03.2020
Сообщений: 184
10.12.2023, 22:46 12
Не должно ничего пропадать. Просто создай дочерним объектом пустышку с коллайдером-триггером и для неё напиши скриптик. Например так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
using UnityEngine;
 
public class TriggerCube : MonoBehaviour
{
    private void OnTriggerStay2D(Collider2D collision)
    {
        if (Input.GetKey(KeyCode.Space) && collision.tag == "Cu") 
        {
            collision.transform.parent = transform.parent;
            //Позиционирование
        }
    }
}
При нажатии на пробел это должно сработать.
У куба должен быть тег Cu.
И коллайдер должен быть Is Trigger.
Только это надо делать в Update, а как проверять коллизию в Update мне и самому интересно.
0
39 / 32 / 8
Регистрация: 29.03.2020
Сообщений: 184
11.12.2023, 10:01 13
Немного не правильно понаписывал.
Во-первых парентить надо не к самому игроку, а к "руке", которую можно добавить, как открытое поле.
Во-вторых, я написал для 2D. Но тут легко поправить.
Ну и лучше использовать GetKeyDown вместо GetKey.
0
3 / 2 / 1
Регистрация: 03.12.2023
Сообщений: 112
11.12.2023, 11:01  [ТС] 14
Цитата Сообщение от ПСВ Посмотреть сообщение
Немного не правильно понаписывал.
Да, уже переделал в 3d..
Рука у меня есть- область пред персонажем, все таки игра от 3 лица, камера закреплена за персонажем.. Обычный комплект анимаций потом переделаю в анимации передвижения с кубом.
А по поводу GetKeyDown\Up, использую канвасную 2х-разовую кнопку ToggleOn\ToggleOff.

Пока оставил как есть, немного переосмыслить надо)

Добавлено через 27 минут
Но в любом случае, как бы ни переделывал на персонажа- у меня пикапалка отпадает. Притягивается к кубу и висит у куба
0
39 / 32 / 8
Регистрация: 29.03.2020
Сообщений: 184
11.12.2023, 11:21 15
Что за пикапалка? Я не в курсе про пикапалку. Мы говорили про руку, она должна быть дочерней к игроку, а куб дочерним к руке.
0
3 / 2 / 1
Регистрация: 03.12.2023
Сообщений: 112
11.12.2023, 11:41  [ТС] 16
Цитата Сообщение от ПСВ Посмотреть сообщение
Что за пикапалка?
На скрине. Pickup- область перед пероснажем, прикреплена к персонажу, по сути рука.
А ящики отдельно лежат.

Сейчас скрипт из первого сообщения висит на персонаже, кнопка на канвасе обращается в этот же скрипт.

Получается по нажатии кнопки рядом с ящиком, этот самый элемент Pickup становится самостоятельным и к ящику трансформится..

Скрин для наглядности
Кликните здесь для просмотра всего текста
Привязка объектов сцены в скрипт на префабе
0
3 / 2 / 1
Регистрация: 03.12.2023
Сообщений: 112
12.12.2023, 22:58  [ТС] 17
Добрый вечер! Пара минут выдалась. Кое что сделал.
На руке тэг Hands;
На коробочке тэг Box;

Скрипт висит на объекте персонажа "Hands".
Как можно объяснить, что GetComponent<BoxCollider>().enabled = false и РБ я хочу сделать ящику, а не рукам.. (20-21 строки)

Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class BoxPickup3 : MonoBehaviour
{
    private Transform targetObject; //ящик
    private Transform Pickup; //рука
    private float interactionRadius = 3; //public float inter...radius без = и 3
    private void Start()
    {
        targetObject = GameObject.FindWithTag("Box").transform; //Таргет назначена коробка по тегу!!!
        Pickup = GameObject.FindWithTag("Hands").transform; //Пикап- руки по тегу!!!
    }
    public void ToggleOn()
    {
        float distance = Vector3.Distance(transform.position, targetObject.position); //проверяем дистанцию до ящика
        if (distance <= interactionRadius) //если дистанция "устраивает"
        { 
            GetComponent<BoxCollider>().enabled = false; //убираем коллайдер на руках. Как это сделать только ящику?
            GetComponent<Rigidbody>().useGravity = false; //убираем РБ на руках. Так-же это надо сделать только ящику
            targetObject.position = transform.position; //ящик идет в руки
            transform.parent = GameObject.Find("Hands").transform; //ящик становится дочерним объектом рук
        }
    }
    public void ToggleOff()
    {
        transform.parent = null;
        GetComponent<Rigidbody>().useGravity = true;
        GetComponent<BoxCollider>().enabled = true;
    }
}


Добавлено через 12 минут
Добил! Теперь ящик идет в руки и не двигается с персонажем

Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class BoxPickup3 : MonoBehaviour
{
    private Transform targetObject; //ящик
    private Transform Pickup; //рука
    private float interactionRadius = 3; //public float inter...radius без = и 3
    private void Start()
    {
        targetObject = GameObject.FindWithTag("Box").transform; //Таргет назначена коробка по тегу!!!
        Pickup = GameObject.FindWithTag("Hands").transform; //Пикап- руки по тегу!!!
    }
    public void ToggleOn()
    {
        float distance = Vector3.Distance(transform.position, targetObject.position);
        if (distance <= interactionRadius)
        {
            GameObject.FindGameObjectWithTag("Box").GetComponent<BoxCollider>().enabled = false;
            GameObject.Find("Box").GetComponent<Rigidbody>().useGravity = false;
            targetObject.position = transform.position;
            //transform.parent = GameObject.Find("Hands").transform;
        }
    }
    public void ToggleOff()
    {
        //transform.parent = null;
        GameObject.FindGameObjectWithTag("Box").GetComponent<BoxCollider>().enabled = true;
        GameObject.Find("Box").GetComponent<Rigidbody>().useGravity = true;
    }
}


Добавлено через 23 минуты
Готово!
Теперь вопрос. Клонировал коробочки, а игрок взаимодействует только с первой коробкой. Всё ищется по тегу, получается берет только первый тег?
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class BoxPickup3 : MonoBehaviour
{
    private Transform targetObject; //ящик
    private Transform Pickup; //рука
    private float interactionRadius = 3; //public float inter...radius без = и 3
    private void Start()
    {
        targetObject = GameObject.FindWithTag("Box").transform; //Таргет назначена коробка по тегу!!!
        Pickup = GameObject.FindWithTag("Hands").transform; //Пикап- руки по тегу!!!
    }
    public void ToggleOn()
    {
        float distance = Vector3.Distance(transform.position, targetObject.position);
        if (distance <= interactionRadius)
        {
            GameObject.FindGameObjectWithTag("Box").GetComponent<BoxCollider>().enabled = false;
            GameObject.FindGameObjectWithTag("Box").GetComponent<Rigidbody>().useGravity = false;
            targetObject.position = transform.position;
            targetObject.transform.parent = Pickup.transform;
            //transform.parent = GameObject.Find("Hands").transform;
            //ShieldModel.transform.parent = PlayerModel.transform
            
        }
    }
    public void ToggleOff()
    {
        targetObject.transform.parent = null;
        GameObject.FindGameObjectWithTag("Box").GetComponent<BoxCollider>().enabled = true;
        GameObject.FindGameObjectWithTag("Box").GetComponent<Rigidbody>().useGravity = true;
    }
}

Может надо как то обратиться к массиву коробок? GameObject.FindGameObjectSWithTag...?
0
39 / 32 / 8
Регистрация: 29.03.2020
Сообщений: 184
12.12.2023, 23:07 18
Именно так =)
Предварительно создай массив, а потом можешь проверять в цикле какая коробка ближе.

Добавлено через 4 минуты
Кстати если этот скрипт на руке, то не надо её искать. И обращаться к ней можно не Pickup.transform, а просто transform.
1
3 / 2 / 1
Регистрация: 03.12.2023
Сообщений: 112
13.12.2023, 17:09  [ТС] 19
Добавлено через 21 секунду
Цитата Сообщение от ПСВ Посмотреть сообщение
Предварительно создай массив
Т.е. create empity, добавить тэг на массив и все коробки удочерить туда?
Разве не будут тогда все коробки смещаться (т.е. как один большой объект)? Пока далеко от компуктора, но уже в предвкушении)

Добавлено через 1 час 22 минуты
Т.к. у меня targetObject = GameObject.FindWithTag("Box").transform;
То получить .transform всех объектов не получится, с GameObject.FindGameObjectSWithTag
0
39 / 32 / 8
Регистрация: 29.03.2020
Сообщений: 184
13.12.2023, 18:11 20
Создать массив:
GameObject[] boxes;

Добавить в него все коробки:
boxes = GameObject.FindGameObjectsWithTag("Box");

В цикле искать ближайшую:
C#
1
2
3
4
for (int i = 0; i < boxes.Length; i++)
{
    //логика перебора
}
Нет, только не массив создаём, а список, протупил.
А в список нельзя записать FindGameObjectsWithTag.
Теперь сам не знаю.
Можно создать большой массив, скажем на 20 элементов, чтоб мало не показалось.
GameObject[] boxes = new GameObject[20];
Но это не слишком хорошо.

Добавлено через 11 минут
Массив нельзя расширять, а список не принимает FindGameObjectsWithTag.

Добавлено через 16 минут
Логика поиска ближайшего ящика:
C#
1
2
3
4
5
6
7
8
9
10
11
float temp = 0f;
for (int i = 0, tempint = 0; i < boxes.Length; i++)
{
    if (temp < Vector3.Distance(transform.position, boxes[i].transform.position))
    {
        temp = Vector3.Distance(transform.position, boxes[i].transform.position);
        tempint = i;
    }
    if (i == boxes.Length) targetObject = boxes[tempint].transform;
}
}
Добавлено через 21 минуту
Короче, не правильно я написал, надо подумать.

Добавлено через 3 минуты
Как-то вот так должно работать:
C#
1
2
3
4
5
6
7
8
9
10
float temp = 10f;
for (int i = 0, tempint = 0; i < boxes.Length; i++)
{
    if (Vector3.Distance(transform.position, boxes[i].transform.position) < temp)
    {
        temp = Vector3.Distance(transform.position, boxes[i].transform.position);
        tempint = i;
    }
    if (i == boxes.Length - 1) targetObject = boxes[tempint].transform;
}
1
13.12.2023, 18:11
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
13.12.2023, 18:11
Помогаю со студенческими работами здесь

Выбор объектов сцены мышью
Есть сцена с шарами. Нужно реализовать возможность выбора шара мышью. Находил примеры, но они...

Видимость объектов сцены и их потомков классами
добрый день, очень надеюсь на вашу помощь. Ситуация следующая: есть два класса Unit и Floor....

Собрать со сцены упорядоченный массив объектов
На сцене есть 14 точек (см. скрин), как их упорядочить в массиве от _targetPoint до...

Как удалять со сцены одновременно несколько объектов?
Мне нужно чтобы по нажатию на кнопку удалялся со сцены одновременно несколько объектов. Как удалить...

Общий скрипт на все сцены
Привет. Надо создавать экземпляр класса с MonoBehaviour, который будет работать на всех сценах без...

Выделение объектов сцены центром экрана посредством камеры
Ку-ку, кодеры! Использую OpenGL 3.3+ c GLFW + GLSL. Пишу это все на C++ в QT Creator. Пишу свою...

Добавление объекта со сцены, на скрипт префаба
Здравствуйте! В создании своего небольшого проекта, я столкнулся с небольшой проблемой, дело в том...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru