我一直在尝试使用我在这个fractal tutorial中学到的东西来制作我可以用于自己项目的东西。我想要一个可以在Unity中生成树的脚本。我觉得我已经取得了很大的进步,但已经碰壁了。
我设置脚本的方式是根据两个参数缩放分支:
最大的问题是,当儿童成为非均匀尺度物体的父母时,他们会以无意识的方式扭曲。为了绕过,我已经制作了其他GameObjects的预制实例(默认为1,1,1)。这些GameObjects也是包含其他预制实例的其他GameObject的父对象。这是有问题的,因为分形的缩放原则需要从父级继续继承规模,但子预制实例从不传递任何东西。所以我最终必须调整预制实例的比例,使它们能够直接从彼此继承。由于指数修饰符(在'else'之后的Start()中间),下面的脚本“起作用”,但仅当所有分支具有相同数量的分支时,即仅当公共最小和最大分支密度变量相同时整数。
总结一下,我有两个问题,我希望您提出意见。
主要问题:尽管缺乏连续的层次结构,同时允许树的整体形式不均匀,我怎样才能保持分形原理的缩放完整性?
到目前为止,第二个问题是我的'thicknessScaler'变量使我的分支太薄,尤其是它越多。现在它只是将1除以分支的数量,所以我需要一个不会刮掉的东西。
using UnityEngine;
using System.Collections;
public class TreeFractal : MonoBehaviour
{
public GameObject[] branches; // the last branch is pointed, while all the others are rounded
public int maxDepth;
public float childScale;
public float maxTwist; // OFF temporarily
public Vector3 baseBranchSize; // proportions of instantiated prefab
public int minBranchDensity; // amount of offshoots per node, randomized
public int maxBranchDensity;
public float branchTilt;
private int depth;
private int branchDensity;
private GameObject branch;
private GameObject instance;
private TreeFractal grandparent;
private float displace;
private float thicknessScaler = 1;
private float parentDensity;
private void Start()
{
if (depth < maxDepth)
branch = branches[0];
else
branch = branches[1];
instance = Instantiate(branch);
instance.transform.parent = transform; // prefabs (non-uniform proportions) are made the children of uniform-scaled Game Objects.
if (depth == 0)
{
displace = baseBranchSize.y;
instance.transform.localScale = baseBranchSize;
}
else //Multiplication by density^depth is to make up for the shrinking game objects, as the prefab instances do not pass on their scale
//while the GameObjects do. This only works when all 'depths' of the tree have the same amount of offshoots.
//Because the GameObject must remain uniform, all scaling of the y axis must occur in the prefab instance.
{
displace = baseBranchSize.y * Mathf.Pow(parentDensity, depth);
//if (depth == 2)3
print(baseBranchSize.y * Mathf.Pow(parentDensity, depth));
instance.transform.localScale = new Vector3
(
baseBranchSize.x,
baseBranchSize.y * Mathf.Pow(parentDensity, depth),
baseBranchSize.z
);
}
instance.transform.localPosition = new Vector3(0f, 1f * (displace / 2), 0f); //prefab instance pivots at one end of the GameObject, for rotations.
instance.transform.localRotation = Quaternion.Euler(0f, 0f, 0f);
transform.Rotate(Random.Range(-maxTwist * ((float)(depth + 1)/ maxDepth), maxTwist * ((float)(depth + 1) / maxDepth)), 0f, 0f);
//increases the potential randomized twist more, the smaller the branches get.
if (depth < maxDepth)
{
StartCoroutine(CreateChildren());
}
}
private void Update()
{
}
private IEnumerator CreateChildren()
{
branchDensity = Random.Range(minBranchDensity, maxBranchDensity + 1);
for (int i = 0; i < branchDensity; i++)
{
yield return new WaitForSeconds(Random.Range(0.1f, 0.5f));
Quaternion quaternion = BranchRotater(branchDensity, i);
new GameObject("Fractal Child").AddComponent<TreeFractal>().
Initialize(this, i, quaternion);
}
}
private Quaternion BranchRotater (int density, int childIndex) //returns the rotation of the branch depending on the index and amount of branches.
{
Quaternion quaternion = Quaternion.Euler
(0f,
(360 / density) * childIndex,
branchTilt
);
return quaternion;
}
private void Initialize(TreeFractal parent, int childIndex, Quaternion quaternion)
{
branches = parent.branches;
branchTilt = parent.branchTilt;
maxDepth = parent.maxDepth;
depth = parent.depth + 1;
baseBranchSize = parent.baseBranchSize;
maxTwist = parent.maxTwist;
transform.parent = parent.transform;
childScale = parent.childScale;
minBranchDensity = parent.minBranchDensity;
maxBranchDensity = parent.maxBranchDensity;
thicknessScaler = 1f / parent.branchDensity; // I need a better equation here. This scaler is too small.
transform.localScale = Vector3.one * childScale * thicknessScaler; // reproportions all 3 axes of child GameObject so that
//the child remains of uniform scale. This must then be compensated for in the scaling of said object's child-prefab.
parentDensity = parent.branchDensity;
transform.localPosition = Vector3.up * parent.displace; //positions child relative to its parent
transform.localRotation = quaternion;
}
}
答案 0 :(得分:0)
如果您构建这样的预制件,则可以在预制件的根节点处应用父对子比例,并在子节点处应用非均匀比例。如果现在将子项的根附加到根节点,则只会统一比例结转。
prefab:
[root]
|--->[non-uni]
| |---> mesh
.
.
[childRoot]