Как остановить ротацию в клонах?

У меня есть несколько сборных. У каждого объекта есть скрипт, позволяющий его вращать (Скрипт "Вращение"). Я пытаюсь остановить на несколько секунд скорость вращения в моих объектах-клонах каждый раз, когда я нажимаю кнопку, которую я добавил на главный экран моей сцены в Unity. думаю, что лучшим решением было бы найти каждый объект с определенным тегом (все клоны имеют один и тот же тег). После нажатия кнопки каждый объект с указанным тегом должен остановиться. К сожалению, это не работает с объектами, являющимися клонами... Кто-нибудь может решить мою проблему?

У каждого клона есть скрипт ротации:

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

public class Rotation : MonoBehaviour {

    public float speed;
    public float speed2 = 0f;
    private Rigidbody2D rb2D;


    // Use this for initialization
    void Start () {

    }

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

        transform.Rotate (0, 0, speed);
    }

    public void Stop (){

        StartCoroutine(SpeedZero());
        Debug.Log ("ZEROOOOO");
    }

    IEnumerator SpeedZero()
    {
        transform.Rotate (0, 0, speed2);
        yield return new WaitForSeconds(20);
        transform.Rotate (0, 0, speed);

    }
}

Объекты создаются с помощью скрипта SunSpawner:

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

public class SunSpawner : MonoBehaviour {


    public GameObject[] theSuns;
    public Transform generationPoint;


    private int sunSelector;
    private float sceneHeight;

    float distance = 0.5f;


    Vector3 maxWidthPoint;
    Vector3 minWidthPoint;

    //Radious base on circle collider radious
    float lastSunRadious = 2f;

    public void Update (){

        if (transform.position.y < generationPoint.position.y) {

            sunSelector = Random.Range(0, theSuns.Length);
            float currentSunRadious = theSuns[sunSelector].GetComponentInChildren<CircleCollider2D>().radius * theSuns[sunSelector].GetComponentInChildren<CircleCollider2D>().transform.localScale.x * theSuns[sunSelector].transform.localScale.x;
            float distanceBetween = distance + lastSunRadious + currentSunRadious; //Random.Range(lastSunRadious+currentSunRadious, sceneHeight);
            float sunXPos = Random.Range(minWidthPoint.x + currentSunRadious, maxWidthPoint.x - currentSunRadious);

            Vector3 newSunPosition = new Vector3(sunXPos, transform.position.y + distanceBetween, transform.position.z);

            transform.position = newSunPosition;
            lastSunRadious = currentSunRadious;
            Instantiate (theSuns [sunSelector], transform.position, transform.rotation);

        }
    }
}

Теперь я добавил Canvas и кнопку, в которой я хотел использовать функцию OnClick для остановки вращения в каждом объекте (клоне), который существует и имеет определенный тег (в моем случае это «Журнал»). Как я уже писал, я не могу этого сделать. Я пробовал несколько вещей: создать список, найти тег, обратиться к скрипту Rotation и запустить сопрограмму, но ничего не работает. В настоящее время у меня нет скрипта, добавленного к кнопке остановки, потому что я не знаю, как это решить.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Один из способов сделать это — через События.
Вращающиеся объекты подписываются на событие в тот момент, когда они создаются, и вы используете свои кнопки для вызова события, эффективно изменяя их состояние.


Под компонентом на холсте:
(Он не обязательно должен находиться прямо под вашим Canvas GameObject, но где угодно в вашем коде. Важно вызывать методы)

// Call these methods from your onClick from the appropriate button.
// For example the Stop button should call StopClonesRotation().
public void StopClonesRotation() { Rotation.StopRotating(); }
public void StartClonesRotation() { Rotation.StartRotating(); }

Скрипт вращения:
(Этот скрипт должен быть на каждом вращающемся объекте в вашей сцене)
(Сценарий выше вызывает статические методы этого класса)

public delegate void RotateAction();
public static event RotateAction StopRotating;
public static event RotateAction StartRotating;

RotateAction startAction;
RotateAction endAction;

public float Speed;
bool shouldRotate = true;


private void Awake() {
    startAction = () => shouldRotate = true;
    endAction = () => shouldRotate = false;
}
void OnEnable() {
    StartRotating += startAction;
    StopRotating += endAction;
}
void OnDisable() {
    StartRotating -= startAction;
    StopRotating -= endAction;
}

void Update () {
   if (!shouldRotate) { return; }
   transform.Rotate (0, 0, Speed);
}

Другой способ сделать это — FindObjectsOfType(), который менее эффективен, чем Events.
(Ссылка на документы: https://docs.unity3d.com/ScriptReference/Object.FindObjectsOfType.html)
Ты

Под компонентом на холсте:

// Call these methods from your onClick from the appropriate button.
// For example the Stop button should call StopClonesRotation().
public void StopClonesRotation() { 
   var allRotatingObjects = FindObjectsOfType<Rotation>();
   foreach (var rotatingObj in allRotatingObjects) { rotatingObj.shouldRotate = false; }
}
public void StartClonesRotation() { 
   var allRotatingObjects = FindObjectsOfType<Rotation>();
   foreach (var rotatingObj in allRotatingObjects) { rotatingObj.shouldRotate = true; }
}

Скрипт вращения:
(Этот скрипт должен быть на каждом вращающемся объекте в вашей сцене)

public float Speed;
bool shouldRotate = true;

void Update () {
   if (!shouldRotate) { return; }
   transform.Rotate (0, 0, Speed);
}

Примечание: Как удалить обработчик лямбда-событий

Draco18s no longer trusts SE 21.07.2019 20:56

Спасибо. Не был уверен, что это сработает с прямой отпиской лямбд, но был уверен, что кто-нибудь это заметит :) Отредактировал ответ для работы с кешированным действием.

Lyrca 22.07.2019 11:13

Я столкнулся с вопросом о лямбда-событии через несколько минут после прочтения вашего ответа, иначе я бы не заметил. :P Интеллектуально я знаю о проблеме с лямбдой, я просто не заметил.

Draco18s no longer trusts SE 22.07.2019 16:34

Другие вопросы по теме