using System.Collections; using System.Collections.Generic; using UnityEngine; using static CommunicationEvents; 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; //Attributes for simulating the drawing of a line/curve public LineRenderer lineRenderer; private List<Vector3> linePositions = new List<Vector3>(); private bool lineDrawingActivated; private bool curveDrawingActivated; private int curveDrawingVertexCount = 12; private LineFact curveDrawingStartLine; private Vector3 curveEndPoint; private Vector3 angleMiddlePoint; // Start is called before the first frame update public void Start() { if (Cursor == null) Cursor = GetComponent<WorldCursor>(); CommunicationEvents.StartLineDrawingEvent.AddListener(ActivateLineDrawing); CommunicationEvents.StopLineDrawingEvent.AddListener(DeactivateLineDrawing); CommunicationEvents.StartCurveDrawingEvent.AddListener(ActivateCurveDrawing); CommunicationEvents.StopCurveDrawingEvent.AddListener(DeactivateCurveDrawing); } // Update is called once per frame public void Update() { //SELECTION-HIGHLIGHTING-PART //Check if a Fact was Hit RaycastHit Hit = Cursor.Hit; if (Hit.transform != null) { Transform selection = Hit.transform; //Set the last Fact unselected if (this.lastFactSelection != null) { //Invoke the EndHighlightEvent that will be handled in FactSpawner // CommunicationEvents.EndHighlightEvent.Invoke(this.lastFactSelection); OnMouseOverFactEnd(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); } //SELECTION-HIGHLIGHTING-PART-END //LineRendering-Part if (this.lineDrawingActivated) UpdateLineDrawing(Hit.point); else if (this.curveDrawingActivated) UpdateCurveDrawing(Hit.point); } } 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 ActivateLineDrawing(Fact startFact) { lineRenderer.startWidth = 0.095f; lineRenderer.endWidth = 0.095f; //Set LineDrawing activated this.lineDrawingActivated = true; //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]); } //Updates the second-point of the Line when First Point was selected in LineMode public void UpdateLineDrawing(Vector3 currentPosition) { this.linePositions[1] = currentPosition; this.lineRenderer.SetPosition(1, this.linePositions[1]); } //Deactivate LineDrawing so that no Line gets drawn when Cursor changes public void DeactivateLineDrawing(Fact startFact) { //Reset the first points this.lineRenderer.SetPosition(0, Vector3.zero); this.lineRenderer.SetPosition(1, Vector3.zero); if (linePositions.Count > 0) this.linePositions.Clear(); this.lineDrawingActivated = false; } //Expect a LineFact here, so that it's possible to change between two possible StartPoints public void ActivateCurveDrawing(Fact startFact) { lineRenderer.startWidth = 0.05f; lineRenderer.endWidth = 0.05f; //Set CurveDrawing activated this.curveDrawingActivated = true; curveDrawingStartLine = (LineFact)startFact; curveEndPoint = Cursor.transform.position; //Determine which point of the line is closer to the cursor and initialize angleMiddlePoint //angleMiddlePoint is needed for the Angle Preview float Distance1 = (Facts.Find(x => x.Id == curveDrawingStartLine.Pid1).Representation.transform.position - curveEndPoint).magnitude; float Distance2 = (Facts.Find(x => x.Id == curveDrawingStartLine.Pid2).Representation.transform.position - curveEndPoint).magnitude; if (Distance1 >= Distance2) angleMiddlePoint = Facts.Find(x => x.Id == curveDrawingStartLine.Pid2).Representation.transform.position; else angleMiddlePoint = Facts.Find(x => x.Id == curveDrawingStartLine.Pid1).Representation.transform.position; } public void UpdateCurveDrawing(Vector3 currentPosition) { //Determine the Center of Start-Point and End-Point Vector3 tempCenterPoint = Vector3.Lerp(currentPosition, curveEndPoint, 0.5f); Vector3 curveMiddlePoint = angleMiddlePoint + 2 * (tempCenterPoint - angleMiddlePoint); linePositions = new List<Vector3>(); for (float ratio = 0; ratio <= 1; ratio += 1.0f / this.curveDrawingVertexCount) { var tangentLineVertex1 = Vector3.Lerp(currentPosition, curveMiddlePoint, ratio); var tangentLineVertex2 = Vector3.Lerp(curveMiddlePoint, curveEndPoint, ratio); var bezierPoint = Vector3.Lerp(tangentLineVertex1, tangentLineVertex2, ratio); linePositions.Add(bezierPoint); } lineRenderer.positionCount = linePositions.Count; lineRenderer.SetPositions(linePositions.ToArray()); } public void DeactivateCurveDrawing(Fact startFact) { for (int i = 0; i < linePositions.Count; i++) { this.lineRenderer.SetPosition(i, Vector3.zero); } if (linePositions.Count > 0) this.linePositions.Clear(); this.curveDrawingActivated = false; } }