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

public class Waypoints : MonoBehaviour
{
    [Header("Objects To Move")]
    public Transform objectToMovePrefab;
    public int numberOfObjectsToMove = 1;

    [Header("Speed")]
    public float speed;
    public bool randomSpeed = false;
    public float minRandomSpeed = 1;
    public float maxRandomSpeed = 100;
    private bool changeSpeedOnce = false;
    private bool currentSpeedState;

    [Header("Waypoints")]
    [SerializeField] private List<Transform> waypoints;

    [Header("Delay")]
    public bool useDelay = false;
    public float delay = 3;
    public bool randomDelay = false;
    public float minRandomDelay = 0.3f;
    public float maxRandomDelay = 5;

    [Header("LineRenderer")]
    public LineRenderer lineRenderer;
    public bool moveOnLineRenderer = false;
    public List<Vector3> lineRendererPositions = new List<Vector3>();

    [Header("Cinemachine Cameras")]
    public CinemachineVirtualCamera virtualCamera;

    private List<WaypointsFollower> waypointsFollowers = new List<WaypointsFollower>();

    private void Start()
    {
        currentSpeedState = changeSpeedOnce;

        for (int i = 0; i < numberOfObjectsToMove; i++)
        {
            var parent = GameObject.Find("Moving Object Parent");
            var objectToMove = Instantiate(objectToMovePrefab, parent.transform);
            objectToMove.name = "Platfrom";

            waypointsFollowers.Add(objectToMove.GetComponent<WaypointsFollower>());
        }

        virtualCamera.Follow = waypointsFollowers[0].gameObject.transform;
        virtualCamera.LookAt = waypointsFollowers[0].gameObject.transform;

        foreach (Transform wp in waypoints)
        {
            lineRendererPositions.Add(wp.position);
        }

        if (moveOnLineRenderer)
        {
            foreach (WaypointsFollower wpf in waypointsFollowers)
            {
                wpf.go = true;
            }
        }

        SpeedUpdater();

        if (useDelay)
            StartCoroutine(SendObjectstomoveWithDelay());
    }

    private void Update()
    {
        lineRendererPositions.Clear();
        lineRendererPositions.AddRange(GetLinePointsInWorldSpace());

        SpeedUpdater();
    }

    public int Count => waypoints.Count;
    public Vector3 GetWaypoint(int index)
    {
        return waypoints[index].position;
    }

    public int CountLR => lineRendererPositions.Count;
    public Vector3 GetLRWaypoint(int index)
    {
        return lineRendererPositions[index];
    }

    IEnumerator SendObjectstomoveWithDelay()
    {
        {
            foreach (WaypointsFollower follower in waypointsFollowers)
            {
                if (randomDelay)
                {
                    delay = Random.Range(minRandomDelay, maxRandomDelay);
                }

                yield return new WaitForSeconds(delay);

                follower.go = true;
            }
        }
    }

    private void SpeedUpdater()
    {
        foreach (WaypointsFollower follower in waypointsFollowers)
        {
            if (randomSpeed)
            {
                follower.speed = Random.Range(minRandomSpeed, maxRandomSpeed);
            }
            else
            {
                follower.speed = speed;
            }
        }
    }

    Vector3[] GetLinePointsInWorldSpace()
    {
        var positions = new Vector3[lineRenderer.positionCount];
        //Get the positions which are shown in the inspector 
        lineRenderer.GetPositions(positions);


        //the points returned are in world space
        return positions;
    }
}

SpeedUpdtaer 内でフラグを使用していますが、実行時にもフラグを変更できるようにしたいと考えています。問題は、Update で SpeedUpdater を呼び出すと、フレームごとに foreach ループが発生し、List waypointsFollowers に多くのアイテムが存在する可能性があるため、コストがかかる可能性があることです。

遅延部分については、実行時に useDelay フラグを変更すると、その瞬間から各移動オブジェクトが次のウェイポイントに到達し、そこから遅延が機能し始めます。実行時に useDelay フラグを false に変更し、次のウェイポイントで待機しない場合も同様です。

遅延は正常に機能していますが、今のところ開始のみであり、SpeedUpdater も正常に機能していますが、フレームごとに foreach を作成することが良い方法であるかどうかはわかりません。作成方法と、各フレームをループさせずに実行時に速度と速度ランダムフラグを変更できるコードがどこにあるかわかりません。

4

1 に答える 1

1

プロパティを使用します。プロパティを使用すると、変数値セットで追跡でき、条件付きまたは値の変更時に次のようなロジックを実行できます (チェックをコンパイルしませんでした)。

private bool useDelay = false;
public bool UseDelay { get => useDelay; set {
useDelay = value;
if (useDelay)
    StartCoroutine(SendObjectstomoveWithDelay()); 
}};
private bool randomDelay = false;
public bool RandomDelay { get => randomDelay; set {
SpeedUpdater(value);
randomDelay = value;
}};

そのためにSpeedUpdater()、ブール引数を受け入れるものも作成します。

private void SpeedUpdater(bool randomSpeedArgument)
    {
        foreach (WaypointsFollower follower in waypointsFollowers)
        {
            if (randomSpeedArgument)
            {
                follower.speed = Random.Range(minRandomSpeed, maxRandomSpeed);
            }
            else
            {
                follower.speed = speed;
            }
        }
    }

私はあなたの質問の論理に順応することにあまり注意を払っていませんでした. サンプル コードは、値の取得/設定でロジックを実行する方法を示すためのものです。他の方法はイベントであり、もう少し複雑なオプションであり、この場合にはあまり必要ではないと思います。ドキュメントを読むことができます

于 2021-05-13T07:36:55.697 に答える