private bool CollidesWithExistingObject(LevelStructure structure) { //Collider[] hitColliders = Physics.OverlapBox(structure.transform.position, structure.transform.localScale * 1.2); Collider myCollider = structure.GetComponent <Collider>(); Collider[] hitColliders = Physics.OverlapBox(structure.transform.position, myCollider.bounds.extents); //Debug.Log("Testing bounds at point " + structure.transform.position + " with local scale " + myCollider.bounds.extents); int hitCount = 0; for (int i = 0; i < hitColliders.Length; i++) { Debug.Log("Hit : " + hitColliders[i].name + i); if (ObjectIsDescendant(structure.transform, hitColliders[i].gameObject.transform)) { Debug.Log("Not counting descendant collision" + hitColliders[i].name + i); continue; } hitCount++; } Debug.Log("Total hit : " + hitColliders.Length); Debug.Log("Hit count : " + hitCount); Debug.Log("My children: (this is getting weird): " + structure.transform.childCount); return(hitCount > 0); }
public LevelStructure Generate(float weight, StructureAttachmentPoint outPoint) { if (UnityEngine.Random.Range(0f, 0.99f) > weight) { return(null); } Debug.Log("Generating Structure"); LevelStructure root = null; if (outPoint == null) { // Base case: root = RandomKind(AttachmentKind.Platform).GenerateClone(); Debug.Log("Base case, got " + root); } else { // Recursive case: create a structure compatible with that outPoint Debug.Log("Recursive case, looking for compatible with " + outPoint.Kind); root = RandomCompatibleStructure(outPoint).GenerateClone(); Debug.Log("Recursive case, got " + root); // And on that new structure, mark the outPoint we're using. StructureAttachmentPoint usedPoint = root.RandomCompatiblePoint(outPoint); usedPoint.ConsumeTransforms(root.UsedTransforms); Debug.Log("Done marking used transforms: " + root.UsedTransforms.Count); // Because this is the time where we know (physically) where // we belong, we'll also place ourselves in space. Debug.Assert(outPoint != null); Debug.Assert(usedPoint != null); Debug.Assert(root != null); // We're gluing together "usedPoint" and "outPoint". // "outPoint" is (presumably) the point on our parent // "usedPoint" is the point on our structure "root". /* * Vector3 originalOffset = usedPoint.transform.position; * var originalRotation1 = outPoint.transform.localRotation; * var originalRotation2 = usedPoint.transform.localRotation; * //root.transform.localRotation = outPoint.transform.localRotation * usedPoint.transform.localRotation; * //root.transform.localPosition += root.transform.localRotation * originalOffset; * root.transform.parent = outPoint.transform; * root.transform.localPosition = new Vector3(0, 0, 0); * root.transform.localRotation = originalRotation2; * Vector3 slideAmount = usedPoint.transform.position - root.transform.position; * root.transform.position -= slideAmount; */ // this is close, but not quite. root.transform.parent = outPoint.transform; root.transform.localRotation = usedPoint.transform.localRotation; root.transform.position -= (usedPoint.transform.position - outPoint.transform.position); // We're gluing together "usedPoint" and "outPoint". // "outPoint" is (presumably) the point on our parent // "usedPoint" is the point on our structure "root". //root.transform.localRotation = usedPoint.transform.localRotation; // We adjust by (where the root expects to be connected) and (where the parent expects the root to be connected) // TODO: Did we just induce a collision with the parent? // Maybe need to look "up" the whole tree. // If so, just bail and do nothing. if (root.structurePerturbations.HasFlag(StructurePerturbations.SmallSlide)) { root.transform.position += new Vector3((UnityEngine.Random.value - 0.5f) * 4, 0, (UnityEngine.Random.value - 0.5f) * 4); //root.transform.lposition.x += UnityEngine.Random.value- 0.5f; //root.transform.position.y += UnityEngine.Random.value- 0.5f; } } // root is the structure we've just created. var renderer = root.GetComponent <Renderer>(); if (renderer != null) { //renderer.material = LevelGenerator.I.Materials.ChooseRandom(); } // Generate sub-structures if possible weight *= DensityValue; foreach (StructureAttachmentPoint subPoint in root.GetComponentsInChildren <StructureAttachmentPoint>()) { if (subPoint.Direction == AttachmentDirection.OutAttach) { // Is every transform is uses available? if (!subPoint.TransformsAvailable(root.UsedTransforms)) { continue; } // OK, great: LevelStructure newStructure = Generate(weight, subPoint); if (newStructure != null) { subPoint.ConsumeTransforms(root.UsedTransforms); } } } return(root); }
public void GenerateConnections() { // Let's randomize the order... there seems to be some persistence in the RNG // that is probably something my fault (...). // This is terrible. // candidateConnectionPoints = candidateConnectionPoints.OrderBy(x => UnityEngine.Random.value).ToList(); foreach (Tuple <Transform, Transform> pair in candidateConnectionPoints) { Transform from = pair.Item1; Transform to = pair.Item2; Vector3 direction = to.position - from.position; //Debug.Log("DEBUGGING ANGLE: " + Vector3.Angle(from.position, to.position)); // Flip a coin or whatever. float coinFlip = UnityEngine.Random.value; if (coinFlip < 0.60f) { continue; } // Have either of these points since been used? if (to.GetComponentInParent <LevelStructure>().UsedTransforms.Contains(to)) { continue; } if (from.GetComponentInParent <LevelStructure>().UsedTransforms.Contains(from)) { continue; } // This is a quick (for me, not the computer) way of avoiding ludicrously dense paths if (!SphereCastConnects(from, to, MaxConnectionRadius)) { continue; } int oldFromCount = from.GetComponentInParent <LevelStructure>().connectionCount; int oldToCount = to.GetComponentInParent <LevelStructure>().connectionCount; if (oldFromCount > 1) { continue; } if (oldToCount > 1) { continue; } from.GetComponentInParent <LevelStructure>().connectionCount++; to.GetComponentInParent <LevelStructure>().connectionCount++; Debug.Log("Adding connection!"); // TODO Take into account the angle -- maybe we want a pathway, maybe we want a rail Debug.Assert(ConnectionStructures != null); LevelStructure connection = ConnectionStructures.PickRandom <LevelStructure>().GenerateClone(); Collider connectionCollider = connection.GetComponent <Collider>(); float stretchFactor = direction.magnitude / connectionCollider.bounds.extents.z; // Warp it, stretch it, (bop it?) connection.transform.localScale = new Vector3(1, 1, stretchFactor / 2); connection.transform.position = (to.position + from.position) / 2; // Set rotation //connection.transform.rotation = Quaternion.FromToRotation(from.position, to.position); connection.transform.rotation = Quaternion.LookRotation(from.position - to.position, Vector3.forward); // The rotation also twists the platform. Basically I want to reset the z rotation to 0. // Maybe there's a nice way of not needing this? // Why can't we just set "eulerAngles" directly? Simply prevented by properties rules, I guess. // See https://docs.unity3d.com/ScriptReference/Quaternion-eulerAngles.html to show that this is the right way. Vector3 nextEuler = connection.transform.rotation.eulerAngles; nextEuler.z = 0; Quaternion nextRotation = new Quaternion(); nextRotation.eulerAngles = nextEuler; connection.transform.rotation = nextRotation; // Set hierarchy plumbing connection.transform.parent = transform; generatedStructures.Add(connection); } }