Skip to content
Snippets Groups Projects
ShinyThings.cs 14.8 KiB
Newer Older
  • Learn to ignore specific revisions
  • using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    John Schihada's avatar
    John Schihada committed
    using UnityEditor;
    
    John Schihada's avatar
    John Schihada committed
    using static CommunicationEvents;
    
    using System;
    
    
    public class ShinyThings : MonoBehaviour
    {
        public WorldCursor Cursor;
        //Attributes for Highlighting of Facts when Mouse-Over
        private string selectableTag = "Selectable";
        private Transform lastFactSelection;
    
        public Material defaultMaterial;
        public Material highlightMaterial;
    
    
    John Schihada's avatar
    John Schihada committed
        //Attributes for simulating the drawing of a line/curve
    
        public LineRenderer lineRenderer;
        private List<Vector3> linePositions = new List<Vector3>();
    
    John Schihada's avatar
    John Schihada committed
    
        private bool lineDrawingActivated;
        private bool curveDrawingActivated;
    
        //These are only the vertices for the Curve
    
    John Schihada's avatar
    John Schihada committed
        private int curveDrawingVertexCount = 36;
    
    John Schihada's avatar
    John Schihada committed
        private LineFact curveDrawingStartLine;
        private Vector3 curveEndPoint;
        private Vector3 angleMiddlePoint;
    
    John Schihada's avatar
    John Schihada committed
        private float curveRadius;
    
        //Variables for Pushout-Highlighting
        private Fact highlightedPushoutFact;
    
        private GameObject extraHighlight;
    
        private bool timerActive { get; set; }
        private float timer { get; set; }
    
        private float timerDuration = 5.0f;
        private float timerDurationEnd = 2.5f;
        private float speedSlowDown;
    
        public Material pushoutMaterial;
        private Material tempMaterial;
    
    
        // Start is called before the first frame update
    
    John Schihada's avatar
    John Schihada committed
        public void Start()
    
    John Schihada's avatar
    John Schihada committed
            if (Cursor == null) Cursor = GetComponent<WorldCursor>();
            CommunicationEvents.StartLineDrawingEvent.AddListener(ActivateLineDrawing);
            CommunicationEvents.StopLineDrawingEvent.AddListener(DeactivateLineDrawing);
            CommunicationEvents.StartCurveDrawingEvent.AddListener(ActivateCurveDrawing);
            CommunicationEvents.StopCurveDrawingEvent.AddListener(DeactivateCurveDrawing);
    
            CommunicationEvents.StopPreviewsEvent.AddListener(StopPreviews);
    
            CommunicationEvents.PushoutFactEvent.AddListener(StartPushoutFactHighlighting);
    
            speedSlowDown = timerDurationEnd * 10;
    
    
            this.timerActive = false;
            this.timer = 0;
    
        }
    
        // Update is called once per frame
    
    John Schihada's avatar
    John Schihada committed
        public void Update()
    
        {
            //SELECTION-HIGHLIGHTING-PART
            //Check if a Fact was Hit
    
    
            Highlighting(Hit);
    
           
            //LineRendering-Part
    
            //@John before:  hit.point
    
    
            //Debug.Log(this.transform.position);
    
    
            if (this.lineDrawingActivated)
                UpdateLineDrawing(this.transform.position);
            else if (this.curveDrawingActivated)
                UpdateCurveDrawing(this.transform.position);
    
    
            //If the Timer is Active, check if timerDuration is reached and stop Pushout-Highlighting
            if (this.timerActive)
            {
                this.timer += Time.deltaTime;
                if (this.timer >= this.timerDuration)
                {
    
                    if (this.timer >= this.timerDuration + this.timerDurationEnd)
                    {
                        this.timerActive = false;
                        this.timer = 0;
                        StopPushoutFactHighlighting();
                    }
                    else {
                        var main = this.extraHighlight.transform.GetChild(0).GetComponent<ParticleSystem>().main;
                        speedSlowDown -= Time.deltaTime * 10;
                        main.startSpeed = speedSlowDown;
                        main = this.extraHighlight.transform.GetChild(1).GetComponent<ParticleSystem>().main;
                        main.startSpeed = speedSlowDown;
                    }
    
        }
    
        private void Highlighting(RaycastHit hit)
        {
            if (hit.transform != null)
    
                Transform selection = hit.transform;
    
                //only do stuff if selection changes
    
    
                //Set the last Fact unselected
                if (this.lastFactSelection != null)
                {
    
                    if (selection == this.lastFactSelection) return;
    
                    //Invoke the EndHighlightEvent that will be handled in FactSpawner
                    // CommunicationEvents.EndHighlightEvent.Invoke(this.lastFactSelection);
    
                    if (this.lastFactSelection.CompareTag(selectableTag))
                        OnMouseOverFactEnd(lastFactSelection);
                    else
                        OnMouseOverSnapZoneEnd(lastFactSelection);
    
                    this.lastFactSelection = null;
                }
    
                //Set the Fact that was Hit as selected
                if (selection.CompareTag(selectableTag))
                {
                    //Invoke the HighlightEvent that will be handled in FactSpawner
                    this.lastFactSelection = selection;
                    //CommunicationEvents.HighlightEvent.Invoke(selection);
                    OnMouseOverFact(lastFactSelection);
                }
    
                else if (selection.CompareTag("SnapZone"))
                {
                    this.lastFactSelection = selection;
                    OnMouseOverSnapZone(lastFactSelection);
    
                }
            }
    
    
            //SELECTION-HIGHLIGHTING-PART-END
        }
    
        private void OnMouseOverSnapZoneEnd(Transform selection)
        {
            Renderer selectionRenderer;
    
            if (selection != null)
            {
                selectionRenderer = selection.GetComponent<Renderer>();
                if (selectionRenderer != null)
                {
                    //Add transparency
                    var oldCol = selectionRenderer.material.color;
                    oldCol.a = .25f;
                    selectionRenderer.material.color = oldCol;
                    //Unhide Mouse cursor
                    UnityEngine.Cursor.visible = true;
                }
    
        private void OnMouseOverSnapZone(Transform selection)
        {
            Renderer selectionRenderer;
            selectionRenderer = selection.GetComponent<Renderer>();
            if (selectionRenderer != null)
            {
                //Remove transparency
                var oldCol = selectionRenderer.material.color;
    
                selectionRenderer.material.color = oldCol;
    
                //Hide Mouse cursor
               UnityEngine.Cursor.visible = false;
    
            }
    
    John Schihada's avatar
    John Schihada committed
        public void OnMouseOverFact(Transform selection)
        {
            Renderer selectionRenderer;
            selectionRenderer = selection.GetComponent<Renderer>();
            if (selectionRenderer != null)
            {
                //Set the Material of the Fact, where the mouse is over, to a special one
                selectionRenderer.material = highlightMaterial;
            }
        }
    
    
        public void OnMouseOverFactEnd(Transform selection)
        {
            Renderer selectionRenderer;
    
            if (selection != null)
            {
                selectionRenderer = selection.GetComponent<Renderer>();
                if (selectionRenderer != null)
                {
                    //Set the Material of the fact back to default
                    selectionRenderer.material = defaultMaterial;
                }
            }
        }
    
    
        public void StartPushoutFactHighlighting(Fact startFact) {
    
    
            GameObject fireworksRepresentation = (GameObject)Resources.Load("Prefabs/Fireworks", typeof(GameObject));
    
            highlightedPushoutFact = startFact;
    
            if (typeof(PointFact).IsInstanceOfType(highlightedPushoutFact))
            {
                PointFact fact = (PointFact)highlightedPushoutFact;
                tempMaterial = fact.Representation.transform.GetChild(0).GetComponent<MeshRenderer>().material;
                fact.Representation.transform.GetChild(0).GetComponent<MeshRenderer>().material = pushoutMaterial;
    
                this.extraHighlight = GameObject.Instantiate(fireworksRepresentation);
                this.extraHighlight.transform.position = fact.Representation.transform.position;
    
            }
            else if (typeof(LineFact).IsInstanceOfType(highlightedPushoutFact))
            {
                LineFact fact = (LineFact)highlightedPushoutFact;
                tempMaterial = fact.Representation.transform.GetChild(0).GetChild(0).GetComponent<MeshRenderer>().material;
                fact.Representation.transform.GetChild(0).GetChild(0).GetComponent<MeshRenderer>().material = pushoutMaterial;
    
                this.extraHighlight = GameObject.Instantiate(fireworksRepresentation);
                this.extraHighlight.transform.position = fact.Representation.transform.position;
    
            }
            else if (typeof(AngleFact).IsInstanceOfType(highlightedPushoutFact)) {
                AngleFact fact = (AngleFact)highlightedPushoutFact;
                tempMaterial = fact.Representation.transform.GetChild(0).GetChild(0).GetComponent<MeshRenderer>().material;
                fact.Representation.transform.GetChild(0).GetChild(0).GetComponent<MeshRenderer>().material = pushoutMaterial;
    
                this.extraHighlight = GameObject.Instantiate(fireworksRepresentation);
                this.extraHighlight.transform.position = fact.Representation.transform.position;
    
            }
    
            //Activate Timer
            this.timerActive = true;
        }
    
        public void StopPushoutFactHighlighting() {
    
            if (typeof(PointFact).IsInstanceOfType(highlightedPushoutFact))
            {
                PointFact fact = (PointFact)highlightedPushoutFact;
                fact.Representation.transform.GetChild(0).GetComponent<MeshRenderer>().material = tempMaterial;
            }
            else if (typeof(LineFact).IsInstanceOfType(highlightedPushoutFact))
            {
                LineFact fact = (LineFact)highlightedPushoutFact;
                fact.Representation.transform.GetChild(0).GetChild(0).GetComponent<MeshRenderer>().material = tempMaterial;
            }
            else if (typeof(AngleFact).IsInstanceOfType(highlightedPushoutFact))
            {
                AngleFact fact = (AngleFact)highlightedPushoutFact;
                fact.Representation.transform.GetChild(0).GetChild(0).GetComponent<MeshRenderer>().material = tempMaterial;
            }
    
    
            GameObject.Destroy(this.extraHighlight);
            this.extraHighlight = null;
    
    John Schihada's avatar
    John Schihada committed
        public void ActivateLineDrawing(Fact startFact)
        {
    
            this.lineRenderer.positionCount = 2;
    
    
    John Schihada's avatar
    John Schihada committed
            lineRenderer.startWidth = 0.095f;
            lineRenderer.endWidth = 0.095f;
            //Set LineDrawing activated
            this.lineDrawingActivated = true;
    
    John Schihada's avatar
    John Schihada committed
            //Add the position of the Fact for the start of the Line
            linePositions.Add(startFact.Representation.transform.position);
            //The second point is the same point at the moment
            linePositions.Add(startFact.Representation.transform.position);
    
            this.lineRenderer.SetPosition(0, linePositions[0]);
            this.lineRenderer.SetPosition(1, linePositions[1]);
    
    John Schihada's avatar
    John Schihada committed
        //Updates the second-point of the Line when First Point was selected in LineMode
    
        public void UpdateLineDrawing(Vector3 currentPosition)
    
    John Schihada's avatar
    John Schihada committed
        {
            this.linePositions[1] = currentPosition;
            this.lineRenderer.SetPosition(1, this.linePositions[1]);
        }
    
    John Schihada's avatar
    John Schihada committed
        //Deactivate LineDrawing so that no Line gets drawn when Cursor changes
    
        public void DeactivateLineDrawing(Fact startFact)
    
            this.lineRenderer.positionCount = 0;
            this.linePositions = new List<Vector3>();
    
    John Schihada's avatar
    John Schihada committed
            this.lineDrawingActivated = false;
    
        //Expect a LineFact here, where Line.Pid2 will be the Basis-Point of the angle
    
    John Schihada's avatar
    John Schihada committed
        public void ActivateCurveDrawing(Fact startFact)
        {
    
            //In AngleMode with 3 Points we want to draw nearly a rectangle so we add a startPoint and an Endpoint to this preview
            this.lineRenderer.positionCount = curveDrawingVertexCount + 2;
    
    John Schihada's avatar
    John Schihada committed
            lineRenderer.startWidth = 0.05f;
            lineRenderer.endWidth = 0.05f;
    
            //Set CurveDrawing activated
            this.curveDrawingActivated = true;
    
            curveDrawingStartLine = (LineFact)startFact;
    
            PointFact curveDrawingPoint1 = (PointFact)Facts.Find(x => x.Id == curveDrawingStartLine.Pid1);
            PointFact curveDrawingPoint2 = (PointFact)Facts.Find(x => x.Id == curveDrawingStartLine.Pid2);
    
            //curveEndPoint is a point on the Line selected, with some distance from point2
            curveEndPoint = curveDrawingPoint2.Point + 0.3f * (curveDrawingPoint1.Point - curveDrawingPoint2.Point).magnitude * (curveDrawingPoint1.Point - curveDrawingPoint2.Point).normalized;
            
            angleMiddlePoint = curveDrawingPoint2.Point;
            curveRadius = (curveEndPoint - curveDrawingPoint2.Point).magnitude;
    
    John Schihada's avatar
    John Schihada committed
        public void UpdateCurveDrawing(Vector3 currentPosition)
        {
    
    
            //Find the nearest of all potential third points
            PointFact nearestPoint = null;
            foreach (Fact fact in Facts) {
                if (fact is PointFact && fact.Id != curveDrawingStartLine.Pid1 && fact.Id != curveDrawingStartLine.Pid2 && nearestPoint == null)
                    nearestPoint = (PointFact)fact;
                else if (fact is PointFact && fact.Id != curveDrawingStartLine.Pid1 && fact.Id != curveDrawingStartLine.Pid2 && (nearestPoint.Point - currentPosition).magnitude > (((PointFact)fact).Point - currentPosition).magnitude)
                    nearestPoint = (PointFact)fact;
            }
    
            Vector3 startPoint = new Vector3(0,0,0);
    
            if (nearestPoint != null)
            {
                Vector3 planePoint = Vector3.ProjectOnPlane(currentPosition, Vector3.Cross((nearestPoint.Point-angleMiddlePoint), (curveEndPoint-angleMiddlePoint)));
    
                //Determine the Start-Point for the nearest third-point
                startPoint = angleMiddlePoint + curveRadius * (planePoint - angleMiddlePoint).normalized;
            }
            else
            {
                //Determine the Start-Point
                startPoint = angleMiddlePoint + curveRadius * (currentPosition - angleMiddlePoint).normalized;
            }
    
    
    John Schihada's avatar
    John Schihada committed
            //Determine the Center of Start-Point and End-Point 
    
    John Schihada's avatar
    John Schihada committed
            Vector3 tempCenterPoint = Vector3.Lerp(startPoint, curveEndPoint, 0.5f);
            Vector3 curveMiddlePoint = angleMiddlePoint + curveRadius * (tempCenterPoint - angleMiddlePoint).normalized;
    
    John Schihada's avatar
    John Schihada committed
            linePositions = new List<Vector3>();
    
            //Start: AngleMiddlePoint -> FirstPoint of Curve
            linePositions.Add(((PointFact)Facts.Find(x => x.Id == curveDrawingStartLine.Pid2)).Point);
    
    John Schihada's avatar
    John Schihada committed
            for (float ratio = 0; ratio <= 1; ratio += 1.0f / this.curveDrawingVertexCount)
            {
    
    John Schihada's avatar
    John Schihada committed
                var tangentLineVertex1 = Vector3.Lerp(startPoint, curveMiddlePoint, ratio);
    
    John Schihada's avatar
    John Schihada committed
                var tangentLineVertex2 = Vector3.Lerp(curveMiddlePoint, curveEndPoint, ratio);
                var bezierPoint = Vector3.Lerp(tangentLineVertex1, tangentLineVertex2, ratio);
                linePositions.Add(bezierPoint);
            }
    
    
            //End: LastPoint of Curve -> AngleMiddlePoint
            linePositions.Add(((PointFact)Facts.Find(x => x.Id == curveDrawingStartLine.Pid2)).Point);
    
    
    John Schihada's avatar
    John Schihada committed
            lineRenderer.positionCount = linePositions.Count;
            lineRenderer.SetPositions(linePositions.ToArray());
    
    John Schihada's avatar
    John Schihada committed
        public void DeactivateCurveDrawing(Fact startFact)
        {
    
            
            this.lineRenderer.positionCount = 0;
            this.linePositions = new List<Vector3>();
    
    John Schihada's avatar
    John Schihada committed
            this.curveDrawingActivated = false;
    
    
        public void StopPreviews(Fact startFact) {
            if (lineDrawingActivated)
                DeactivateLineDrawing(null);
            if (curveDrawingActivated)
                DeactivateCurveDrawing(null);
        }