Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 控制沿路径移动的非运动学刚体_C#_Unity3d_Rigid Bodies - Fatal编程技术网

C# 控制沿路径移动的非运动学刚体

C# 控制沿路径移动的非运动学刚体,c#,unity3d,rigid-bodies,C#,Unity3d,Rigid Bodies,我正在为Unity的Android开发一款无休止的跑步者游戏。我不想使用运动学刚体。所以涉及到物理学,但刚体默认沿着预定义的路径运行。(并通过用户操作跳跃或更改车道)。直走很容易。我已经做到了,但我想在比赛的下一个阶段有轮换。这似乎是可行的,但有时会变得紧张不安,转弯也不像我希望的那么顺利。如果我提高速度,玩家会变得不稳定。你能帮我优化代码,使转弯更平稳,无论速度如何 就我所搜索的而言,我在网上找不到答案。也许人们更多地使用运动学刚体,而不是为了处理物理问题。所以我使用.AddForce和.Ad

我正在为Unity的Android开发一款无休止的跑步者游戏。我不想使用运动学刚体。所以涉及到物理学,但刚体默认沿着预定义的路径运行。(并通过用户操作跳跃或更改车道)。直走很容易。我已经做到了,但我想在比赛的下一个阶段有轮换。这似乎是可行的,但有时会变得紧张不安,转弯也不像我希望的那么顺利。如果我提高速度,玩家会变得不稳定。你能帮我优化代码,使转弯更平稳,无论速度如何

就我所搜索的而言,我在网上找不到答案。也许人们更多地使用运动学刚体,而不是为了处理物理问题。所以我使用
.AddForce
.AddTorque
。我现在使用带有预定义转弯(道路段)的预制件。因此,它是随着玩家的移动而产生的。每个道路预制都有一条用于移动路径的样条线(我想是基于Unity 2015程序样条线生成视频的自由资源)。因此,玩家沿着样条线拾取一个节点,将其设置为目标,并使用其旋转来使用AddTorque转向

如果我切换到运动学刚体,可能会更容易。也许这很理想,但我坚持这样做是为了学习物理,有些人可能会发现它对另一个项目有用,因为在这方面没有足够的资源

void FixedUpdate()
  {


    if (!jump)
    {
        //maxangle = Mathf.Clamp(r.velocity.magnitude * 2f,3,15f);
        maxangle = r.velocity.magnitude;

        r.constraints = RigidbodyConstraints.None;
        r.constraints = RigidbodyConstraints.FreezeRotationZ | RigidbodyConstraints.FreezeRotationX;
        TurnToTarget(transform, sample.Rotation,target, maxangle);
        r.constraints = RigidbodyConstraints.None;
        r.constraints = RigidbodyConstraints.FreezeRotationZ | RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY;
    }
    //Debug.Log(currentroad.transform.name + maxangle);

    if (!GameManager.gameManager.dead  && running)
    {
        r.isKinematic = false;
        //Debug.Log(transform.position.y);
        var speed = r.velocity.magnitude;
        Vector3 directionOfTarget = (target - transform.position).normalized;

        if (speed < runspeed)
        {
            //r.velocity += Vector3.forward * 1f;
            Debug.Log(r.velocity.z+ " " + r.velocity.magnitude);
            Debug.Log(directionOfTarget);
            r.AddForce(directionOfTarget* (runspeed-speed), ForceMode.VelocityChange);
        }
        if (transform.position.y > 2.7f)
        {
            r.mass = 50000f;
            Physics.gravity = new Vector3(0, -100f, 0);
        }
        if (grounded)
        {
            r.mass = 10f;
            Physics.gravity = new Vector3(0, -10f, 0);
        }

private void TurnToTarget(Transform transform, Quaternion targetrot, Vector3 movePoint, float maxTurnAccel)
 {
      Vector3 directionOfTarget = (movePoint -transform.position).normalized;
      Vector3 directionInEulers = targetrot.eulerAngles;

      Vector3 offsetInEulers = ClampHeading(directionInEulers) - ClampHeading(transform.eulerAngles);
    offsetInEulers = ClampHeading(offsetInEulers);
    //optional

    Vector3 angularVelocity = r.angularVelocity / Time.fixedDeltaTime;
    if (offsetInEulers.sqrMagnitude < Mathf.Pow(maxTurnAccel, 2))
    {
        if (offsetInEulers.y < 0)
        {
            if (angularVelocity.y < offsetInEulers.y)
            {
                offsetInEulers.y = -offsetInEulers.y;
            }
        }
        else
        {
            if (angularVelocity.y > offsetInEulers.y)
            {
                offsetInEulers.y = -offsetInEulers.y;
            }
        }
        if (offsetInEulers.x > 0)
        {
            if (angularVelocity.x < -offsetInEulers.x)
            {
                offsetInEulers.x = -offsetInEulers.x * 2;
            }
        }
        else
        {
            if (angularVelocity.x > -offsetInEulers.x)
            {
                offsetInEulers.x = -offsetInEulers.x * 2;
            }
        }
        if (offsetInEulers.z > 0)
        {
            if (angularVelocity.z < -offsetInEulers.z)
                offsetInEulers.z = -offsetInEulers.z * 2;
        }
        else
        {
            if (angularVelocity.z > -offsetInEulers.z)
                offsetInEulers.z = -offsetInEulers.z * 2;
        }
    }
    offsetInEulers = ClampVector(offsetInEulers, -maxTurnAccel, maxTurnAccel);
    //Debug.Log(currentroad + " " + offsetInEulers + " " + r.angularVelocity + " " + directionOfTarget + " " + ClampHeading(directionInEulers)+" " +transform.eulerAngles);

    r.AddRelativeTorque(transform.up * offsetInEulers.y);
    //r.AddTorque(offsetInEulers*r.velocity.magnitude);

}
void FixedUpdate()
{
如果(!跳转)
{
//maxangle=数学钳位(r.速度.幅值*2f,3,15f);
maxangle=r.速度.幅值;
r、 约束=刚体约束。无;
r、 约束=RigidbodyConstraints.FreezeRotationZ | RigidbodyConstraints.FreezeRotationX;
旋转目标(变换、采样、旋转、目标、最大角度);
r、 约束=刚体约束。无;
r、 约束=RigidbodyConstraints.FreezeRotationZ | RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY;
}
//Debug.Log(currentroad.transform.name+maxangle);
如果(!GameManager.GameManager.dead&&running)
{
r、 Iskinetic=false;
//Debug.Log(transform.position.y);
var速度=r.速度.量级;
Vector3 DirectionFTarget=(target-transform.position);
如果(速度<运行速度)
{
//r、 速度+=矢量3.前进*1f;
Debug.Log(r.velocity.z+“”+r.velocity.magnity);
Debug.Log(directionOfTarget);
r、 AddForce(方向目标*(运行速度),ForceMode.VelocityChange);
}
if(变换位置y>2.7f)
{
r、 质量=50000f;
物理重力=新矢量3(0,-100f,0);
}
如果(接地)
{
r、 质量=10f;
物理重力=新矢量3(0,-10f,0);
}
专用void TurnToTarget(变换变换、四元数目标、矢量3移动点、浮点maxTurnAccel)
{
Vector3 DirectionFTarget=(movePoint-transform.position).标准化;
Vector3方向eulers=targetrot.euleranges;
Vector3 offsetInEulers=箝位(directioneulers)-箝位(transform.euleranges);
offsetInEulers=抓取(offsetInEulers);
//可选的
矢量3角速度=r.角速度/时间.固定时间;
如果(偏移量小于数学功率(最大加速度,2))
{
如果(偏移量y<0)
{
if(角度速度y<偏移速度y)
{
offsetInEulers.y=-offsetInEulers.y;
}
}
其他的
{
if(angularVelocity.y>offsetInEulers.y)
{
offsetInEulers.y=-offsetInEulers.y;
}
}
如果(offsetInEulers.x>0)
{
if(angularVelocity.x<-offsetInEulers.x)
{
offsetInEulers.x=-offsetInEulers.x*2;
}
}
其他的
{
if(angularVelocity.x>-offsetInEulers.x)
{
offsetInEulers.x=-offsetInEulers.x*2;
}
}
如果(偏移量z>0)
{
if(角度速度.z<-偏移速度.z)
offsetInEulers.z=-offsetInEulers.z*2;
}
其他的
{
if(angularVelocity.z>-offsetInEulers.z)
offsetInEulers.z=-offsetInEulers.z*2;
}
}
offsetInEulers=ClampVector(offsetInEulers,-maxTurnAccel,maxTurnAccel);
//调试.Log(currentroad+“”+offsetInEulers+“”+r.angularVelocity+“”+DirectionFTarget+“”+Clampheding(directionInEulers)+“”+transform.euleranges);
r、 AddRelativeTorque(transform.up*offsetInEulers.y);
//r、 附加扭矩(偏移量*r.速度.幅值);
}
首先 首先要注意的是在这段代码中:

    if (transform.position.y > 2.7f)
    {
        r.mass = 50000f;
        Physics.gravity = new Vector3(0, -100f, 0);
    }
    if (grounded)
    {
        r.mass = 10f;
        Physics.gravity = new Vector3(0, -10f, 0);
    }
如果看起来您正在操纵质量以实现“停止”的效果。如果玩家在空中,你会以较高的重力值将其猛击到地面,以使其快速减速。操纵运动中物体的质量可能会导致很多问题,特别是当你在同一物理框架中施加力时。我看到你使用ForceMode.VelocityChange来解决这个问题,所以你在这方面很荣幸。不过r、 当你给一个物体添加相对力矩时,它的影响很大程度上取决于质量

直接更改对象的质量不会自动缩放对象当前的线性动量和角动量。相反,当质量增加到50000F时,动量将增加:

50,000 / (prior mass).
在飞行中改变质量通常会引起问题。我建议找到一种不同的解决方案,迫使你的球员落地,而不需要操纵质量(更不用说重力了)。也许是移动刚体。向下定位,或者施加向下的冲力
Update() - transform is updated
FixedUpdate() - reads most recent transform data
Update() - transform is updated
FixedUpdate() - reads most recent transform data
FixedUpdate() - reads most recent transform data
Update() - transform is updated