25-02-2021, 10:40 AM
(This post was last modified: 25-02-2021, 10:45 AM by josemendez.)
If your meshes are 2D, you could use 2D mode:
http://obi.virtualmethodstudio.com/tutor...olver.html
If you need "2.5D" (3D assets in a 2D simulation space) you can just project linear velocities to the XY plane, and angular velocities to the Z axis. You can optionally project positions too to avoid drifting. This is very easy to do using the particles API:
Just add this component to any actor and it will restrict its movement to the solver's local 2D plane.
http://obi.virtualmethodstudio.com/tutor...olver.html
Quote:ModeHowever this has two drawbacks: particle orientations will also be restricted to the XY plane, which can look odd if your assets are 3D. Also, it affects the entire solver.
The solver can simulate in 2D or 3D mode. In 2D mode, simulation only happens in the XY plane.
If you need "2.5D" (3D assets in a 2D simulation space) you can just project linear velocities to the XY plane, and angular velocities to the Z axis. You can optionally project positions too to avoid drifting. This is very easy to do using the particles API:
Code:
using UnityEngine;
using Obi;
[RequireComponent(typeof(ObiActor))]
public class ConstrainTo2D : MonoBehaviour
{
private ObiActor actor;
private float[] perParticleDepth;
public void Start()
{
actor = GetComponent<ObiActor>();
actor.OnBeginStep += Softbody_OnBeginStep;
}
private void Softbody_OnBeginStep(ObiActor a, float stepTime)
{
var solver = actor.solver;
if (perParticleDepth == null || perParticleDepth.Length == 0)
{
// store initial particle depth values, to ensure no positional drifting outside the XY plane:
perParticleDepth = new float[actor.solverIndices.Length];
for (int i = 0; i < actor.solverIndices.Length; ++i)
perParticleDepth[i] = solver.positions[actor.solverIndices[i]].z;
}
for (int i = 0; i < actor.solverIndices.Length; ++i)
{
int particleIndex = actor.solverIndices[i];
var position = solver.positions[particleIndex];
var linearVelocity = solver.velocities[particleIndex];
var angularVelocity = solver.angularVelocities[particleIndex];
// project velocities back to the xy plane.
linearVelocity.z = 0;
angularVelocity.x = 0;
angularVelocity.y = 0;
// project positions back to their original xy plane:
position.z = perParticleDepth[particleIndex];
solver.positions[particleIndex] = position;
solver.velocities[particleIndex] = linearVelocity;
solver.angularVelocities[particleIndex] = angularVelocity;
}
}
}
Just add this component to any actor and it will restrict its movement to the solver's local 2D plane.