为了账号安全,请及时绑定邮箱和手机立即绑定

在更改新的随机速度之前如何等待秒数?

在更改新的随机速度之前如何等待秒数?

C#
慕田峪7331174 2021-11-07 19:16:33
using System.Collections;using System.Collections.Generic;using UnityEngine;public class GateControl : MonoBehaviour{    public Transform door;    public float doorSpeed = 1.0f;    public bool randomDoorSpeed = false;    [Range(0.3f, 10)]    public float randomSpeedRange;    private Vector3 originalDoorPosition;    // Use this for initialization    void Start()    {        originalDoorPosition = door.position;    }    // Update is called once per frame    void Update()    {        if (randomDoorSpeed == true && randomSpeedRange > 0.3f)        {            StartCoroutine(DoorSpeedWaitForSeconds());        }        door.position = Vector3.Lerp(originalDoorPosition,            new Vector3(originalDoorPosition.x, originalDoorPosition.y, 64f),            Mathf.PingPong(Time.time * doorSpeed, 1.0f));    }    IEnumerator DoorSpeedWaitForSeconds()    {        doorSpeed = Random.Range(0.3f, randomSpeedRange);        yield return new WaitForSeconds(3);    }}在 Update 中使用 StartCoroutine 是一个坏主意。但我希望它在运行游戏时需要一个随机速度,然后等待 3 秒并更改为新的随机速度,然后再等待 3 秒并更改为另一个新的随机速度,依此类推。在等待 3 秒以保持当前速度不变直到下一次更改时。
查看完整描述

3 回答

?
有只小跳蛙

TA贡献1824条经验 获得超8个赞

您已经知道协程应该从Start:


void Start()

{

     //initialization

     StartCoroutine(DoorSpeedWaitForSeconds());

}

因此,使协程成为具有适当终止条件的循环:


IEnumerator DoorSpeedWaitForSeconds()

{

    var delay = new WaitForSeconds(3);//define ONCE to avoid memory leak

    while(IsGameRunning)

    {

        if(randomDoorSpeed == true && randomSpeedRange > 0.3f)

            doorSpeed = Random.Range(0.3f, randomSpeedRange);


        if(!randomDoorSpeed)

            doorSpeed = 1;//reset back to original value


        yield return delay;//wait

    }

}

对于你问的另一个问题,如果你考虑一下,你不可能使用基于 Time.time 的动态速度的乒乓。你需要像这样改变它:


bool isRising = true;

float fraq = 0;

void Update()

{

    if (isRising)

        fraq += Time.deltaTime * doorSpeed;

    else

        fraq -= Time.deltaTime * doorSpeed;


    if (fraq >= 1)

        isRising = false;

    if (fraq <= 0)

        isRising = true;


    fraq = Mathf.Clamp(fraq, 0, 1);



    door.position = Vector3.Lerp(originalDoorPosition,

        new Vector3(originalDoorPosition.x, originalDoorPosition.y, 64f),

        fraq);

}


查看完整回答
反对 回复 2021-11-07
?
犯罪嫌疑人X

TA贡献2080条经验 获得超4个赞

您可以在没有协程的情况下解决原始问题:


public float timeBetweenChangeSpeed = 3f;

public float timer = 0;


void Update ()

{

    // Add the time since Update was last called to the timer.

    timer += Time.deltaTime;


    // If 3 seconds passed, time to change speed

    if(timer >= timeBetweenChangeSpeed)

    {

        timer = 0f;

        //Here you call the function to change the random Speed (or you can place the logic directly)

        ChangeRandomSpeed();

    }


}

还有关于开门和关门。这是我在我参与的迷宫游戏中用来控制门的脚本:


您需要设置空游戏对象以设置边界,即直到您想要将门移动到打开或关闭时的哪一点。您将这个空的游戏对象放置在您的场景中,并将它们链接到正确字段中的脚本。该脚本将自行使用 transform.position 组件。当角色接近时,还有一个触发器输入来激活门。如果你不需要那部分,我明天可以编辑代码。


您还可以使用此脚本移动平台、敌人……一般而言,任何可以直线移动的东西。


using UnityEngine;

using System.Collections;


public class OpenDoor : MonoBehaviour {


    // define the possible states through an enumeration

    public enum motionDirections {Left,Right};

    // store the state

    public motionDirections motionState = motionDirections.Left;


    //Variables for State Machine

    bool mOpening = false;

    bool mClosing = false;


    //bool mOpened = false;


    //OpenRanges to open/close the door

    public int OpenRange = 5;

    public GameObject StopIn;   

    public GameObject StartIn;


    //Variables for Movement

    float SpeedDoor = 8f;

    float MoveTime = 0f;    


    int CounterDetections = 0;



    void Update () {

        // if beyond MoveTime, and triggered, perform movement

        if (mOpening || mClosing) {/*Time.time >= MoveTime && */

            Movement();

        }

    }


    void Movement()

    {

        if(mOpening)

        {

            transform.position = Vector3.MoveTowards(transform.position, StopIn.transform.position, SpeedDoor * Time.deltaTime);


            if(Vector3.Distance(transform.position, StopIn.transform.position) <= 0)

                mOpening = false;


        }else{ //This means it is closing


            transform.position = Vector3.MoveTowards(transform.position, StartIn.transform.position, SpeedDoor * Time.deltaTime);


            if(Vector3.Distance(transform.position, StartIn.transform.position) <= 0)

                mClosing = false;


        }

    }


    // To decide if door should be opened or be closed

    void OnTriggerEnter(Collider Other)

    {

        print("Tag: "+Other.gameObject.tag);


        if(Other.gameObject.tag == "Enemy" || Other.gameObject.tag == "Player" || Other.gameObject.tag == "Elevator")

        {

            CounterDetections++;

            if(!mOpening)

                Opening();

        }       

    }


    void OnTriggerStay(Collider Other)

    {

        if(Other.gameObject.tag == "Elevator")

        {

            if(!mOpening)

                Opening();

        }

    }


    void OnTriggerExit(Collider Other)

    {

        if(Other.gameObject.tag == "Enemy" || Other.gameObject.tag == "Player")

        {

            CounterDetections--;

            if(CounterDetections<1)

                Closing();

        }

    }


    void Opening()

    {

        mOpening = true;

        mClosing = false;

    }


    void Closing()

    {

        mClosing = true;

        mOpening = false;

    }

}


查看完整回答
反对 回复 2021-11-07
?
达令说

TA贡献1821条经验 获得超6个赞

使用计时器并设置间隔。每次达到间隔时都会触发委托事件。

    var t = new Timer {Interval = 3000};
    t.Elapsed += (sender, args) => { /* code here */};


查看完整回答
反对 回复 2021-11-07
  • 3 回答
  • 0 关注
  • 169 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信