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# 如何用Unity3d'绘制弹丸弹道;内置的物理引擎?_C#_Unity3d - Fatal编程技术网

C# 如何用Unity3d'绘制弹丸弹道;内置的物理引擎?

C# 如何用Unity3d'绘制弹丸弹道;内置的物理引擎?,c#,unity3d,C#,Unity3d,我正在做一个游戏,它将投掷一个对物理力有反应的抛射物。我在游戏中使用了内置的统一物理,但我在发射前绘制了弹丸的轨迹。为此,我使用了一个LineRenderer和一个简单的物理类来计算位置: public class SlingPhysics { private Vector3 HalfGravity; private float ForceMultiplier; public void Init(Vector3 gravity, float slingForce, fl

我正在做一个游戏,它将投掷一个对物理力有反应的抛射物。我在游戏中使用了内置的统一物理,但我在发射前绘制了弹丸的轨迹。为此,我使用了一个LineRenderer和一个简单的物理类来计算位置:

public class SlingPhysics
{
    private Vector3 HalfGravity;
    private float ForceMultiplier;

    public void Init(Vector3 gravity, float slingForce, float mass, float drag)
    {
        HalfGravity = gravity / 2.0f;
        ForceMultiplier = slingForce / mass / (1 + drag);
    }

    public Vector3 GetPosition(Vector3 start, Vector3 direction, float timeDelta)
    {
        Vector3 pos = direction * (timeDelta * ForceMultiplier);
        pos.y += (HalfGravity.y * timeDelta * timeDelta);
        return start + pos;
    }

    /// <summary>
    /// Computes an array of Trajectory object positions by time.
    /// </summary>
    /// <returns>Number of positions filled into the buffer</returns>
    /// <param name="startPos">Starting Position</param>
    /// <param name="direction">Direction (and magnitude) vector</param>
    /// <param name="timeIncrement">Time increment of the samples</param>
    /// <param name="yFloor">Minimum height, below which is clipped</param>
    /// <param name="positions">Buffer to fill with positions</param>
    public int GetPositions(Vector3 startPos, Vector3 direction, float timeIncrement, float yFloor, Vector3[] positions)
    {
        int maxItems = positions.Length;
        int i = 0;
        for (; i < maxItems; i++)
        {
            Vector3 pos = GetPosition(startPos, direction, timeIncrement * i);
            if (pos.y < yFloor)
                break;
            positions[i] = pos;
        }
        return i;
    }
}
公共课SlingPhysics
{
私人矢量3半重力;
私人浮动乘数;
公共空隙初始值(矢量3重力、浮力、浮力质量、浮力阻力)
{
半重力=重力/2.0f;
力倍增器=滑行力/质量/(1+阻力);
}
公共向量3获取位置(向量3开始、向量3方向、浮点时间增量)
{
矢量3位置=方向*(时间增量*力乘数);
位置y+=(半重力y*时间增量*时间增量);
返回启动+pos;
}
/// 
///按时间计算轨迹对象位置数组。
/// 
///填充到缓冲区中的位置数
///起始位置
///方向(和幅度)矢量
///样本的时间增量
///最小高度,低于该高度将被剪裁
///填补空缺的缓冲区
公共int GetPositions(矢量3起始位置、矢量3方向、浮点时间增量、浮点yFloor、矢量3[]位置)
{
int maxItems=位置。长度;
int i=0;
对于(;i
这非常有效,并且(有些令人惊讶)与发射时弹丸最终行进的实际轨迹完全匹配,并且由Unity Physics引擎控制

但现在,我们决定在刚体上引入阻力,轨迹不再完美。我可以继续尝试改变我的物理模型来匹配Unity正在做的事情,但这似乎是一场失败的战斗

有没有办法使用Unity Physics引擎预先计算并绘制轨迹

如果没有,在统一物理中,阻力和角阻力是如何在数学上实现的

Unity(5.3.4)物理实现是否有文档来源

我可以继续尝试改变我的物理模型,以符合统一性 正在做什么

不,不要这样做。每当Unity更新时,物理之类的东西就会中断。例如,Unity 4和Unity 5物理不一样。我不得不大量修改我的Unity 4物理代码,使其正常工作

解决问题的最简单方法是根本不计算任何东西。我这样做的方式是创建两个投射物投射物1是可以看到和射击的主要投射物PROJECTLE2是玩家看不见的隐藏投射物

在拖动模式下,拍摄投射物2(隐藏),然后将其经过的路径或位置(矢量3)存储在
列表中。使用存储的路径绘制
投射物轨迹

您只需拍摄一次投影2(隐藏)并存储路径。如果在拖动模式下,手指、鼠标或拖动移动到另一个位置,则必须清除
列表
,再次重新拍摄投射物2(隐藏),将位置存储到
列表
,然后再次更新
投射物轨迹

松开手指后,您现在可以射击玩家可见的投射物1(主投射物)

如果使用的是
lineRenderer
,则
SetVertexCount
的编号与
列表的编号相同。Count
。通过在
列表中的位置上循环,可以轻松绘制线条

无论Unity更新多少次,结果都是一样的

我可以继续尝试改变我的物理模型,以符合统一性 正在做什么

不,不要这样做。每当Unity更新时,物理之类的东西就会中断。例如,Unity 4和Unity 5物理不一样。我不得不大量修改我的Unity 4物理代码,使其正常工作

解决问题的最简单方法是根本不计算任何东西。我这样做的方式是创建两个投射物投射物1是可以看到和射击的主要投射物PROJECTLE2是玩家看不见的隐藏投射物

在拖动模式下,拍摄投射物2(隐藏),然后将其经过的路径或位置(矢量3)存储在
列表中。使用存储的路径绘制
投射物轨迹

您只需拍摄一次投影2(隐藏)并存储路径。如果在拖动模式下,手指、鼠标或拖动移动到另一个位置,则必须清除
列表
,再次重新拍摄投射物2(隐藏),将位置存储到
列表
,然后再次更新
投射物轨迹

松开手指后,您现在可以射击玩家可见的投射物1(主投射物)

如果使用的是
lineRenderer
,则
SetVertexCount
的编号与
列表的编号相同。Count
。通过在
列表中的位置上循环,可以轻松绘制线条


无论Unity更新多少次,结果始终相同。

计算阻力以匹配Unity引擎的方法是计算并跟踪FixedUpdate中的速度,然后更新阻力的速度

单位公式f
velocity *= Mathf.Clamp01(1f - Drag * Time.fixedDeltaTime);
public class SlingPhysics
{
    private Vector3 Gravity;
    private float Force, Mass, Drag;

    public void Init(Vector3 gravity, float force, float mass, float drag)
    {
        Gravity = gravity;
        Force = force;
        Mass = mass;
        Drag = drag;
    }

    /// <summary>
    /// Computes an array of Trajectory object positions by time.
    /// </summary>
    /// <returns>Number of positions filled into the buffer</returns>
    /// <param name="startPos">Starting Position</param>
    /// <param name="direction">Direction (and magnitude) vector</param>
    /// <param name="yFloor">Minimum height, below which is clipped</param>
    /// <param name="positions">Buffer to fill with positions</param>
    public int GetPositions(Vector3 startPos, Vector3 direction, float yFloor, Vector3[] positions)
    {
        float timeIncrement = Time.fixedDeltaTime;

        int maxItems = positions.Length;
        int i = 0;
        Vector3 velocity = direction * Force / Mass;
        Vector3 pos = startPos;
        for (; i < maxItems; i++)
        {
            velocity += Gravity * timeIncrement;
            velocity *= Mathf.Clamp01(1f - Drag * timeIncrement);
            pos += velocity * timeIncrement;
            if (pos.y < yFloor)
                break;
            positions[i] = pos;
        }
        return i;
    }
}