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);
}
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;
}
}
TA贡献1821条经验 获得超6个赞
使用计时器并设置间隔。每次达到间隔时都会触发委托事件。
var t = new Timer {Interval = 3000}; t.Elapsed += (sender, args) => { /* code here */};
- 3 回答
- 0 关注
- 169 浏览
添加回答
举报