【问题标题】:Unity Move 3D object Within a barrierUnity 在屏障内移动 3D 对象
【发布时间】:2019-06-22 05:27:19
【问题描述】:

我正在使用下面的代码附加到带有脊体和碰撞的圆柱体对象上。这个对象被放置在形成一个圆圈的碰撞障碍的中间。我试图让这个物体平稳地向前移动一段随机距离,在它移动后,等待一段随机时间然后再次移动。如果它撞到带有标签名称“墙”的障碍物,则转身离开墙壁一定程度,这样它就可以继续在里面移动。并继续执行以下代码。

但是物体移动不顺畅,几乎没有移动。

我该如何解决这个问题?提前感谢您提供任何链接或帮助解决此问题。

public bool hit, m = false;


public float waitTime;
public float movDistance;
public float fRotation;
public float transitionSpeed = 1f;

private float lerpTime = 3f;
private float currentLerpTime = 0f;
private Vector3 startPos, endPos;

void Start()
{
    //rb = GetComponent<Rigidbody>();
    startPos = this.transform.position;
}

private void Update()
{
    if (m == false) {
        if (hit == true) {
            currentLerpTime += Time.deltaTime;
            if (currentLerpTime >= lerpTime) {
                currentLerpTime = lerpTime;
                hit = false;
            }
            float p = currentLerpTime / lerpTime;
            this.transform.position = Vector3.Lerp(startPos, endPos, p);


        }
        if (hit == false) {
            setRanges();
            m = true;
            StartCoroutine(Example());
        }
    }
}

public void setRanges()
{
    waitTime = Random.Range(4f, 10f);
    movDistance = Random.Range(2f, 10f);
    fRotation = Random.Range(1f, 270f);
    endPos = this.transform.position + Vector3.forward * movDistance;
}


IEnumerator Example()
{
    Debug.Log("Wait" + waitTime + "Seconds");
    startPos = this.transform.position;
    yield return new WaitForSeconds(waitTime);
    hit = true;
    m = false;

}
void OnCollisionEnter(Collision col)
{
    if (col.gameObject.tag == "wall")
    {

        Debug.Log(" hit wall");
        this.transform.rotation = Quaternion.Euler(0, 180, 0);
        hit = false;
    }
}

【问题讨论】:

  • 不要直接通过transform.position移动刚体!而是使用rb.MovePosition

标签: unity3d collision-detection coroutine lerp


【解决方案1】:

从你的代码中省略一些琐碎的部分

if (m == false) {
    if (hit == true) {
        //.... Move
        hit = false;
    }
    if (hit == false) {
        //.... Set new target position
        m = true;
        //.... Set m to false and hit to true after waitTime
    }
}

你会在你的逻辑中发现问题。

对象移动 1 帧后,将 hit 设置为 false,然后它会再次停止移动,直到通过 waitTime

我想正确的逻辑应该是在物体到达目标位置后停止,所以:

if(hit){
    //... Move
    if(currentLerpTime == lerpTime)
         hit = false;
}

【讨论】:

  • 谢谢这解决了第一个动作的平滑移动问题,我不确定之后的动作,当它碰撞对象完全旋转但由于某种原因它保持相同的方向下一步即使它旋转了。而在接下来的移动和移动之后,它似乎只是传送到下一个位置,允许它离开设置的边界区域。我编辑了上面的代码以显示我当前正在使用的代码。
  • 我认为问题出在 setRanges() 中的 endPos 中,因为它设置为向前移动?如果这是问题所在,除此之外还有更好的移动方式吗?
  • 1) 您还需要在碰撞发生时更改endPos。 2) 传送是因为你从不重置currentLerpTime
  • currentLerpTime 是有道理的,但有没有比 Vector3.forward 更好的方法?我的物体转了个弯,这很好,而且将来不会总是 180 度转。所以我希望对象按照它所面对的方式向前移动,但即使方向发生变化,它也会继续尝试以同样的方式前进。
  • Vector3.forward 总是返回 (0,0,1),你需要使用 Object Position + Object's Transform.forward * distance 确定结束位置。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多