avatar

Динамическое изменение размеров объекта в Unity3D (решено)

Спросил ,
Имеется куб, который надо динамически изменять.

Скрипт вешается на сам куб, раз в 10 секунд(например) меняется его размер на новый, случайный( new Vector3(Random.Range(2,10),Random.Range(2,10),Random.Range(2,10)) ).

Как динамически менять размеры? Желательно, пример кода.

36 ответов

avatar
Не проверил, но думаю должно работать:
using UnityEngine;
using System.Collections;

public GameObject go; // Объект, размер которого будем менять (задается в инспекторе)
private float timer = 10.0f; // Ставим таймер на 10 секунд

void Update () {
timer -= 1.0f * Time.deltaTime; // Отнимаем от таймера 1 в секунду
if (timer <= 0.0f) { // Если таймер пришел к нулю
go.transform.localScale = new Vector3(Random.Range(2.0f,10.0f), Random.Range(2.0f,10.0f), Random.Range(2.0f,10.0f)); // Меняем размер объекта
timer = 10.0f; // Снова ставим таймер на 10 секунд
} }
avatar
Вот, я так же проверял, но тут загвоздка в том, что размер меняется мгновенно, а не постепенно.
avatar
В смысле постепенно? Ты спрашивал, как менять раз в 10 секунд.
avatar
Да, но надо постепенно. В данном Вами примером, размер меняется раз в 10 секунд мгновенно, резко, а надо плавно, чтобы было видно и игрок случайно не попал внутрь.
avatar
Всё что у меня получилось:
randomscale.cs
using UnityEngine;
using System.Collections;

public class randomscale : MonoBehaviour {

public GameObject go; // Объект, размер которого будем менять (задается в инспекторе)
private float timer = 10.0f; // Ставим таймер на 10 секунд
private Vector3 scale; // Переменная для текущего размера
private Vector3 newscale; // Переменная для нового размера

void Start () {
scale = new Vector3(go.transform.localScale.x, go.transform.localScale.y, go.transform.localScale.z); // Проверяем текущий размер
newscale = scale;
}

void Update () {
timer -= 1.0f * Time.deltaTime; // Отнимаем от таймера 1 в секунду
go.transform.localScale = Vector3.Lerp(scale, newscale, Time.deltaTime); // Меняем размер объекта

if (timer <= 0.0f) { // Если таймер пришел к нулю
scale = new Vector3(go.transform.localScale.x, go.transform.localScale.y, go.transform.localScale.z); // Проверяем текущий размер
newscale = new Vector3(Random.Range(2.0f,10.0f) , Random.Range(2.0f,10.0f), Random.Range(2.0f,10.0f)); // Задаем новый случайный размер
timer = 10.0f; // Снова ставим таймер на 10 секунд
}
}
}

Но эта часть не работает почему-то правильно:
go.transform.localScale = Vector3.Lerp(scale, newscale, Time.deltaTime); // Меняем размер объекта

Она должна менять размер плавно. Нужно погуглить, как её правильно написать.
avatar
Если найдешь решение, напиши, полезно было бы узнать где косяк.
avatar
Все, получилось!

using UnityEngine;
using System.Collections;

public class changeCube : MonoBehaviour {

    public GameObject go; // Объект, размер которого будем менять (задается в инспекторе)
    private float timer = 10.0f; // Ставим таймер на 10 секунд
    private Vector3 scale; // Переменная для текущего размера
    private Vector3 newscale; // Переменная для нового размера

    void Start()
    {
        scale = new Vector3(go.transform.localScale.x, go.transform.localScale.y, go.transform.localScale.z); // Проверяем текущий размер
        newscale = scale;
    }

    void Update()
    {
        timer -= 1.0f * Time.deltaTime; // Отнимаем от таймера 1 в секунду
        go.transform.localScale = Vector3.Lerp(go.transform.localScale, newscale, Time.deltaTime);
        if (timer <= 0.0f)
        {
            newscale = new Vector3(Random.Range(2.0f, 10.0f), Random.Range(2.0f, 10.0f), Random.Range(2.0f, 10.0f)); // Задаем новый случайный размер
            timer = 10.0f; // Снова ставим таймер на 10 секунд
        }
    }
}


косяк был в том, как я понял, что переменная размера отдельно записывалась, а надо было передавать нынешние размеры объекта, т.е.
go.transform.localScale = Vector3.Lerp(go.transform.localScale, newscale, Time.deltaTime);
avatar
Точно. Переменная scale не обновлялась и по этому Vector3.Lerp застревал на одно месте между scale и newscale…
avatar
Так, теперь проблема есть: игрок все равно проваривается, если стоит на таком кубе. Шаманил с физикой — не помогает, если игрок стоит просто — проваливается при изменении размеров.
avatar
С коллайдером наверное что-то. Попробуй mesh collider вместо box collider.

И ещё попробуй это поменять эти параметры:
Edit -> Project Settings -> Physics -> Min Penetration For Penalty.
Чем это значение меньше, тем точнее коллизии.

Edit -> Project Settings -> Physics -> Solver Iteration Count
Чем это значение выше, тем точнее расчёт коллизий.
Мне это помогло однажды: gamesetup.ru/qa/12.html#comment2992
avatar
Закинь изменение скейла в корутину и жди завершения фрейма. Также может помочь галочка Convex на ригид боди
avatar
А если более простым языком?)
avatar
У тебя объекты с коллайдерами маленькие. Нужно их увеличить или сделать как говорит Fortunato. Вчера сидел и игрался с динамическим изменением в 2D пространстве. Все работало.
avatar
подскажите как сделать чтобы обьект плавно менял масштаб с 0 на 1 за 1 секунду скриптом а не анимацией плизз.и если можно то скрипт попроще
avatar
Попрошайничать не хорошо.
А по теме — помогут матрицы. Матрица масштабирования выглядит так:
[ sx 0 0 ]
[ 0 sy 0 ]
[ 0 0 sz ]
Где sx, sy и sz это scale x, scale y и scale z соответственно
avatar
З.Ы. Забыл сказать, что её неплохо бы расширить ещё, но всё-равно никому это не поможет, так что :D
avatar
ну вопервых я не попрощшайничаю так как тут уже выкладывался скрипт по теме. я просто прошу подсказать как мне сделать плавный переход ведь должна быть функция которая плавно поменяет значение, тем более мне надо тоже сотворить с перемещением обьекта
avatar
gamesetup.ru/qa/22.html#comment4200

Вот решение же, вроде заметно в теме
avatar
мне надо что бы обьект по истечении 21 секунды до 22 секунды плавно изменил масштаб(во втором варианте переместился) с 0 на 1и так и остался.
avatar
Код там прокомментирован, все понятно же, меняйте как Вам надо и пробуйте.
avatar
я как бы типа немного нуб:) Я сделал то что мне надо но через костыли и 2 переменныые типа старый скейл и новый скейл вообщем темболее планого перехода как при анимации не получилось
avatar
Перечитайте комментарий, на который я Вам указал и подумайте еще раз. Там все просто и понятно, я же это понял, когда только столкнулся.
avatar
go.transform.localScale = new Vector3(Random.Range(2.0f,10.0f), Random.Range(2.0f,10.0f), Random.Range(2.0f,10.0f)
всё так как в твоём скрипте только эту строчку надо поменять на чтото типо go.transform.localScale = и функция чтобы плавно изменить маштаб от 0 до 1 за 1 секунду
помоги именно с этой функцией плиззз
просто напиши как надо
avatar
То, что написал ты — генерация нового размера. Ты правильно сформулируй вопрос, не совсем понимаю что ты хочешь.
avatar
есть гейм обджект куб у которого скейл 0. надо чтобы по истечении 21 секунды (в промежутке между 21 и 22 секундой)произошло плавное изменение скейла с 0 до 1ю как вот если б я проанимировал 1 кадр скейл 0 а через секунду кадр со скейлом 1 и при проигрованиии идет плавная смена масштаба.тоже самое мне надо с позицией обьекта.куб с положением 000за 1 секунду плавно переплывает в положение 10,0,0
помоги а то сил уже нет
avatar
и такой вопрос есть куб.как сделать чтобы он был как кнопка и при клике на него мышкой он менял свой скейл на 0 а другой куб(тоже кнопка) приезжал слева например
avatar
using UnityEngine;
using System.Collections;

public class changeCube : MonoBehaviour {

    public GameObject go; // Объект с которым работаем
    private float timer = 21.0f; // Ставим таймер на 21 секунду
	private float iTimer = 1.0f; // таймер для изменения
    private Vector3 scale; // Переменная для текущего размера
    private Vector3 newscale; // Переменная для нового размера
	private Vector3 pos; //начальная позиция
	private Vector3 newpos; //конечная позиция

    void Start()
    {
        scale = new Vector3(0f, 0f, 0f); // 
        newscale = new Vector3(1f, 1f, 1f);
		newpos = new Vector3(10f,0f,0f);
		go.transform.localScale = scale;
    }

    void Update()
    {
        timer -= 1.0f * Time.deltaTime; // Отнимаем от таймера 1 в секунду
		if(timer <= 0)
		{
			nTimer -= 1.0f * Time.deltaTime;
			go.transform.localScale = Vector3.Lerp(go.transform.localScale, newscale, Time.deltaTime);
			go.transform.position = Vectro3.Lerp(go.transform.position, newpos, Time.deltaTime);
		}
    }
}


работоспособность не проверял, сам проверь
avatar
а по проще никак??? просто неужели столько сложностей чтобы масштабировать и двигать обьект??? ладно может у меня подход неправильный?? вообщем общая задача такая: используется НГУИ для создания кнопок.при старте главной менюшки должно отсчитатся 21 секунда и с 21 до 22 секунды кнопка старт должна плавно появится(именно сменой масштаба с 0 до 1), потом при нажатии мышкой или клавиатурой на кнопку старт она должна изменится обратно(сменить масштаб с 1 на 0) и слева и справа должны приехать кнопки НГУИ ньюгейм и екзит соответственно. и кнопочка опции приехать снизу
вот как то так подскажи плиззз
avatar
как я уже говорил, NGUI в помощь, через него что угодно можно сделать. И даже простая менюшка делается не в 2 строчки.
avatar
ссмотри менюшку то я сделал нет проблем а вот с движением проблемы помоги а плз
avatar
С NGUI я не работал особо, забросил пока что его. Читай мануалы, уроки, благо их в сети сейчас полно.
avatar
ну так чё подучиш нубчика в скайпе???
avatar
как правильно пишется функция гет компонент
avatar
Читай официальную документацию.
Только зарегистрированные и авторизованные пользователи могут отвечать на вопросы.