【问题标题】:Smooth raycast positioning平滑的光线投射定位
【发布时间】:2016-05-19 09:44:48
【问题描述】:

我编写了一个脚本,通过光线投射将对象移动到地形上的位置,但是我似乎一辈子都无法让这个移动变得平滑。我已经尝试了各种各样的方法来解决这个问题(你可能可以通过下面注释掉的代码量来判断);禁用各种刚体变量,但无济于事。

一种(某种)有效的方法是禁用附加到对象的对撞机,但这会导致对象无意中沉入地形之下。

谁能告诉我解决这个问题的最佳方法是什么?我觉得这应该很简单,但我把它复杂化了。

         //Move
        if (Input.GetKey(KeyCode.E)) {
          //            if (Input.GetKeyDown(KeyCode.E))
          //            {
          //                modObj.GetComponent(BoxCollider).enabled = false;               
          initPos = modObj.transform.position;
          var initRotation = modObj.transform.rotation;
          //            }
          //            
          //            modObj.GetComponent(Rigidbody).isKinematic = true;
          //            modObj.GetComponent(Rigidbody).useGravity = false; 

          moveObject(modObj, initPos, initRotation);
        } else {
          //            modObj.GetComponent(BoxCollider).enabled = true;
          //            modObj.GetComponent(Rigidbody).isKinematic = false;
          //            modObj.GetComponent(Rigidbody).useGravity = true; 
        }
function moveObject(modObj: GameObject, initPos: Vector3, initRotation: Quaternion) {
  //Debug.Log("Moving Object");

  var hit: RaycastHit;
  var foundHit: boolean = false;

  foundHit = Physics.Raycast(transform.position, transform.forward, hit);
  //Debug.DrawRay(transform.position, transform.forward, Color.blue);

  if (foundHit && hit.transform.tag == "Terrain") {
    modifyObjGUIscript.activateMoveDisplay(initPos, hit.point);

    //      var meshHalfHeight = modObj.GetComponent.<MeshRenderer>().bounds.size.y /2; //helps account for large and small objects

    modObj.transform.position = hit.point; //***method 01***
    //      modObj.transform.position = Vector3.Lerp(initPos, hit.point, speed); //***method 02***
    //      modObj.transform.position = Vector3.SmoothDamp(initPos, hit.point, velocity, smoothTime); //***method 02***

    //      modObj.transform.position.y =  modObj.transform.position.y + meshHalfHeight + hoverHeight;

    modObj.transform.rotation = initRotation;
  }
}

【问题讨论】:

    标签: unity3d raycasting rigid-bodies


    【解决方案1】:

    您需要调用 moveObject 以非常频繁地重新计算位置 - 如果可能,每帧。例如来自更新或协程:

    void Update() 
    {
        modObj.transform.position = Vector3.Lerp(initPos, hit.point, speed); 
    }
    
    
    IEnumerator MoveObject(Vector3 initPos, Vector3 endPos, float speed)
    {
        while (initPos != endPos)
        {
        modObj.transform.position = Vector3.Lerp(initPos, endPos, speed);
        yield return null;
        }
    }
    

    【讨论】:

    • 正确。还要注意,你经常这样做:有一个新的独立标记(即空游戏对象),称为“Tracker”。但是出于开发目的,它上面有一个小的白色立方体,因此您可以看到它。将 Jorel 的脚本放在 Tracker 上(不在您的实际飞机上)。让用户实际驾驶,等等,Tracker。接下来,让您的飞机真正随处跟踪追踪器。通过这种方式,您可以为飞机平滑 Y 上的运动;这样做通常更简单、更合乎逻辑。
    • @joreldraw sorry 在我的帖子中应该更清楚:moveObject() 函数是从 Input.GetKey(KeyCode.E) 内部的 FixedUpdate() 调用的;这和你说的相符吗?根据我收到的其他反馈,我还将定位从使用对象的变换更改为使用其刚体:var movRb = modObj.GetComponent.&lt;Rigidbody&gt;();movRb.position = Vector3.Lerp(initPos, hit.point, speed);。这当然有帮助,但没有解决问题。任何进一步的反馈将不胜感激。
    • 尝试用while条件调用协程,我为此编辑协程。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-24
    • 1970-01-01
    • 2019-10-17
    • 2018-07-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多