Newer
Older
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
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;
John Schihada
committed
//These are only the vertices for the Curve
private LineFact curveDrawingStartLine;
private Vector3 curveEndPoint;
private Vector3 angleMiddlePoint;
//Variables for Pushout-Highlighting
private Fact highlightedPushoutFact;
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
if (Cursor == null) Cursor = GetComponent<WorldCursor>();
CommunicationEvents.StartLineDrawingEvent.AddListener(ActivateLineDrawing);
CommunicationEvents.StopLineDrawingEvent.AddListener(DeactivateLineDrawing);
CommunicationEvents.StartCurveDrawingEvent.AddListener(ActivateCurveDrawing);
CommunicationEvents.StopCurveDrawingEvent.AddListener(DeactivateCurveDrawing);
John Schihada
committed
CommunicationEvents.StopPreviewsEvent.AddListener(StopPreviews);
CommunicationEvents.PushoutFactEvent.AddListener(StartPushoutFactHighlighting);
speedSlowDown = timerDurationEnd * 10;
this.timerActive = false;
this.timer = 0;
}
// Update is called once per frame
{
//SELECTION-HIGHLIGHTING-PART
//Check if a Fact was Hit
RaycastHit Hit = Cursor.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;
oldCol.a = .75f;
//Hide Mouse cursor
UnityEngine.Cursor.visible = false;
}
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;
public void ActivateLineDrawing(Fact startFact)
{
this.lineRenderer.positionCount = 2;
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
John Schihada
committed
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
John Schihada
committed
public void DeactivateLineDrawing(Fact startFact)
this.lineRenderer.positionCount = 0;
this.linePositions = new List<Vector3>();
John Schihada
committed
John Schihada
committed
//Expect a LineFact here, where Line.Pid2 will be the Basis-Point of the angle
public void ActivateCurveDrawing(Fact startFact)
{
John Schihada
committed
//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;
lineRenderer.startWidth = 0.05f;
lineRenderer.endWidth = 0.05f;
//Set CurveDrawing activated
this.curveDrawingActivated = true;
curveDrawingStartLine = (LineFact)startFact;
John Schihada
committed
PointFact curveDrawingPoint1 = (PointFact)Facts.Find(x => x.Id == curveDrawingStartLine.Pid1);
PointFact curveDrawingPoint2 = (PointFact)Facts.Find(x => x.Id == curveDrawingStartLine.Pid2);
John Schihada
committed
//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
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;
}
Vector3 tempCenterPoint = Vector3.Lerp(startPoint, curveEndPoint, 0.5f);
Vector3 curveMiddlePoint = angleMiddlePoint + curveRadius * (tempCenterPoint - angleMiddlePoint).normalized;
John Schihada
committed
//Start: AngleMiddlePoint -> FirstPoint of Curve
linePositions.Add(((PointFact)Facts.Find(x => x.Id == curveDrawingStartLine.Pid2)).Point);
John Schihada
committed
for (float ratio = 0; ratio <= 1; ratio += 1.0f / this.curveDrawingVertexCount)
{
var tangentLineVertex1 = Vector3.Lerp(startPoint, curveMiddlePoint, ratio);
var tangentLineVertex2 = Vector3.Lerp(curveMiddlePoint, curveEndPoint, ratio);
var bezierPoint = Vector3.Lerp(tangentLineVertex1, tangentLineVertex2, ratio);
linePositions.Add(bezierPoint);
}
John Schihada
committed
//End: LastPoint of Curve -> AngleMiddlePoint
linePositions.Add(((PointFact)Facts.Find(x => x.Id == curveDrawingStartLine.Pid2)).Point);
lineRenderer.positionCount = linePositions.Count;
lineRenderer.SetPositions(linePositions.ToArray());
John Schihada
committed
}
public void DeactivateCurveDrawing(Fact startFact)
{
this.lineRenderer.positionCount = 0;
this.linePositions = new List<Vector3>();
John Schihada
committed
}
John Schihada
committed
public void StopPreviews(Fact startFact) {
if (lineDrawingActivated)
DeactivateLineDrawing(null);
if (curveDrawingActivated)
DeactivateCurveDrawing(null);
}