如何停止克隆中的旋转?

How to stop rotation in clones?

我有一些预制件。每个对象都有一个允许它旋转的脚本 (Script "Rotation")。每次我按下添加到 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 函数停止旋转存在的每个对象(克隆)并具有特定标签(在我的例子中它是 "Log").正如我所写,我做不到。我尝试了一些东西,创建了一个列表,搜索了一个标签,参考了 Rotation 脚本和 运行 协程,但没有任何效果。目前,我没有在停止按钮上添加任何脚本,因为我不知道如何解决它。

一种方法是通过事件。
旋转对象在实例化时订阅事件,您使用按钮调用事件,有效地改变它们的状态。


在您的 Canvas 上的组件下:
(不必直接在你的 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(); }

旋转脚本:
(这个脚本应该在场景中的每个旋转对象上)
(上面的脚本调用了这个 class' 静态方法)

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(),它的性能不如事件。
(Link 到文档:https://docs.unity3d.com/ScriptReference/Object.FindObjectsOfType.html

在您的 Canvas 上的组件下:

// 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);
}