geom1 | 包含已分配形状的每对 GeometryHolder 对象的第一个成员的数组。 |
geom2 | 包含已分配形状的每对 GeometryHolder 对象的第二个成员的数组。 |
xform1 | 包含每对 ImmediateTransform 的第一个成员的数组。 |
xform2 | 包含每对 ImmediateTransform 的第二个成员的数组。 |
pairCount | 在 GeometryHolder 和 ImmediateTransform 数组中提供的配对数。 |
outContacts | 已生成的接触点输出数组。 |
outContactCounts | 每个配对生成的接触点数量的输出数组。 |
contactDistance | 开始在配对之间生成接触点的距离。 |
int 返回生成的接触点总数。
生成所有给定形状对的接触点。将生成的接触点存储在 ImmediateContact 数组中,并将每个配对的接触点数存储在 `outContactCounts` 数组中。
此代码示例定义了 PhysX 在此场景中需要多少对对象。您可以为小型联系人检查设置一个特定数字,或者,如果您打算运行更复杂的仿真,则可能需要实现广相位筛选,找出多少对对象将交互。最简单且性能最差的选择是将所有可能的身体对放入场景中存在的 GenerateContacts 函数中。此示例展示了手动添加两对物体并检查它们之间接触的基本设置。
using System.Collections.Generic; using UnityEngine; using UnityEngine.LowLevelPhysics; using Unity.Collections;
public class ImmediatePhysics_GenerateContacts_Example : MonoBehaviour { private int m_NumberOfPairs = 2;
// Pull in a reference from the Editor to the Mesh Collider. [SerializeField] private MeshCollider m_Mesh;
List<Vector3> contactPoints = new List<Vector3>();
// There is no way to know how many contacts the shapes will generate, // so set a maximum value that should confidently fit all of them. int s_MaxContactCount = 100;
void Start() { // Create and set up geometry and transform arrays. NativeArray<GeometryHolder> geom1 = new NativeArray<GeometryHolder>(m_NumberOfPairs, Allocator.Temp); NativeArray<GeometryHolder> geom2 = new NativeArray<GeometryHolder>(m_NumberOfPairs, Allocator.Temp);
// Create a box shape that is 1 meter wide on each axis, and use that to construct a GeometryHolder object. BoxGeometry boxShape = new BoxGeometry(new Vector3(0.5f, 0.5f, 0.5f)); GeometryHolder box = GeometryHolder.Create(boxShape);
// Get the geometry of an existing collider. GeometryHolder convexMesh = m_Mesh.GeometryHolder;
NativeArray<ImmediateTransform> xForms1 = new NativeArray<ImmediateTransform>(m_NumberOfPairs, Allocator.Temp); NativeArray<ImmediateTransform> xForms2 = new NativeArray<ImmediateTransform>(m_NumberOfPairs, Allocator.Temp);
ImmediateTransform body1Transform = new ImmediateTransform { Position = new Vector3(0, 0, 0), Rotation = Quaternion.identity };
ImmediateTransform body2Transform = new ImmediateTransform { Position = new Vector3(0, 0.75f, 0), Rotation = Quaternion.Euler(new Vector3(45f, 0, 0)) };
// First pair is two boxes interacting. geom1[0] = box; geom2[0] = box;
xForms1[0] = body1Transform; xForms2[0] = body2Transform;
// Second pair is a box and a convex Mesh Collider. geom1[1] = convexMesh; geom1[2] = box;
xForms1[1] = body1Transform; xForms2[1] = body2Transform;
// This code re-uses the same transforms, which means that if all the bodies // were part of the same simulation, they would all overlap with each other. However, // because we are only generating contacts per pair, one pair of bodies does not affect // the other pairs.
// Create a place to hold the output contacts and their counts per pair. // There is no way to know how many contacts the shapes will generate, // so set a maximum value that should confidently fit all of them. NativeArray<ImmediateContact> contacts = new NativeArray<ImmediateContact>(s_MaxContactCount, Allocator.Temp); // The number of contactCounts is the same as the number of pairs. NativeArray<int> contactCounts = new NativeArray<int>(m_NumberOfPairs, Allocator.Temp);
// Finally, call the GenerateContacts function and put all the arrays in. // Keep note of the ReadOnly status of the input arrays.
var totalContacts = ImmediatePhysics.GenerateContacts(geom1.AsReadOnly(), geom2.AsReadOnly(), xForms1.AsReadOnly(), xForms2.AsReadOnly(), m_NumberOfPairs, contacts, contactCounts);
// It is now possible to check whether there were any contacts for the pairs. // First, iterate over the number of input pairs defined in m_NumberOfPairs. int idx = 0; for (int i = 0; i < m_NumberOfPairs; i++) { // Iterate over the number of contacts that were generated per each pair. for (int j = 0; j < contactCounts[i]; j++) { // Add the contact points to a list for visualization later. contactPoints.Add(contacts[idx].Point);
// The number of contact points per each pair can be variable, so // use a separate index to keep track of which contact to retrieve. idx++; } } } }