using System; using System.Collections; using TMPro; using UnityEngine; using static CommunicationEvents; public class FactSpawner : MonoBehaviour { public GameObject Sphere, Line, Ray, Angle, Ring, Circle; void Start() { AddFactEvent.AddListener(SpawnFactRepresentation); AnimateNonExistingFactEvent.AddListener(AnimateNonExistingFactTrigger); } public void SpawnFactRepresentation(Fact fact) { switch (fact) { case PointFact PointFact: SpawnPoint(PointFact); break; case LineFact LineFact: SpawnLine(LineFact); break; //case RightAngleFact AngleFact: //needed for Hint System case AbstractAngleFact AngleFact: SpawnAngle(AngleFact); break; case RayFact RayFact: SpawnRay(RayFact); break; case CircleFact CircleFact: SpawnRingAndCircle(CircleFact); break; case AttachedPositionFunction AttachedPositionFunction: SpawnAttachedPositionFunction(AttachedPositionFunction); break; default: break; }; } public void SpawnAttachedPositionFunction(AttachedPositionFunction fact) { var attachedBehaviour = fact.Fact.WorldRepresentation.gameObject .AddComponent<AttachedPositionFunctionBehaviour>(); attachedBehaviour.Fact = fact; fact.WorldRepresentation = attachedBehaviour; } public void SpawnPoint(PointFact fact) { GameObject point = GameObject.Instantiate(Sphere); fact.WorldRepresentation = point.GetComponent<FactObject3D>(); fact.WorldRepresentation.Fact = fact; point.transform.SetPositionAndRotation(fact.Position, fact.Rotation); } public void SpawnLine(LineFact fact) { //Change FactRepresentation to Line GameObject line = GameObject.Instantiate(Line); fact.WorldRepresentation = line.GetComponentInChildren<FactObject3D>(); fact.WorldRepresentation.Fact = fact; //Place the Line in the centre of the two points line.transform.position = fact.Position; //Change scale and rotation, so that the two points are connected by the line //and without affecting Scale of the Text line.transform.GetChild(0).localScale = fact.LocalScale; line.transform.GetChild(0).rotation = fact.Rotation; line.GetComponentInChildren<TextMeshPro>().text = fact.Label + " = " + Math.Round(fact.Distance, 2) + " m"; } public void SpawnRay(RayFact fact) { //Change FactRepresentation to Line GameObject line = GameObject.Instantiate(Ray); fact.WorldRepresentation = line.GetComponentInChildren<FactObject3D>(); fact.WorldRepresentation.Fact = fact; //Place the Line in the centre of the two points line.transform.position = fact.Position; //Change scale and rotation, so that the two points are connected by the line //and without affecting Scale of the Text line.transform.GetChild(0).localScale = fact.LocalScale; line.transform.GetChild(0).rotation = fact.Rotation; } //Spawn an angle: point with id = angleFact.Pid2 is the point where the angle gets applied public void SpawnAngle(AbstractAngleFact fact) { //Change FactRepresentation to Angle GameObject angle = GameObject.Instantiate(Angle); fact.WorldRepresentation = angle.GetComponentInChildren<FactObject3D>(); fact.WorldRepresentation.Fact = fact; angle.transform.SetPositionAndRotation(fact.Position, fact.Rotation); //Set text of angle TextMeshPro[] texts = angle.GetComponentsInChildren<TextMeshPro>(); foreach (TextMeshPro t in texts) { //Change Text not to the id, but to the angle-value (from both sides) t.text = Math.Round((float)fact.angle, 2) + "°"; } //Generate angle mesh CircleSegmentGenerator[] segments = angle.GetComponentsInChildren<CircleSegmentGenerator>(); foreach (CircleSegmentGenerator c in segments) c.setAngle((float)fact.angle); } public void SpawnRingAndCircle(CircleFact fact) { var ringAndCircleGO = new GameObject("RingAndCircle"); SpawnRing(fact, ringAndCircleGO.transform); SpawnCircle(fact, ringAndCircleGO.transform); ringAndCircleGO.transform.SetPositionAndRotation(fact.Position, fact.Rotation); fact.WorldRepresentation = ringAndCircleGO.AddComponent<FactObject3D>(); fact.WorldRepresentation.Fact = fact; } public void SpawnRing(CircleFact circleFact, Transform parent = null) { GameObject ring = GameObject.Instantiate(Ring, parent); var tori = ring.GetComponentsInChildren<TorusGenerator>(); foreach (var torus in tori) torus.torusRadius = circleFact.radius + (float)Math3d.vectorPrecission; } public void SpawnCircle(CircleFact circleFact, Transform parent = null) { GameObject circle = Instantiate(Circle, parent); //Set radius circle.transform.localScale = Vector3.Scale(circle.transform.localScale, circleFact.LocalScale); } public void AnimateNonExistingFactTrigger(Fact fact) { StartCoroutine(_BlossomAndDie(fact)); IEnumerator _BlossomAndDie(Fact fact) { SpawnFactRepresentation(fact); yield return new WaitForSeconds(GlobalBehaviour.HintAnimationDuration); RemoveFactEvent.Invoke(fact); } } }