// Use this for initialization IEnumerator Start() { level = new LevelStructure(); floatingSec = level.FloatingSec; waitSec = level.WaitSec; InitAnimals(); ApplicationModel.correctCardOrder = new string[level.AnimalsToOrderCount]; var rnd = new System.Random(); for (int i = 0; i <= level.AnimalsToOrderCount - 1; i++) { animal = shuffledAnimals[rnd.Next(0, 4)]; ApplicationModel.correctCardOrder[i] = animal.name; StartCoroutine(SmoothMove(startPos, new Vector2(canvasCenterX, canvasPosY), animal.rectTransform, floatingSec)); yield return(new WaitForSeconds(floatingSec + waitSec)); StartCoroutine(SmoothMove(animal.rectTransform.position, new Vector2(-(animal.rectTransform.rect.width + canvasPosX), canvasPosY), animal.rectTransform, floatingSec)); yield return(new WaitForSeconds(floatingSec)); if (i == level.AnimalsToOrderCount - 1) { LoadOrderingScene(); } } }
bool RadiusHitsOtherStructure(LevelStructure structure, float radius) { // TODO: Can we just make this a constant somewhere? Collider[] hitColliders = new Collider[structure.transform.childCount + 2]; //Debug.Log("RadiusHitsOtherStructures Start: " + hitColliders.Length + " radius: " + radius); // How many things do we hit? int overlapCount = Physics.OverlapSphereNonAlloc(structure.transform.position, radius, hitColliders); //Debug.Log("RadiusHitsOtherStructures: " + overlapCount + structure); // Filter out ourselves foreach (Collider c in hitColliders) { if (c == null) { continue; } if (ObjectIsDescendant(structure.transform, c.gameObject.transform)) { overlapCount--; //Debug.Log("Decrement Child: " + overlapCount + structure); } else { //Debug.Log("New object:" + c.gameObject + " " + c.gameObject.transform); } } //Debug.Log("RadiusHitsOtherStructures: " + overlapCount + structure); return(overlapCount > 0); }
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 void TestGenerate() { if (CurrentGenerated) { DestroyImmediate(CurrentGenerated.gameObject); } // TODO: 1.0 should be "InitialGenWeight" CurrentGenerated = Generate(1.0f, null); CurrentGenerated.transform.position = new Vector3(0, 0, 0); // place at origin CurrentGenerated.transform.parent = transform; }
// Find the ballon from this center until it hits another object... float CenteredBalloonRadius(LevelStructure structure, int desiredCount = 1) { Vector3 center = structure.transform.position; float smallestOneHit = 1; float smallestTwoHit = 1000000; float eps = 1; float radius = 1; Collider[] hitColliders = new Collider[desiredCount + 2]; int bailCount = 1000; while (!RadiusHitsOtherStructure(structure, radius)) { smallestOneHit = radius; radius *= 2; if (bailCount-- < 1) { Debug.Log("BAILING IN CENTERED 1!\n"); break; } } // OK, we just found the first radius where we hit something. smallestTwoHit = radius; float experiment = (smallestTwoHit + smallestOneHit) / 2; // avoid infinite loop in weird... concave... cases? Not sure when this is true, exactly. while (smallestTwoHit > (smallestOneHit + eps)) { if (bailCount-- < 1) { Debug.Log("BAILING IN CENTERED 2!\n"); break; } experiment = (smallestTwoHit + smallestOneHit) / 2; if (!RadiusHitsOtherStructure(structure, experiment)) { smallestOneHit = experiment; } else { smallestTwoHit = experiment; } } return(experiment); }
// Use this for initialization void Start() { Debug.Log("World Manager started"); blockSize = 10; playerMonitoring = new Dictionary <int, ClientDetails> (); levelStructure = new LevelStructure(mapPattern, blockSize); levelStructure.convertToMesh(regionBlank, transform); //resourceBrickGenerator(); //Generate resources on start. Potentially use this in future as a way for the server to generate new resources in the world when the current world runs out/low. levelStructure.refreshMesh(); }
public void OnEndDrag(PointerEventData eventData) { if (ErrorHandler.Error.activeSelf || ErrorHandler.Excellent.activeSelf) { return; } if (origParent != parentToReturn) { clone.transform.SetParent(parentToReturn); Destroy(clone.GetComponent <Dragable>()); } else { Destroy(clone.gameObject); } clone.GetComponent <CanvasGroup>().blocksRaycasts = true; clone.GetComponent <LayoutElement>().ignoreLayout = false; LevelStructure level = new LevelStructure(); if (origParent != parentToReturn && ApplicationModel.orderedAnimalsCount == level.AnimalsToOrderCount) { if (!CheckAnimalOrder()) { ErrorHandler.Error.SetActive(true); } else { ApplicationModel.CurrentLevel++; ApplicationModel.CurrentBoneNumber++; if (FirebaseAuthHelper.Auth.CurrentUser != null) { ApplicationModel.SaveLocalUserData(FirebaseAuthHelper.Auth.CurrentUser.UserId); FirebaseDatabaseHandler.SaveCloudUserData(FirebaseAuthHelper.Auth.CurrentUser.UserId); } else { ApplicationModel.SaveLocalUserData("notRegisteredUser"); } ErrorHandler.Excellent.SetActive(true); } ApplicationModel.orderedAnimalsCount = 0; } }
static public bool SphereCastConnects(Transform connectionFrom, Transform connectionTo, float radius) { LevelStructure fromPlatform = connectionFrom.GetComponentInParent <LevelStructure>(); LevelStructure toPlatform = connectionTo.GetComponentInParent <LevelStructure>(); // Compute the direction: Vector3 fromPosition = connectionFrom.position; Vector3 toPosition = connectionTo.position; Vector3 direction = toPosition - fromPosition; float newMaxDistance = Math.Min(MaxConnectionDistance, Vector3.Distance(fromPosition, toPosition)); // Performance: First, see if a raycast works: RaycastHit[] results = new RaycastHit[1]; Ray raycastRay = new Ray(fromPosition, direction); if (Physics.RaycastNonAlloc(raycastRay, results, newMaxDistance) == 0) { return(false); } // And we better have hit the toPlatform if (results[0].transform.GetComponentInParent <LevelStructure>() != toPlatform) { return(false); } ///////////////////////////////////// // This is expensive, but is necessary...? // Yes. It really does actually eliminate a lot of (bad) cases RaycastHit[] hitInfo = Physics.SphereCastAll(fromPosition, radius, direction, newMaxDistance); // Analyze the hitinfo to see if we've hit what we want. foreach (RaycastHit hit in hitInfo) { if (!ObjectIsDescendant(fromPlatform.transform, hit.transform) && !ObjectIsDescendant(toPlatform.transform, hit.transform)) { //Debug.Log("From: " + from + " to: " + to + " fails for " + hit); return(false); } } // End expensive filtering ///////////////////////////////////// return(true); }
void Start() { SetBlacks(); SetLang(); Canvas = GameObject.Find("Canvas"); UpdateValues(); TextAsset txt = (TextAsset)Resources.Load("Levels/" + curCamp + "/" + curLvl, typeof(TextAsset)); string settings = txt.text; curLevelStruct = JsonUtility.FromJson <LevelStructure>(settings); SetEnterExitSettings(); SetWalls(); SetLine(); AddWhiteSquare(); AddBlackSquare(); AddNoWay(); AddTakePoints(); AddDeleteObject(); }
private void LoadTheme() { LevelStructure level = new LevelStructure(); Background.GetComponent <Image>().sprite = ThemeCacheClass.BackgroundSprite; ExitIcon.GetComponent <Image>().sprite = ThemeCacheClass.ExitIconSprite; Bone.GetComponent <Image>().sprite = ThemeCacheClass.BoneSprite; Bone.GetComponentInChildren <Text>().text = ApplicationModel.CurrentBoneNumber.ToString(); Header.GetComponent <Image>().sprite = ThemeCacheClass.HeaderSprite; int i = 0; foreach (Image image in Animals.GetComponentsInChildren <Image>()) { //First is parent if (first) { first = false; continue; } image.sprite = ThemeCacheClass.AnimalList[i].Sprite; image.gameObject.name = ThemeCacheClass.AnimalList[i].Name; i++; } int k = 0; foreach (Image image in OrderCubes.GetComponentsInChildren <Image>(true)) { image.gameObject.SetActive(true); image.gameObject.name = ApplicationModel.correctCardOrder[k]; k++; if (k == level.AnimalsToOrderCount) { break; } } }
// Use this for initialization void Start() { LevelStructure level = new LevelStructure(); switch (level.Theme) { case ThemeEnum.Forest: ForestTheme.SetActive(true); ForestTheme.GetComponentInChildren <Text>().text = ApplicationModel.CurrentBoneNumber.ToString(); break; case ThemeEnum.Jungle: JungleTheme.SetActive(true); JungleTheme.GetComponentInChildren <Text>().text = ApplicationModel.CurrentBoneNumber.ToString(); break; case ThemeEnum.Farm: FarmTheme.SetActive(true); FarmTheme.GetComponentInChildren <Text>().text = ApplicationModel.CurrentBoneNumber.ToString(); break; case ThemeEnum.Mountain: MountainTheme.SetActive(true); MountainTheme.GetComponentInChildren <Text>().text = ApplicationModel.CurrentBoneNumber.ToString(); break; case ThemeEnum.Water: WaterTheme.SetActive(true); WaterTheme.GetComponentInChildren <Text>().text = ApplicationModel.CurrentBoneNumber.ToString(); break; case ThemeEnum.Safari: SafariTheme.SetActive(true); SafariTheme.GetComponentInChildren <Text>().text = ApplicationModel.CurrentBoneNumber.ToString(); break; } }
void Awake() { instance = this; numberOfColumns = transform.childCount; columnStructures = transform.GetComponentsInChildren <ColumnStructure>(); }
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); }
void GenerateCluster(Vector3 center) { // Is this... insane? StructureGenerator gen = this.GetComponent(typeof(StructureGenerator)) as StructureGenerator; for (int i = 0; i < NumStructures; i++) { LevelStructure structure = gen.Generate(1.0f, null); gen.CurrentGenerated = null; // look at me. I'm the owner now. if (structure.structurePerturbations.HasFlag(StructurePerturbations.RotateSpherical)) { if (UnityEngine.Random.value < 0.5f) { // Apply a fun perturbation. Maybe this should be in the structure generation? // https://docs.unity3d.com/ScriptReference/Random-rotation.html just, like, purely random? // Ah this is nice:https://www.youtube.com/watch?v=paJPbqpQIQc&feature=emb_logo Vector3 perturbation = UnityEngine.Random.insideUnitSphere; // between -1 and 1, apparently. perturbation *= 10; structure.transform.Rotate(perturbation); } } else if (structure.structurePerturbations.HasFlag(StructurePerturbations.RotateOverY)) { float coin = UnityEngine.Random.value; // Let's flip 90 degrees if (coin < 0.4f) { structure.transform.Rotate(0, 90, 0); } else if (coin < 0.5) { structure.transform.Rotate(0, UnityEngine.Random.Range(-179f, 180f), 0); } } //var structure = structurePrefabs.PickRandom<LevelStructure>().GenerateClone(); structure.transform.parent = transform; int bailCount = 0; do { var newVector = 30 * UnityEngine.Random.insideUnitSphere; newVector.x *= 2; newVector += center; structure.transform.position = newVector; Debug.Log("ITERATING"); Physics.SyncTransforms(); if (bailCount++ > 100) { break; } //} while (CollidesWithExistingObject(structure)); float radius = CenteredBalloonRadius(structure, structure.transform.childCount); Debug.Log("Found radius: " + radius); } while (CollidesWithExistingObject(structure) && CenteredBalloonRadius(structure, structure.transform.childCount) < 15); Debug.Log("ADDED!" + structure.transform.position); generatedStructures.Add(structure); } }
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); } }
void Awake() { instance = this; numberOfColumns = transform.GetChildCount(); columnStructures = transform.GetComponentsInChildren<ColumnStructure>(); }