我在c#和unity中构建了一个基于分形的对象生成器,它构建了对象的分支,然后使用Colliders和Rigidbodies相互反弹。现在他们互相撞击,继续前进越来越远。我想做的就是给每个物体分配一定程度的引力,这样即使它们在碰撞中被击退,它们也会把它们拉回来。除了物体的重力方面,除了工作之外,我得到了一切。有没有人有这方面的经验谁不介意给我一些方向?谢谢!
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class BuildFractal : MonoBehaviour
{
public Mesh[] meshes;
public Material material;
public Material[,] materials;
private Rigidbody rigidbody;
public int maxDepth; // max children depth
private int depth;
public float childScale; // set scale of child objects
public float spawnProbability; // determine whether a branch is created or not
public float maxRotationSpeed; // set maximium rotation speed
private float rotationSpeed;
public float maxTwist;
public Text positionText;
// Create arrays for direction and orientation data
private static Vector3[] childDirections = {
Vector3.up,
Vector3.right,
Vector3.left,
Vector3.forward,
Vector3.back,
// Vector3.down
};
private static Quaternion[] childOrientations = {
Quaternion.identity,
Quaternion.Euler(0f, 0f, -90f),
Quaternion.Euler(0f, 0f, 90f),
Quaternion.Euler(90f, 0f, 0f),
Quaternion.Euler(-90f, 0f, 0f),
// Quaternion.Euler(180f, 0f, 0f)
};
private void Start ()
{
rotationSpeed = Random.Range(-maxRotationSpeed, maxRotationSpeed);
transform.Rotate(Random.Range(-maxTwist, maxTwist), 0f, 0f);
if (materials == null)
{
InitializeMaterials();
}
// Select from random range of meshes
gameObject.AddComponent<MeshFilter>().mesh = meshes[Random.Range(0, meshes.Length)];
// Select from random range of colors
gameObject.AddComponent<MeshRenderer>().material = materials[depth, Random.Range(0, 2)];
// Add a collider to each object
gameObject.AddComponent<SphereCollider>().isTrigger = false;
// Add Rigigbody to each object
gameObject.AddComponent<Rigidbody>();
gameObject.GetComponent<Rigidbody>().useGravity = false;
gameObject.GetComponent<Rigidbody>().mass = 1000;
// Create Fractal Children
if (depth < maxDepth)
{
StartCoroutine(CreateChildren());
}
}
private void Update ()
{
transform.Rotate(0f, rotationSpeed * Time.deltaTime, 0f);
}
private IEnumerator CreateChildren ()
{
for (int i = 0; i < childDirections.Length; i++)
{
if (Random.value < spawnProbability)
{
yield return new WaitForSeconds(Random.Range(0.1f, 1.5f));
new GameObject("Fractal Child").AddComponent<BuildFractal>().Initialize(this, i);
}
/*if (i == childDirections.Length)
{
DestroyChildren();
}*/
// positionText.text = transform.position.ToString(this);
}
}
private void Initialize (BuildFractal parent, int childIndex)
{
maxRotationSpeed = parent.maxRotationSpeed;
// copy mesh and material references from parent object
meshes = parent.meshes;
materials = parent.materials;
maxTwist = parent.maxTwist;
// set depth and scale based on variables defined in parent
maxDepth = parent.maxDepth;
depth = parent.depth + 1;
childScale = parent.childScale;
transform.parent = parent.transform; // set child transform to parent
// transform.localScale = Vector3.one * childScale;
transform.localScale = Vector3.one * Random.Range(childScale / 10, childScale * 1);
transform.localPosition = childDirections[childIndex] * (Random.Range((0.1f + 0.1f * childScale),(0.9f + 0.9f * childScale)));
transform.localRotation = childOrientations[childIndex];
spawnProbability = parent.spawnProbability;
}
private void InitializeMaterials ()
{
materials = new Material[maxDepth + 1, 2];
for (int i = 0; i <= maxDepth; i++)
{
float t = i / (maxDepth - 1f);
t *= t;
// Create a 2D array to hold color progressions
materials[i, 0] = new Material(material);
materials[i, 0].color = Color.Lerp(Color.gray, Color.white, t);
materials[i, 1] = new Material(material);
materials[i, 1].color = Color.Lerp(Color.white, Color.white, t);
}
// materials[maxDepth, 0].color = Color.white;
materials[maxDepth, 1].color = Color.white;
}
}
答案 0 :(得分:1)
取决于您的重力模拟的准确程度。假设模拟中的所有对象具有相同的密度,您可以使用Mesh.bounds粗略估计其体积:
Vector3 size = myMesh.bounds.size;
float volume = size.x * size.y * size.z * scale; // scale could be childScale in your case
由于您的模拟是分形,因此您必须在每个分形迭代中应用childScale。但是,如果网格没有变化,你就不必重新计算网格的基础体积。
重力模拟: 对于大量对象,这可能会非常复杂。你必须模拟整个重力场。
只有两个相互作用的对象的计算相当简单。施加到相互吸引的物体的力可以通过牛顿公式计算
F1 = F2 = G * m1 * m2 / r ^ 2
(见:https://en.wikipedia.org/wiki/Gravitational_constant)
但是你的系统中可能有两个以上的对象。您必须为每个对象计算上述关系 - 在每个对象之间。对于每个对象,您必须添加所有计算的力,然后应用所产生的力。
假设你的场景中有N个物体,你必须为每个物体做上述计算(N-1)。这会产生N ^(N-1)计算,这将很快失控,特别是如果你在分形结构中这样做。
要掌握这种巨大的复杂性,您可以引入一系列影响,因此只有附近的物体才会相互影响。虽然这会进一步降低模拟的准确性。