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>();
John Schihada
committed
public Material linePreviewMaterial;
public Material anglePreviewMaterial;
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; }
John Schihada
committed
private float timerDuration = 2.5f;
private float timerDurationEnd = 5.0f;
private int slowDownCount = 8;
private int slowDownCounter;
private bool[] slowDownSwitch;
private float simulationSpeed;
private Boolean pushoutFail;
public GameObject directionalLight;
private Color lightColor;
private Color tempColor;
private Color darkColor;
private Boolean factAnimationActive = false;
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);
John Schihada
committed
CommunicationEvents.PushoutFactFailEvent.AddListener(StartPushoutFactFailHighlighting);
speedSlowDown = timerDurationEnd * 10;
John Schihada
committed
lightColor = directionalLight.GetComponent<Light>().color;
slowDownSwitch = new bool[slowDownCount];
Array.Clear(slowDownSwitch, 0, slowDownSwitch.Length);
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);
John Schihada
committed
//If the Timer is Active, check Pushout-Highlighting
if (this.timerActive)
{
this.timer += Time.deltaTime;
John Schihada
committed
CheckPushoutHighlighting();
}
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) {
John Schihada
committed
GameObject fireworksRepresentation = (GameObject)Resources.Load("Prefabs/Fireworks_Animation", 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;
John Schihada
committed
this.pushoutFail = false;
this.slowDownCounter = 0;
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;
//Event for the happy Task-Charakter
CommunicationEvents.PushoutFactEndEvent.Invoke(null);
}
John Schihada
committed
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
public void StartPushoutFactFailHighlighting(Fact startFact)
{
this.pushoutFail = true;
this.tempColor = this.lightColor;
this.darkColor = new Color(0.6f, 0.6f, 0.6f);
this.timerActive = true;
}
public void CheckPushoutHighlighting() {
//If the Pushout suceeded -> Fireworks-Animation
if (this.pushoutFail == false)
{
//Fireworks already started in StartPushoutFactHighlighting
if (this.timer >= this.timerDuration)
{
//After this.timerDuration+this.timerDurationEnd: Destroy Fireworks-Animation
if (this.timer >= this.timerDuration + this.timerDurationEnd)
{
this.timerActive = false;
this.timer = 0;
StopPushoutFactHighlighting();
}
//After this.timerDuration: Slow Down Fireworks
else
{
ParticleSystem main1 = this.extraHighlight.transform.GetChild(0).GetComponent<ParticleSystem>();
ParticleSystem main2 = this.extraHighlight.transform.GetChild(1).GetComponent<ParticleSystem>();
//Save StartSpeed when first slowing down
if (this.slowDownCounter == 0)
this.simulationSpeed = main1.main.simulationSpeed;
slowDownAnimation(main1, main2);
}
}
}
//If the Pushout failed -> Rain-Animation
else
{
if (this.timer <= 0.5f * (this.timerDurationEnd))
{
//sky slowly gets dark
if (directionalLight.GetComponent<Light>().color.r > darkColor.r)
{
tempColor.r -= Time.deltaTime/5;
tempColor.g -= Time.deltaTime/5;
tempColor.b -= Time.deltaTime/5;
directionalLight.GetComponent<Light>().color = tempColor;
}
}
else if (this.timer <= 2.0f * this.timerDuration + 0.5f * this.timerDurationEnd)
{
//Rain-Animation starts
if (!factAnimationActive)
{
GameObject RainRepresentation = (GameObject)Resources.Load("Prefabs/Rainmaker/RainPrefab", typeof(GameObject));
RainRepresentation.transform.position = new Vector3(0, 40, 0);
this.extraHighlight = GameObject.Instantiate(RainRepresentation);
factAnimationActive = true;
}
}
//Rain-Animation stops and sky slowly gets bright again
else if (this.timer <= 2.0f * this.timerDuration + this.timerDurationEnd)
{
if (factAnimationActive)
{
//Stop Rain
GameObject.Destroy(this.extraHighlight);
this.extraHighlight = null;
factAnimationActive = false;
}
//sky slowly gets bright again
if (directionalLight.GetComponent<Light>().color.r <= lightColor.r)
{
tempColor.r += Time.deltaTime/5;
tempColor.g += Time.deltaTime/5;
tempColor.b += Time.deltaTime/5;
directionalLight.GetComponent<Light>().color = tempColor;
}
}
else
{
//Stop timer
this.timerActive = false;
this.timer = 0;
}
}
}
public void slowDownAnimation(ParticleSystem main1, ParticleSystem main2) {
if (this.timer <= this.timerDuration + (this.timerDurationEnd*((float)slowDownCounter+1.0f)/(float)slowDownCount))
{
if(slowDownSwitch[(int)((this.timer-this.timerDuration)/(this.timerDuration/(float)slowDownCount))] == false)
if (slowDownCounter < slowDownCount)
{
var mainModule1 = main1.main;
float speed = mainModule1.simulationSpeed;
mainModule1.simulationSpeed = speed - (float)(this.simulationSpeed / (float)slowDownCount);
var mainModule2 = main2.main;
mainModule2.simulationSpeed = speed - (float)(this.simulationSpeed / (float)slowDownCount);
slowDownSwitch[slowDownCounter] = true;
}
}
}
public void ActivateLineDrawing(Fact startFact)
{
John Schihada
committed
this.lineRenderer.material = this.linePreviewMaterial;
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;
John Schihada
committed
this.lineRenderer.material = this.anglePreviewMaterial;
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);
}