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