繁体   English   中英

如何在一定时间后不与 Unity 中的播放器 object 发生碰撞后使平台 go 下降?

[英]How do I make a platform go down after a certain amount of time not colliding with the player object in Unity?

一般来说,我是 Unity 和 C# 的新手,所以请原谅我的术语(或缺少术语)......

我已经成功 - 在朋友的帮助下,归功于其应得的 - 在与播放器发生一帧碰撞后使平台 go 上升了一定数量,唯一的问题是,现在。 我似乎无法让它再次下降..,说朋友挑战我让它 go 上升,在空中停留一段时间。 然后 go 退回。

这是我的工作代码片段,它使它成为 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;
        }

因此,如果我的逻辑是正确的,我需要在条件为的语句中嵌套另一个 if 语句: HaveCollided.= true || transform.position.y >= 5 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;
        }

但它不起作用。 它甚至似乎都没有达到使平台下降的部分。 我真的不知道从这里到哪里 go ......

根据您的评论,我进行了一些修改,以使平台运动更加顺畅。 我也这样做了,所以同样的 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;
    }
}

公平的警告,我没有测试这段代码,这更像是我针对您的情况采取的方向。 在做任何事情之前,给你的播放器添加一个标签。 如果您不确定标签是什么,请查看文档 请务必为播放器提供标签Player ,以便代码按预期工作。

您会注意到前三个变量是序列化的,但是是私有的。 通过这样做,它允许 Unity 在检查器中显示它们,但不允许其他脚本接触它们。

要了解有关协程的更多信息,请查看文档,对于 Lerps,我喜欢这篇文。 让我知道这是否适合您和/或您有任何问题。

最好的办法是添加碰撞器并使用 isTrigger。 播种时间,如果在该时间段内未触发,则引发事件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM