Home > Net >  How can I change the moving objects speed at runtime?
How can I change the moving objects speed at runtime?

Time:11-10

The manager script

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

public class DronesManager : MonoBehaviour
{
    public GameObject target;
    public float movementSpeed;
    public float launchTime;

    public Transform dronesUnchild;

    private List<GameObject> drones = new List<GameObject>();
    private float currentDroneSpeed;

    private void Awake()
    {
        currentDroneSpeed = movementSpeed;
    }

    // Start is called before the first frame update
    void Start()
    {
        target = GameObject.Find("Base");

        drones = GameObject.FindGameObjectsWithTag("Drone").ToList();

        StartCoroutine(MoveDrone());
    }

    // Update is called once per frame
    void Update()
    {
        if(currentDroneSpeed != movementSpeed)
        {
            for(int i = 0; i < drones.Count; i  )
            {
                var droneControl = drones[i].GetComponent<DroneControl>();

                droneControl.movingSpeed = movementSpeed;
            }

            currentDroneSpeed = movementSpeed;
        }
    }

    private IEnumerator MoveDrone()
    {
        // same as you did:
        drones = GameObject.FindGameObjectsWithTag("Drone").ToList();

        foreach(var drone in drones)
        {
            drone.GetComponent<DroneControl>().target = target.transform;
        }

        while (drones.Count > 0)
        {
            // pick one at random, get it
            int index = Random.Range(0, drones.Count);
            var drone = drones[index];

            // remove it from list
            drones.RemoveAt(index);

            // TODO: might want to check/guard if drone == null ... this guards against it
            // being Destroy()ed and yet still lying around in our list marked as "dead"

            // simplified your get-component-and-go-if-not-already-going code here
            var droneControl = drone.GetComponent<DroneControl>();
            if (droneControl.go == false)
            {
                droneControl.movingSpeed = movementSpeed;
                droneControl.go = true;
                drone.transform.parent = dronesUnchild;
            }

            // wait
            yield return new WaitForSeconds(launchTime);
        }
    }
}

I tried to add this part in the Update

void Update()
    {
        if(currentDroneSpeed != movementSpeed)
        {
            for(int i = 0; i < drones.Count; i  )
            {
                var droneControl = drones[i].GetComponent<DroneControl>();

                droneControl.movingSpeed = movementSpeed;
            }

            currentDroneSpeed = movementSpeed;
        }
    }

and this script is attached to each moving object

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

public class DroneControl : MonoBehaviour
{
    public Transform target;
    public float turnSpeed = .01f;

    Quaternion rotGoal;
    Vector3 direction;
    public float movingSpeed;
    public bool go = false;

    private bool waitBeforeRotate = false;
    private bool startRotating = false;

    #region AddedCode
    public float targetRange = 1.0f;

    private bool IsTargetReached(Vector3 dronePos, Vector3 targetPos)
    {
        var distance = Vector3.Distance(dronePos, targetPos);
        return distance < targetRange;
    }
    #endregion AddedCode

    // Update is called once per frame
    void Update()
    {
        // next line is modified to incorporate the range check
        if (go && !IsTargetReached(transform.position, target.position))
        {
            transform.position  = transform.forward * movingSpeed * Time.deltaTime;

            if (waitBeforeRotate == false)
            {
                StartCoroutine(StartRotating());

                waitBeforeRotate = true;
            }

            if (startRotating)
            {
                direction = (target.position - transform.position).normalized;
                rotGoal = Quaternion.LookRotation(direction);
                transform.rotation = Quaternion.Slerp(transform.rotation, rotGoal, turnSpeed);
            }
        }
    }

    IEnumerator StartRotating()
    {
        yield return new WaitForSeconds(3f);

        startRotating = true;
    }
}

but it's never change the speed of moving objects.

if the speed of each moving object in the editor start is 5 for example and in the manager script I change the speed to 100 the speed of each object is still 5.

CodePudding user response:

Maybe this is happening because after picking a random drone in IEnumerator you instantly remove it from the list?

So in Update() you set a speed for all drones, except the ones that are already moving.

  • Related