using System; using System.Collections; using TMPro; using UnityEngine; using UnityEngine.UIElements; using UnityStandardAssets.Vehicles.Car; using static CommunicationEvents; using static GlobalBehaviour; public class FactSpawner : MonoBehaviour { public GameObject Sphere, Line, Ray, Angle, Ring, Circle; void Start() { AddFactEvent.AddListener(SpawnFactRepresentation); RemoveFactEvent.AddListener(DeleteObject); 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.Representation.AddComponent<AttachedPositionFunctionBehaviour>(); attachedBehaviour.URI = fact.Id; fact.Representation = attachedBehaviour.gameObject; } public void SpawnPoint(PointFact fact) { GameObject point = GameObject.Instantiate(Sphere); point.transform.position = fact.Position; point.transform.rotation = fact.Rotation; point.GetComponentInChildren<TextMeshPro>().text = fact.Label; point.GetComponent<FactObject>().URI = fact.Id; fact.Representation = point; } public void SpawnLine(LineFact fact) { //Change FactRepresentation to Line GameObject line = GameObject.Instantiate(Line); //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"; line.GetComponentInChildren<FactObject>().URI = fact.Id; fact.Representation = line; } public void SpawnRay(RayFact fact) { //Change FactRepresentation to Line GameObject line = GameObject.Instantiate(Ray); //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; line.GetComponentInChildren<FactObject>().URI = fact.Id; fact.Representation = line; } //Spawn an angle: point with id = angleFact.Pid2 is the point where the angle gets applied public void SpawnAngle(AbstractAngleFact fact) { Vector3 Psotion = fact.Position; Quaternion Rotation = fact.Rotation; float angleValue = fact.angle; //Change FactRepresentation to Angle GameObject angle = GameObject.Instantiate(Angle); //Place the Angle at position of point2 angle.transform.SetPositionAndRotation(Psotion, 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(angleValue, 2) + "°"; } //Generate angle mesh CircleSegmentGenerator[] segments = angle.GetComponentsInChildren<CircleSegmentGenerator>(); foreach (CircleSegmentGenerator c in segments) c.setAngle(angleValue); angle.GetComponentInChildren<FactObject>().URI = fact.Id; fact.Representation = angle; } public void SpawnRingAndCircle(CircleFact fact) { var ringAndCircleGO = new GameObject("RingAndCircle"); SpawnRing(fact, ringAndCircleGO.transform); SpawnCircle(fact, ringAndCircleGO.transform); //Move Ring to middlePoint ringAndCircleGO.transform.position = fact.Position; fact.Representation = ringAndCircleGO; } public void SpawnRing(CircleFact circleFact, Transform parent = null) { GameObject ring = GameObject.Instantiate(Ring, parent); var tori = ring.GetComponentsInChildren<TorusGenerator>(); var tmpText = ring.GetComponentInChildren<TextMeshPro>(); var FactObj = ring.GetComponentInChildren<FactObject>(); //Set radii foreach (var torus in tori) torus.torusRadius = circleFact.radius; tmpText.text = $"○{circleFact.Point1.Label}"; FactObj.URI = circleFact.Id; } public void SpawnCircle(CircleFact circleFact, Transform parent = null) { GameObject circle = Instantiate(Circle, parent); var FactObj = circle.GetComponentInChildren<FactObject>(); //Set radius circle.transform.localScale = Vector3.Scale(circle.transform.localScale, circleFact.LocalScale); FactObj.URI = circleFact.Id; } public void DeleteObject(Fact fact) => GameObject.Destroy(fact.Representation); public void animateNonExistingFactTrigger(Fact fact) { StartCoroutine(animateNonExistingFact(fact)); IEnumerator animateNonExistingFact(Fact fact) { SpawnFactRepresentation(fact); ShinyThings.HighlightFact(fact, FactObject.FactMaterials.Hint); yield return new WaitForSeconds(GlobalBehaviour.hintAnimationDuration); GameObject.Destroy(fact.Representation); } } }