[英]How do I make a platform go down after a certain amount of time not colliding with the player object in Unity?
I'm new to Unity and C# in general, so excuse my terminology(or lack thereof)...一般来说,我是 Unity 和 C# 的新手,所以请原谅我的术语(或缺少术语)......
I have succeeded -with the help of a friend, to credit where its due- in making a platform go up a certain amount after one frame of collision with the player, The only problem is that, now.我已经成功 - 在朋友的帮助下,归功于其应得的 - 在与播放器发生一帧碰撞后使平台 go 上升了一定数量,唯一的问题是,现在。 I can't seem to get it moving down again.., Said friend challenged me to make it go up, stay airborne for a certain amount of time.
我似乎无法让它再次下降..,说朋友挑战我让它 go 上升,在空中停留一段时间。 then go back down.
然后 go 退回。
Here is a snippet of my working code that makes it go up.这是我的工作代码片段,它使它成为 go 。
bool HaveCollided = false; //Collision checker boolean
void Update()
{
Vector3 up = lifter * Time.deltaTime;
if (HaveCollided != true || transform.position.y >= 5)
{
return;
}
}
void OnCollisionEnter(Collision collision) //Makes HaveCollided true at collision event
{
if (collision.gameObject.GetComponent<Playertag>() != null) //don't use GetComponent in Update()
{
HaveCollided = true;
}
So if my logic is right, I'd need to nest another if statement inside the one where the condition is: HaveCollided.= true || transform.position.y >= 5
因此,如果我的逻辑是正确的,我需要在条件为的语句中嵌套另一个 if 语句:
HaveCollided.= true || transform.position.y >= 5
HaveCollided.= true || transform.position.y >= 5
which should be: HaveCollided.= true || transform.position.y >= 5
这应该是:
if (newTime == Time.deltaTime * CertainAmount && transform.position.y >= 1) //make platform go down until y position is equal to 1
{
//make platform go down
Debug.Log("reached");
transform.position = transform.position - up;
}
But it's not working.但它不起作用。 It doesn't even seem to reach the part that would make the platform descend.
它甚至似乎都没有达到使平台下降的部分。 I literally do not know where to go from here...
我真的不知道从这里到哪里 go ......
Based on your comment I made a few revisions to make the platform movement a bit smoother.根据您的评论,我进行了一些修改,以使平台运动更加顺畅。 I also made it so the same function can be used for both the upward and downward motion.
我也这样做了,所以同样的 function 可以用于向上和向下运动。
using UnityEngine;
using System.Collections;
[SerializeField] private float timeToMovePlatform = 0.0f; // time it takes the platform to get from 1 point to another
[SerializeField] private float timeToRestAtPeak = 0.0f; // time that the platform rests at the top of its movement
[SerializeField] private float platformYOffset = 0.0f; // offset the platform moves from its origin point to float upward
private Coroutine movingPlatform = null; // determines if the platform is currently moving or not
private void OnCollisionEnter(Collision col)
{
// add a tag to your player object as checking a tag at runtime vs. a GetComponent is faster
if(col.gameObject.tag == "Player")
{
// only trigger when we are not currently moving
if(movingPlatform == null)
{
// start our coroutine so the platform can move
movingPlatform = StartCoroutine(MovePlatform(true));
}
}
}
/// <summary>
/// Moves this object up or down depending on the parameter passed in
/// </summary>
/// <param name="moveUpward">Determines if this object is currently moving upward or not</param>
private IEnumerator MovePlatform(bool moveUpward)
{
// store our start position
Vector3 startPos = transform.position;
// build our goal position based on which direction we are moving
Vector3 goalPos = new Vector3(startPos.x, startPos + (moveUpward ? platformYOffset : -platformYOffset), startPos.z);
// set our current time
float currentTime = 0.0f;
while(currentTime <= timeToMovePlatform)
{
// lerp the position over the current time compared to our total duration
transform.position = Vector3.Lerp(startPos, goalPos, currentTime / timeToMovePlatform);
// update our timer
currentTime += Time.deltaTime;
// need to yield out of our coroutine so it does not get stuck here
yield return null;
}
// just in case there are any floating point issues, set our position directly
transform.position = goalPosition;
// when we are moving upward, make sure to stop at the peak for the set duration
if(moveUpwards)
{
yield return WaitForSeconds(timeToRestAtPeak);
// once we are done waiting, we need to move back downward
StartCoroutine(MovePlatform(false));
}
else
{
// we finished moving downward, so set our coroutine reference to false
// so the player can set the platform to move again
movingPlatform = null;
}
}
Fair warning, I did not test this code it is more a direction I would take for your situation.公平的警告,我没有测试这段代码,这更像是我针对您的情况采取的方向。 Before doing anything, add a tag to your player.
在做任何事情之前,给你的播放器添加一个标签。 If you are unsure what tags are, check out the docs .
如果您不确定标签是什么,请查看文档。 Be sure to give the player the tag Player so that the code will work as expected.
请务必为播放器提供标签Player ,以便代码按预期工作。
You will notice the first three variables are Serialized but are private.您会注意到前三个变量是序列化的,但是是私有的。 By doing this, it allows for Unity to show them in the inspector but not allow other scripts to touch them.
通过这样做,它允许 Unity 在检查器中显示它们,但不允许其他脚本接触它们。
To learn more about Coroutines, check out the docs and for Lerps, I enjoy this blog post .要了解有关协程的更多信息,请查看文档,对于 Lerps,我喜欢这篇博文。 Let me know if this works for you and/or you have any questions.
让我知道这是否适合您和/或您有任何问题。
Your best bet is to add colliders and use isTrigger.最好的办法是添加碰撞器并使用 isTrigger。 Seed a time and if it's not triggered within that time period raise an event.
播种时间,如果在该时间段内未触发,则引发事件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.