/// <summary> /// We override the create world object function for a tree. This is done as we need to load in multiple /// parts of the tree /// </summary> /// <param name="transform"></param> /// <returns></returns> public override WorldObject CreateWorldObject(Transform transform = null) { //Create random with seed unique to tree position - this ensures tree should be same every time. GenerationRandom genRan = new GenerationRandom(WorldPosition.x * World.WorldSize * World.ChunkSize + WorldPosition.z); int canopy = genRan.RandomInt(3, 7); float angleOffset = genRan.Random(0, Mathf.PI); float range = Mathf.Sqrt(canopy * 0.5f) * 0.8f; WorldObject treeBase = WorldObject.CreateWorldObject(this, transform); Vec2i zero = new Vec2i(0, 0); Vector3[] canopyPositions = new Vector3[canopy]; for (int i = 0; i < canopy; i++) { //Define the positions of each canopy as roughly circular about the middle of the tree. float angle = (Mathf.PI * 2 / (canopy)) * i + angleOffset; Vector2 delta = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)) * range + genRan.RandomVector2(-0.1f, 0.1f); float height = 1.8f + genRan.Random(0, 1f); //Store the total position for use later, then generate the canopy itself. canopyPositions[i] = new Vector3(delta.x, height, delta.y); TreeCanopy tr = new TreeCanopy(zero, canopyPositions[i]); tr.SetRandom(genRan); tr.CreateWorldObject(treeBase.transform); } //Generate the trunk float trunkHeight = 1.2f; float trunkScale = 1.2f; TreeBranch trunk = new TreeBranch(zero); trunk.SetCharacteristic(Vector3.zero, new Vector3(0, 0, 0), new Vector3(1, trunkScale, 1)); WorldObject trunkObj = trunk.CreateWorldObject(treeBase.transform); //MeshCollider mc =trunkObj.gameObject.AddComponent<MeshCollider>(); //mc.sharedMesh = trunkObj.gameObject.GetComponent<MeshFilter>().mesh; Vector3 trunkTop = Vector3.up * trunkHeight * trunkScale; //Scale to correct height foreach (Vector3 v in canopyPositions) { TreeBranch canopyBranch = new TreeBranch(zero); //Calculate the Euler angles from the branch base to the canopy Vector3 delta_pos = v - trunkTop; Quaternion.FromToRotation(Vector3.up, delta_pos); //Vector3 rot = Quaternion.FromToRotation(trunkTop, v*5f).eulerAngles; Vector3 rot = Quaternion.FromToRotation(Vector3.up, delta_pos).eulerAngles; float scale = Vector3.Distance(v, trunkTop) / trunkHeight; canopyBranch.SetCharacteristic(trunkTop, rot, new Vector3(1 / scale, scale, 1 / scale)); canopyBranch.CreateWorldObject(treeBase.transform); } return(treeBase); }