Skip to content
Snippets Groups Projects
FactSpawner.cs 7.51 KiB
Newer Older
  • Learn to ignore specific revisions
  • using System;
    using System.Collections;
    using TMPro;
    using UnityEngine;
    
    using static CommunicationEvents;
    
    
    public class FactSpawner : MonoBehaviour
    {
    
            AddFactEvent.AddListener(SpawnFactRepresentation_Wrapped);
    
            RemoveFactEvent.AddListener(DeleteObject);
    
    Richard Marcus's avatar
    Richard Marcus committed
    
    
            AnimateNonExistingFactEvent.AddListener(animateNonExistingFactTrigger);
    
        private void SpawnFactRepresentation_Wrapped(Fact fact) => SpawnFactRepresentation(fact);
    
        public Fact SpawnFactRepresentation(Fact fact)
    
            Func<Fact, Fact> func = fact switch
    
    MaZiFAU's avatar
    MaZiFAU committed
                PointFact => SpawnPoint,
                LineFact => SpawnLine,
                RightAngleFact => SpawnAngle, //needed for Hint System
                AngleFact => SpawnAngle,
                RayFact => SpawnRay,
                CircleFact => SpawnRingAndCircle,
    
    
            return func?.Invoke(fact);
    
    MaZiFAU's avatar
    MaZiFAU committed
    
    
        public Fact SpawnPoint(Fact pointFact)
    
            PointFact fact = ((PointFact)pointFact);
    
    MaZiFAU's avatar
    MaZiFAU committed
    
    
            GameObject point = GameObject.Instantiate(Sphere);
    
    John Schihada's avatar
    John Schihada committed
            point.transform.position = fact.Point;
            point.transform.up = fact.Normal;
    
            point.GetComponentInChildren<TextMeshPro>().text = fact.Label;
    
            point.GetComponent<FactObject>().URI = fact.Id;
    
    John Schihada's avatar
    John Schihada committed
            fact.Representation = point;
    
            return fact;
    
        public Fact SpawnLine(Fact fact)
    
            LineFact lineFact = ((LineFact)fact);
    
            GameObject line = GameObject.Instantiate(Line);
    
            //Place the Line in the centre of the two points
    
    MaZiFAU's avatar
    MaZiFAU committed
            line.transform.position = lineFact.Position;
    
            //Change scale and rotation, so that the two points are connected by the line
            //Get the Line-GameObject as the first Child of the Line-Prefab -> That's the Collider
            var v3T = line.transform.GetChild(0).localScale;
    
            //For every Coordinate x,y,z we have to devide it by the LocalScale of the Child,
            //because actually the Child should be of this length and not the parent, which is only the Collider
    
    MaZiFAU's avatar
    MaZiFAU committed
            v3T.x = lineFact.LocalScale.x / line.transform.GetChild(0).GetChild(0).localScale.x;
    
            //Change Scale/Rotation of the Line-GameObject without affecting Scale of the Text
            line.transform.GetChild(0).localScale = v3T;
    
    MaZiFAU's avatar
    MaZiFAU committed
            line.transform.GetChild(0).rotation = lineFact.Rotation;
    
    MaZiFAU's avatar
    MaZiFAU committed
            line.GetComponentInChildren<TextMeshPro>().text =
                lineFact.Label + " = " + Math.Round(lineFact.Distance, 2) + " m";
    
            line.GetComponentInChildren<FactObject>().URI = lineFact.Id;
    
    MaZiFAU's avatar
    MaZiFAU committed
    
    
            return lineFact;
    
        public Fact SpawnRay(Fact fact)
    
            RayFact rayFact = ((RayFact)fact);
    
            GameObject line = GameObject.Instantiate(Ray);
    
            //Place the Line in the centre of the two points
    
    MaZiFAU's avatar
    MaZiFAU committed
            line.transform.position = rayFact.Position;
    
            //Change scale and rotation, so that the two points are connected by the line
            //Get the Line-GameObject as the first Child of the Line-Prefab -> That's the Collider
            var v3T = line.transform.GetChild(0).localScale;
    
            //For every Coordinate x,y,z we have to devide it by the LocalScale of the Child,
            //because actually the Child should be of this length and not the parent, which is only the Collider
    
    MaZiFAU's avatar
    MaZiFAU committed
            v3T.x = rayFact.LocalScale.x / line.transform.GetChild(0).GetChild(0).localScale.x;
    
            //Change Scale/Rotation of the Line-GameObject without affecting Scale of the Text
            line.transform.GetChild(0).localScale = v3T;
    
    MaZiFAU's avatar
    MaZiFAU committed
            line.transform.GetChild(0).rotation = rayFact.Rotation;
    
            line.GetComponentInChildren<TextMeshPro>().text = rayFact.Label;
    
            line.GetComponentInChildren<FactObject>().URI = rayFact.Id;
    
            rayFact.Representation = line;
            return rayFact;
    
    MaZiFAU's avatar
    MaZiFAU committed
    
    
        //Spawn an angle: point with id = angleFact.Pid2 is the point where the angle gets applied
    
        public Fact SpawnAngle(Fact fact)
    
    MaZiFAU's avatar
    MaZiFAU committed
            Vector3 Psotion;
            Quaternion Rotation;
            float angleValue;
    
    MaZiFAU's avatar
    MaZiFAU committed
    
            // TODO: just use simple inheritence or similar!!
            if (fact is RightAngleFact rightangleFact)
            {
    
    MaZiFAU's avatar
    MaZiFAU committed
                Psotion = rightangleFact.Position;
                Rotation = rightangleFact.Rotation;
                angleValue = 90f;
    
    MaZiFAU's avatar
    MaZiFAU committed
            }
            else if (fact is AngleFact angleFact)
            {
    
    MaZiFAU's avatar
    MaZiFAU committed
                Psotion = angleFact.Position;
                Rotation = angleFact.Rotation;
                angleValue = angleFact.angle;
    
    MaZiFAU's avatar
    MaZiFAU committed
            else
    
    MaZiFAU's avatar
    MaZiFAU committed
                throw new Exception("Invalid Type:" + fact.GetType().ToString());
    
    
            //Change FactRepresentation to Angle
    
            GameObject angle = GameObject.Instantiate(Angle);
    
            //Place the Angle at position of point2
    
    MaZiFAU's avatar
    MaZiFAU committed
            angle.transform.SetPositionAndRotation(Psotion, Rotation);
    
            TextMeshPro[] texts = angle.GetComponentsInChildren<TextMeshPro>();
    
    MaZiFAU's avatar
    MaZiFAU committed
            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) + "°";
    
            CircleSegmentGenerator[] segments = angle.GetComponentsInChildren<CircleSegmentGenerator>();
            foreach (CircleSegmentGenerator c in segments)
                c.setAngle(angleValue);
    
    
    MaZiFAU's avatar
    MaZiFAU committed
            angle.GetComponentInChildren<FactObject>().URI = fact.Id;
            fact.Representation = angle;
            return fact;
    
        public Fact SpawnRingAndCircle(Fact fact)
        {
    
    MaZiFAU's avatar
    MaZiFAU committed
            CircleFact circleFact = fact as CircleFact;
    
    
            var ringAndCircleGO = new GameObject("RingAndCircle");
    
    MaZiFAU's avatar
    MaZiFAU committed
            SpawnRing(circleFact, ringAndCircleGO.transform);
            SpawnCircle(circleFact, ringAndCircleGO.transform);
    
    MaZiFAU's avatar
    MaZiFAU committed
            //Move Ring to middlePoint
            ringAndCircleGO.transform.position = circleFact.Position;
    
    MaZiFAU's avatar
    MaZiFAU committed
            fact.Representation = ringAndCircleGO;
            return fact;
    
    MaZiFAU's avatar
    MaZiFAU committed
        public void SpawnRing(CircleFact circleFact, Transform parent = null)
    
    MaZiFAU's avatar
    MaZiFAU committed
            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)
    
    MaZiFAU's avatar
    MaZiFAU committed
                torus.torusRadius = circleFact.radius;
    
    MaZiFAU's avatar
    MaZiFAU committed
            tmpText.text = $"○{circleFact.Point1.Label}";
    
    MaZiFAU's avatar
    MaZiFAU committed
        public void SpawnCircle(CircleFact circleFact, Transform parent = null)
    
    ki7077's avatar
    ki7077 committed
            GameObject circle = Instantiate(Circle, parent);
    
            var FactObj = circle.GetComponentInChildren<FactObject>();
    
    
    MaZiFAU's avatar
    MaZiFAU committed
            circle.transform.localScale = Vector3.Scale(circle.transform.localScale, circleFact.LocalScale);
    
    
            FactObj.URI = circleFact.Id;
        }
    
    
    MaZiFAU's avatar
    MaZiFAU committed
            => GameObject.Destroy(fact.Representation);
    
    MaZiFAU's avatar
    MaZiFAU committed
        public void animateNonExistingFactTrigger(Fact fact)
        {
    
            StartCoroutine(animateNonExistingFact(fact));
    
    
            IEnumerator animateNonExistingFact(Fact fact)
            {
                Fact returnedFact = SpawnFactRepresentation(fact);
    
                ShinyThings.HighlightFact(returnedFact, FactObject.FactMaterials.Hint);
    
                yield return new WaitForSeconds(GlobalBehaviour.hintAnimationDuration);
    
                GameObject.Destroy(returnedFact.Representation);
            }