diff --git a/Assets/Resources/Prefabs/Facts/Point.prefab b/Assets/Resources/Prefabs/Facts/Point.prefab
index 9ea49bf45ccc46274887b99d43bd8fc5bc824a73..8fb17b2dcf588320298cc0107e108982237d0c77 100644
--- a/Assets/Resources/Prefabs/Facts/Point.prefab
+++ b/Assets/Resources/Prefabs/Facts/Point.prefab
@@ -115,6 +115,7 @@ MonoBehaviour:
   m_Script: {fileID: 11500000, guid: 626c435b76e0d334f959ede8b54b07ac, type: 3}
   m_Name: 
   m_EditorClassIdentifier: 
+  _URI: 
   FactText:
   - {fileID: 4028707725789292921}
   StringLabelFormats:
@@ -384,6 +385,7 @@ MonoBehaviour:
   m_Script: {fileID: 11500000, guid: 626c435b76e0d334f959ede8b54b07ac, type: 3}
   m_Name: 
   m_EditorClassIdentifier: 
+  _URI: 
   FactText: []
   StringLabelFormats: []
   renderer: []
diff --git a/Assets/Resources/Prefabs/UI/Scrolls/ScollFactContainer.prefab b/Assets/Resources/Prefabs/UI/Scrolls/ScollFactContainer.prefab
index ad27123d96cef2d5af974fd8189f5dcbaba22aa1..6fd3e3cc8fb4ab4410d334fdd848683102b1443f 100644
--- a/Assets/Resources/Prefabs/UI/Scrolls/ScollFactContainer.prefab
+++ b/Assets/Resources/Prefabs/UI/Scrolls/ScollFactContainer.prefab
@@ -11,7 +11,6 @@ GameObject:
   - component: {fileID: 7249550241351237421}
   - component: {fileID: 3905790850577996765}
   - component: {fileID: 1086451024575209643}
-  - component: {fileID: 6647832152850111550}
   m_Layer: 5
   m_Name: ScollFactContainer
   m_TagString: Untagged
@@ -29,6 +28,7 @@ RectTransform:
   m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
   m_LocalPosition: {x: 0, y: 0, z: 0}
   m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
   m_Children: []
   m_Father: {fileID: 0}
   m_RootOrder: 0
@@ -61,6 +61,7 @@ MonoBehaviour:
   m_Material: {fileID: 0}
   m_Color: {r: 0, g: 0.15233111, b: 0.9245283, a: 0.392}
   m_RaycastTarget: 1
+  m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
   m_Maskable: 1
   m_OnCullStateChanged:
     m_PersistentCalls:
@@ -75,16 +76,3 @@ MonoBehaviour:
   m_FillOrigin: 0
   m_UseSpriteMesh: 0
   m_PixelsPerUnitMultiplier: 1
---- !u!114 &6647832152850111550
-MonoBehaviour:
-  m_ObjectHideFlags: 0
-  m_CorrespondingSourceObject: {fileID: 0}
-  m_PrefabInstance: {fileID: 0}
-  m_PrefabAsset: {fileID: 0}
-  m_GameObject: {fileID: 8260792079148133554}
-  m_Enabled: 1
-  m_EditorHideFlags: 0
-  m_Script: {fileID: 11500000, guid: 714c3b3ded45aea408421f43873d5e17, type: 3}
-  m_Name: 
-  m_EditorClassIdentifier: 
-  associatedDropHandling: {fileID: 0}
diff --git a/Assets/Scripts/InteractionEngine/FactHandling/FactObject.cs b/Assets/Scripts/InteractionEngine/FactHandling/FactObject.cs
index c4986953c485043159a46a6b86c1fddad106d919..242e9d4b86db25e710aa6971a999fd6a21a66310 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/FactObject.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/FactObject.cs
@@ -74,7 +74,7 @@ void ISerializationCallbackReceiver.OnBeforeSerialize()
                 {
                     collider.gameObject.AddComponent<FactObject>();
                 }
-                catch(Exception) { }
+                catch (Exception) { }
         }
 #endif
     }
@@ -121,16 +121,17 @@ public void ReLabel()
                 : "N/A")
             .ToArray();
 
-        string indexoverflow = "{" + mother_child_labels.Length.ToString() + "}";
-
         for (int i = 0; i < Math.Min(FactText.Count(), StringLabelFormats.Count()); i++)
         {
-            if (StringLabelFormats[i].Contains(indexoverflow))
+            try
+            {
+                FactText[i].text = string.Format(StringLabelFormats[i], mother_child_labels);
+            }
+            catch (Exception ex)
             {
-                Debug.LogWarning("Format contains illegal Argument and will be ignored: " + indexoverflow);
-                continue;
+                Debug.LogError(ex);
+                FactText[i].text = "Err";
             }
-            FactText[i].text = string.Format(StringLabelFormats[i], mother_child_labels);
         }
 
         switch (Fact) // for highly customized labels
diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs b/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs
index 7922bd701aac4f877a0b69ed62ce9f8b205865cd..434c83285e3f89111b6188b6a91defba0f165a47 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs
@@ -414,15 +414,15 @@ public void SendToMMT()
         MMTDeclaration mmtDecl = MakeMMTDeclaration();
 
         GlobalBehaviour.Instance.StartCoroutine(
-            FetchURICoroutine = sendAdd(
+            FetchURICoroutine = _SendAdd(
                 CommunicationEvents.ServerAdress + "/fact/add",
                 mmtDecl.ToJson(),
-                (string uri) => sendURICallback(mmtDecl, uri)
+                (string uri) => _SendURICallback(mmtDecl, uri)
         ));
 
         return;
 
-        void sendURICallback(MMTDeclaration mmtDecl, string uri)
+        void _SendURICallback(MMTDeclaration mmtDecl, string uri)
         {
             this._URI = uri;
 
@@ -430,7 +430,7 @@ void sendURICallback(MMTDeclaration mmtDecl, string uri)
                 ParsingDictionary.parseTermsToId[mMTSymbol.defines.ToString()] = uri;
         }
 
-        IEnumerator sendAdd(string path, string body, Action<string> uriCallback)
+        IEnumerator _SendAdd(string path, string body, Action<string> uriCallback)
         {
             if (!CommunicationEvents.ServerRunning)
             {
@@ -1038,7 +1038,7 @@ protected override string[] GetGetDependentFactIds()
     protected override bool EquivalentWrapped(CircleFact f1, CircleFact f2)
         => DependentFactsEquivalent(f1, f2)
         && Math3d.IsApproximatelyEqual(f1.normal, f2.normal)
-        && f1.radius.IsApproximatelyEqual(f2.radius);
+        && Mathf.Approximately(f1.radius, f2.radius);
 
     protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactOrganizer organizer)
         => new CircleFact(old_to_new[this.Pid1], old_to_new[this.Pid2], this.radius, this.normal, organizer);
diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Facts/FunctionFact.cs b/Assets/Scripts/InteractionEngine/FactHandling/Facts/FunctionFact.cs
index d77e7f88582b9ce034551e37b7deec07271c1bfd..53304976e2a88277cbf2f2851bf4183fd80c9c20 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/Facts/FunctionFact.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/Facts/FunctionFact.cs
@@ -14,10 +14,14 @@ public class FunctionCallFact : FactWrappedCRTP<FunctionCallFact>
 
     public (float t_0, float t_n) Domain;
 
+
     [JsonIgnore]
-    public FunctionFact Function_in => (FunctionFact)FactOrganizer.AllFacts[func_id];
+    public FunctionFact Function_in 
+        => (FunctionFact)FactOrganizer.AllFacts[func_id];
+
     [JsonIgnore]
-    public FunctionFact Function_args => (FunctionFact)FactOrganizer.AllFacts[arg_func_id];
+    public FunctionFact Function_args 
+        => (FunctionFact)FactOrganizer.AllFacts[arg_func_id];
 
 
     public FunctionCallFact() : base() { }
@@ -46,8 +50,8 @@ protected override string[] GetGetDependentFactIds()
         => new[] { func_id, arg_func_id };
 
     protected override bool EquivalentWrapped(FunctionCallFact f1, FunctionCallFact f2)
-        => f1.Domain.t_0.IsApproximatelyEqual(f2.Domain.t_0)
-        && f1.Domain.t_n.IsApproximatelyEqual(f2.Domain.t_n)
+        => Mathf.Approximately(f1.Domain.t_0, f2.Domain.t_0)
+        && Mathf.Approximately(f1.Domain.t_n, f2.Domain.t_n)
         && (DependentFactsEquivalent(f1, f2)
             || (f1.Function_in.Equivalent(f2.Function_in)
                 && f1.Function_args.Equivalent(f2.Function_args)
diff --git a/Assets/Scripts/InteractionEngine/ImageHintAnimation.cs b/Assets/Scripts/InteractionEngine/ImageHintAnimation.cs
index 7f9c33d7203b9c3cbe74829614c0a0b9b014451d..01eca9e9a29140f8ac59d2d602389a2ccbfc592e 100644
--- a/Assets/Scripts/InteractionEngine/ImageHintAnimation.cs
+++ b/Assets/Scripts/InteractionEngine/ImageHintAnimation.cs
@@ -1,8 +1,6 @@
 using System.Collections;
-using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.UI;
-using static GlobalBehaviour;
 
 public class ImageHintAnimation : MonoBehaviour
 {
@@ -21,11 +19,11 @@ void Awake()
 
     public void AnimationTrigger()
     {
-        StartCoroutine(routine = Animation());
+        StartCoroutine(routine = _Animation());
 
-        IEnumerator Animation()
+        IEnumerator _Animation()
         {
-            for ( var track = 0f.LerpInTime(0, GlobalBehaviour.hintAnimationDuration)
+            for (IEnumerator track = IEnumeratorExtensions.WaitForSeconds(GlobalBehaviour.hintAnimationDuration)
                 ; track.MoveNext();)
 
                 yield return imageToChange.color =
diff --git a/Assets/Scripts/InteractionEngine/ShinyThings.cs b/Assets/Scripts/InteractionEngine/ShinyThings.cs
index 4a10ae48c706306d1bb8d6845d62a5563bf6c690..b94a853baa7a6a185cfe1cae3c899b3aa58f8151 100644
--- a/Assets/Scripts/InteractionEngine/ShinyThings.cs
+++ b/Assets/Scripts/InteractionEngine/ShinyThings.cs
@@ -59,19 +59,19 @@ private void HighlightCurserHit(RaycastHit[] hits)
 
         //Set the last Facts unselected
         foreach (var lastFact in LastFactSelection)
-            if (lastFact != null
+            if (lastFact != null // if Fact was deleted
              && !selected_fact_objs.Contains(lastFact))
-                ApplyMaterial(lastFact, lastFact.Default);
+                _ApplyMaterial(lastFact, lastFact.Default);
 
         //Set the Facts that were Hit as selected
         foreach (var fact_obj in selected_fact_objs)
             if (!LastFactSelection.Contains(fact_obj))
-                ApplyMaterial(fact_obj, fact_obj.Selected);
+                _ApplyMaterial(fact_obj, fact_obj.Selected);
 
         LastFactSelection = selected_fact_objs;
         return;
 
-        void ApplyMaterial(FactObject root, Material new_mat) =>
+        void _ApplyMaterial(FactObject root, Material new_mat) =>
             root.CoroutineCascadeForMeAndChildrenAllRenderer(
                 (_, renderer) =>
                     renderer.ProgrammMaterialChange(new[] {
@@ -100,10 +100,10 @@ public void HighlightWithFireworks(Fact fact, FactObject.FactMaterials mat)
     {
         rain_wait = IEnumeratorExtensions.yield_break; //stop rain
 
-        StartCoroutine(BlossomAndDie());
+        StartCoroutine(_BlossomAndDie());
         HighlightFact(fact, mat);
 
-        IEnumerator BlossomAndDie()
+        IEnumerator _BlossomAndDie()
         {
             GameObject firework = GameObject.Instantiate
                 (Fireworks_Animation
@@ -132,11 +132,11 @@ public void LetItRain(Fact startFact, Scroll.ScrollApplicationInfo _)
         if (!rain_wait.MoveNext() || !rain.MoveNext())
         {
             StopCoroutine(rain);
-            StartCoroutine(rain = BlossomAndDie());
+            StartCoroutine(rain = _BlossomAndDie());
         }
         rain_wait = 0f.LerpInTime(0, timerDuration); //reset timer
 
-        IEnumerator BlossomAndDie()
+        IEnumerator _BlossomAndDie()
         {
             Destroy(active_rainwork);
             active_rainwork = GameObject.Instantiate(RainPrefab, new Vector3(0, 40, 0), Quaternion.identity);
diff --git a/Assets/Scripts/InteractionEngine/WorldCursor.cs b/Assets/Scripts/InteractionEngine/WorldCursor.cs
index e90f4caf0b7466f69b633ea449a0b192ac7807da..3f453b7a5a1e0b664e22c35c8bf3d6ad40ad4c53 100644
--- a/Assets/Scripts/InteractionEngine/WorldCursor.cs
+++ b/Assets/Scripts/InteractionEngine/WorldCursor.cs
@@ -7,8 +7,6 @@
 
 public class WorldCursor : MonoBehaviour
 {
-    public RaycastHit Hit;
-    // TODO experimentell for multiple hits
     public RaycastHit[] Hits;
 
     public float IntersectionDistance = 0.1f;
@@ -76,22 +74,20 @@ void Update()
             .OrderBy(h => h.distance)
             .ToArray();
 
-        Fact[] facts = Hits
-            .Select(h =>
-                h.transform.TryGetComponent(out FactObject factObj)
-                ? FactOrganizer.AllFacts[factObj.URI]
-                : null)
-            .ToArray();
-
         int i = 0;
         for (; i < Hits.Length; i++)
         { // find first acceptable hit
-            if (facts[i] is AbstractLineFact lineFact)
+
+            Fact fact = Hits[i].transform.TryGetComponent(out FactObject factObj)
+                ? FactOrganizer.AllFacts[factObj.URI]
+                : null;
+
+            if (fact is AbstractLineFact lineFact)
             {
                 Hits[i].point =
                     Math3d.ProjectPointOnLine(lineFact.Point1.Point, lineFact.Dir, Hits[i].point);
             }
-            else if (facts[i] is CircleFact circleFact)
+            else if (fact is CircleFact circleFact)
             {
                 var projPlane =
                     Math3d.ProjectPointOnPlane(circleFact.normal, circleFact.Point1.Point, Hits[i].point);
@@ -118,24 +114,38 @@ void Update()
             break; // we had at least 1 succesfull case
         }
 
-        if (i == Hits.Length)
-            return; // no valid Hit
+        Fact[] facts;
 
-        Hits = Hits.Skip(i)
-               .TakeWhile(h => h.distance - Hits[i].distance < IntersectionDistance)
-               .ToArray();
+        if (i == Hits.Length)
+        {
+            Hits = new[] { Hits[0] };
+            facts = new Fact[0];
+        }
+        else
+        {
+            Hits = Hits.Skip(i)
+                       .TakeWhile(h => h.distance - Hits[i].distance < IntersectionDistance)
+                       .ToArray();
+
+            facts = Hits
+                .Select(h =>
+                    h.transform.TryGetComponent(out FactObject factObj)
+                    ? FactOrganizer.AllFacts[factObj.URI]
+                    : null)
+                .ToArray();
+        }
 
         if (Hits.Length > 1)
         { // we have two or more objects intersecting
-            if (facts[i + 0] is RayFact rayFact1
-             && facts[i + 1] is RayFact rayFact2)
+            if (facts[0] is RayFact rayFact1
+             && facts[1] is RayFact rayFact2)
             {
                 if (Math3d.LineLineIntersection(out Vector3 intersectionPoint
                     , rayFact2.Point1.Point, rayFact2.Dir
                     , rayFact1.Point1.Point, rayFact1.Dir))
                 {
-                    Hits[i + 0].point = intersectionPoint;
-                    Hits[i + 1].point = intersectionPoint;
+                    Hits[0].point = intersectionPoint;
+                    Hits[1].point = intersectionPoint;
                 }
             }
 
diff --git a/Assets/Scripts/InventoryStuff/DisplayScrolls.cs b/Assets/Scripts/InventoryStuff/DisplayScrolls.cs
index 1b7bf8ec0a3a76c5064087a617f5922c0f05d802..e283d271e113f532895915850b02b98a4bd76dd9 100644
--- a/Assets/Scripts/InventoryStuff/DisplayScrolls.cs
+++ b/Assets/Scripts/InventoryStuff/DisplayScrolls.cs
@@ -38,6 +38,6 @@ void BuildScrollGUI()
 
         Scroll preferredStartScroll = AllowedScrolls.Find(x => x.label.Equals(preferredStartScrollName));
         if (preferredStartScroll != null)
-            this.DetailScreen.GetComponent<ScrollDetails>().setScroll(preferredStartScroll);
+            this.DetailScreen.GetComponent<ScrollDetails>().SetScroll(preferredStartScroll);
     }
 }
diff --git a/Assets/Scripts/InventoryStuff/DropHandling.cs b/Assets/Scripts/InventoryStuff/DropHandling.cs
deleted file mode 100644
index fe6352972fcb2e700297a1a0d42b641ae2645b65..0000000000000000000000000000000000000000
--- a/Assets/Scripts/InventoryStuff/DropHandling.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-using UnityEngine;
-using UnityEngine.EventSystems;
-
-public class DropHandling : MonoBehaviour, IDropHandler, IPointerClickHandler
-{
-    GameObject current;
-    public Fact currentFact;
-
-    public void OnDrop(PointerEventData eventData)
-    {
-
-        var scrollFact = gameObject.GetComponent<RenderedScrollFact>();
-        Debug.Log(eventData.pointerDrag.GetComponent<FactObject>().Fact.Label + " was dropped on "
-            + gameObject.name + " " + (scrollFact.ID + 1) + "/" +
-            ScrollDetails.ParameterDisplays.Count + " label: " + scrollFact.Label);
-
-        Destroy(current);
-
-        current = Instantiate(eventData.pointerDrag, Vector3.zero, Quaternion.identity);
-        //Set imageToChangeDefaultColor of current: Fix so that current won't take the color
-        //the dragged item was having during animation
-        current.GetComponent<ImageHintAnimation>().imageToChangeDefaultColor = eventData.pointerDrag.GetComponent<ImageHintAnimation>().imageToChangeDefaultColor;
-        current.GetComponent<ImageHintAnimation>().ResetAnimation();
-
-        current.transform.SetParent(gameObject.transform, false);
-
-        var rect = current.GetComponent<RectTransform>();
-        rect.anchorMin = new Vector2(0.5f, 0.5f);
-        rect.anchorMax = new Vector2(0.5f, 0.5f);
-
-        currentFact = eventData.pointerDrag.GetComponent<FactObject>().Fact;
-        current.GetComponent<FactObject>().Fact = currentFact;
-        Debug.Log("recieved Fact: " + currentFact.Id);
-
-        CommunicationEvents.NewAssignmentEvent.Invoke();
-      
-
-    }
-
-    public void OnPointerClick(PointerEventData eventData)
-    {
-        Destroy(current);
-        currentFact = null;
-        CommunicationEvents.NewAssignmentEvent.Invoke();
-    }
-
-}
diff --git a/Assets/Scripts/InventoryStuff/DropHandling.cs.meta b/Assets/Scripts/InventoryStuff/DropHandling.cs.meta
deleted file mode 100644
index 3f808ab222c5fbb04cd5fc7e5d98f7ca67f20af1..0000000000000000000000000000000000000000
--- a/Assets/Scripts/InventoryStuff/DropHandling.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 714c3b3ded45aea408421f43873d5e17
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Assets/Scripts/InventoryStuff/RenderedScrollFact.cs b/Assets/Scripts/InventoryStuff/RenderedScrollFact.cs
index 49b02a30f881ee22fc7e24ea9daf2758656aee36..f0263f17d3e7924aaa14fe521bbf57d47cb88562 100644
--- a/Assets/Scripts/InventoryStuff/RenderedScrollFact.cs
+++ b/Assets/Scripts/InventoryStuff/RenderedScrollFact.cs
@@ -1,43 +1,126 @@
 using System.Collections.Generic;
 using TMPro;
 using UnityEngine;
+using UnityEngine.EventSystems;
 using static CommunicationEvents;
 
-public class RenderedScrollFact : MonoBehaviour
+public class RenderedScrollFact : FactWrapper, IDropHandler, IPointerClickHandler
 {
-
-    public int ID;
+    #region Serializable
     public TextMeshProUGUI LabelMesh;
-    private string _label;
-    public string factUri;
-
     public GameObject ScrollParameterObject;
+    #endregion Serializable
+
+    #region Properties
+    public int ID
+    {
+        get => _ID;
+        private set
+        {
+            _ID = value;
+            SetLabel(null);
+        }
+    }
+    private int _ID;
 
-    public string Label
+    public Scroll Scroll
     {
-        get => _label;
+        get => _Scroll;
         set
         {
-            if (_label == value) return;
-            _label = value;
-            LabelMesh.text = value;
+            _Scroll = value;
+            SetLabel(null);
         }
     }
+    private Scroll _Scroll;
+
+    public string ScrollFactURI
+        => Scroll.requiredFacts[ID].@ref.uri;
+
+    public string ScrollFactLabel
+        => LabelMesh.text;
+    #endregion Properties
+
+    protected override void FactUpdated() { }
+
+    public void Populate(Scroll scroll, int Nr)
+    {
+        Scroll = scroll;
+        ID = Nr;
+    }
+
+    private void SetLabel(string label)
+    {
+        LabelMesh.text = label ?? Scroll?.requiredFacts[ID].label ?? "Err";
+    }
 
-    void Start()
+    private void OnEnable()
     {
         HintAvailableEvent.AddListener(OnHintAvailable);
     }
 
+    private void OnDisable()
+    {
+        HintAvailableEvent.RemoveListener(OnHintAvailable);
+    }
+
     public void OnClickHintButton()
     {
-        ScrollFactHintEvent.Invoke(this.ScrollParameterObject, factUri);
+        ScrollFactHintEvent.Invoke(this.ScrollParameterObject, ScrollFactURI);
     }
 
     public void OnHintAvailable(List<string> uris)
     {
         GameObject hintButton = ScrollParameterObject.transform.GetChild(2).gameObject;
-        
-        hintButton.SetActive(value: uris.Contains(factUri));
+
+        hintButton.SetActive(uris.Contains(ScrollFactURI));
     }
+
+    #region DropHandling 
+
+    private FactObject RenderedFactObject;
+
+    public void OnDrop(PointerEventData eventData)
+    {
+        Fact = eventData.pointerDrag.GetComponent<FactObject>().Fact;
+
+        {
+            Debug.Log(Fact.Label + " was dropped on "
+                + gameObject.name + " " + (ID + 1) + "/" +
+                ScrollDetails.ParameterDisplays.Count + " label: " + ScrollFactLabel);
+        }
+
+        Destroy(RenderedFactObject?.gameObject);
+
+        RenderedFactObject = // has to be , Vector3.zero, Quaternion.identity => SetParent
+            Instantiate(eventData.pointerDrag, Vector3.zero, Quaternion.identity)
+            .GetComponent<FactObject>();
+
+        RenderedFactObject.transform.SetParent(gameObject.transform, worldPositionStays: false);
+        RenderedFactObject.Fact = Fact;
+
+        //Set imageToChangeDefaultColor of current: Fix so that current won't take the color
+        //the dragged item was having during animation
+        RenderedFactObject.GetComponent<ImageHintAnimation>().imageToChangeDefaultColor =
+            eventData.pointerDrag.GetComponent<ImageHintAnimation>().imageToChangeDefaultColor;
+        RenderedFactObject.GetComponent<ImageHintAnimation>().ResetAnimation();
+
+        var rect = RenderedFactObject.GetComponent<RectTransform>();
+        rect.anchorMin = new Vector2(0.5f, 0.5f);
+        rect.anchorMax = new Vector2(0.5f, 0.5f);
+
+        Debug.Log("recieved Fact: " + Fact.Id);
+
+        CommunicationEvents.NewAssignmentEvent.Invoke();
+    }
+
+    public void OnPointerClick(PointerEventData eventData)
+    {
+        Destroy(RenderedFactObject);
+        Fact = null;
+
+        CommunicationEvents.NewAssignmentEvent.Invoke();
+    }
+
+    #endregion DropHandling 
 }
diff --git a/Assets/Scripts/InventoryStuff/ScrollClickedScript.cs b/Assets/Scripts/InventoryStuff/ScrollClickedScript.cs
index a4316586ebf78d736b22feede12b933375a9982e..cec5e886ad35da6fe3571e41ea7374c4b679ba3b 100644
--- a/Assets/Scripts/InventoryStuff/ScrollClickedScript.cs
+++ b/Assets/Scripts/InventoryStuff/ScrollClickedScript.cs
@@ -8,6 +8,6 @@ public class ScrollClickedScript : MonoBehaviour, IPointerDownHandler
 
     public void OnPointerDown(PointerEventData eventData)
     {
-        this.DetailScreen.GetComponent<ScrollDetails>().setScroll(this.scroll);
+        this.DetailScreen.GetComponent<ScrollDetails>().SetScroll(this.scroll);
     }
 }
diff --git a/Assets/Scripts/InventoryStuff/ScrollDetails.cs b/Assets/Scripts/InventoryStuff/ScrollDetails.cs
index 5d2cfca9faa5d66bd3fc15aed2b42df6c631c187..e5ba956cebac1fa2039b5d2906c021859396e0ee 100644
--- a/Assets/Scripts/InventoryStuff/ScrollDetails.cs
+++ b/Assets/Scripts/InventoryStuff/ScrollDetails.cs
@@ -4,8 +4,8 @@
 using TMPro;
 using UnityEngine.Networking;
 using Newtonsoft.Json;
-using static CommunicationEvents;
 using System.Linq;
+using static CommunicationEvents;
 using static SOMDocManager;
 
 public class ScrollDetails : MonoBehaviour
@@ -14,107 +14,115 @@ public class ScrollDetails : MonoBehaviour
     public GameObject parameterDisplayPrefab;
     public Scroll ActiveScroll;
     public GameObject mmtAnswerPopUp;
+    private PopupBehavior Popup;
 
-    public static List<GameObject> ParameterDisplays;
+    public static List<RenderedScrollFact> ParameterDisplays;
     private static List<Scroll.ScrollAssignment> LatestCompletions;
     private static List<Fact> LatestRenderedHints;
 
     public string currentMmtAnswer;
 
-    public bool dynamicScrollDescriptionsActive = true;
-    public bool automaticHintGenerationActive = true;
+    public bool DynamicScrollDescriptionsActive = true;
+    public bool AutomaticHintGenerationActive = true;
+
 
-    // Start is called before the first frame update
-    void Start()
+    void Awake()
     {
-        cursor ??= GameObject.FindObjectOfType<WorldCursor>();
-        
-        mmtAnswerPopUp.GetComponent<PopupBehavior>().hidePopUp();
+        if (cursor == null)
+            cursor = FindObjectOfType<WorldCursor>();
+
+        (Popup = mmtAnswerPopUp.GetComponent<PopupBehavior>())
+            .hidePopUp();
     }
 
     private void OnEnable()
     {
         ScrollFactHintEvent.AddListener(animateHint);
-        NewAssignmentEvent.AddListener(newAssignmentTrigger);
+        NewAssignmentEvent.AddListener(NewAssignmentTrigger);
         RemoveFactEvent.AddListener(removeFactFromAssignment);
     }
 
     private void OnDisable()
     {
         ScrollFactHintEvent.RemoveListener(animateHint);
-        NewAssignmentEvent.RemoveListener(newAssignmentTrigger);
+        NewAssignmentEvent.RemoveListener(NewAssignmentTrigger);
         RemoveFactEvent.RemoveListener(removeFactFromAssignment);
     }
 
-    public void setScroll(Scroll s)
+    public void SetScroll(Scroll scroll_to_set)
     {
-        Transform originalScroll = gameObject.transform.GetChild(1).transform;
+        ActiveScroll = scroll_to_set;
+
+        Transform originalScroll = gameObject.transform.GetChild(1);
         Transform originalScrollView = originalScroll.GetChild(1);
         Transform originalViewport = originalScrollView.GetChild(0);
-        this.ActiveScroll = s;
-
-        originalScroll.GetChild(0).GetComponent<TextMeshProUGUI>().text = s.description;
 
         //Clear all current ScrollFacts
         originalViewport.GetChild(0).gameObject.DestroyAllChildren();
 
-        ParameterDisplays = new List<GameObject>();
-        for (int i = 0; i < s.requiredFacts.Count; i++)
+        originalScroll.GetChild(0).GetComponent<TextMeshProUGUI>().text = ActiveScroll.description;
+
+        //ParameterDisplays.ForEach(gameObj => Destroy(gameObj));
+        ParameterDisplays = new();
+        for (int i = 0; i < ActiveScroll.requiredFacts.Count; i++)
         {
-            var originalObj = Instantiate(parameterDisplayPrefab, Vector3.zero, Quaternion.identity, transform);
-            var originalScrollFact = originalObj.transform.GetChild(0).GetComponent<RenderedScrollFact>();
-            originalScrollFact.ID = i;
-            originalScrollFact.Label = s.requiredFacts[i].label;
-            originalScrollFact.factUri = s.requiredFacts[i].@ref.uri;
+            GameObject originalObj =
+                Instantiate(parameterDisplayPrefab, originalViewport.GetChild(0));
 
-            originalObj.transform.SetParent(originalViewport.GetChild(0));
+            RenderedScrollFact originalRSF =
+                originalObj.GetComponentInChildren<RenderedScrollFact>();
 
-            ParameterDisplays.Add(originalObj);
+            ParameterDisplays.Add(originalRSF);
+
+            originalRSF.Populate(ActiveScroll, i);
         }
 
         //set active scroll for ErrorMessagePopup
-        PopupBehavior popup = mmtAnswerPopUp.GetComponent<PopupBehavior>();
-        popup.setScroll(this.ActiveScroll);
-        popup.setParameterDisplays(ParameterDisplays);
+        Popup.setScroll(ActiveScroll);
+        Popup.setParameterDisplays(ParameterDisplays.Select(RSF => RSF.gameObject).ToList());
     }
 
-    public void magicButtonTrigger()
+    public void MagicButtonTrigger()
     {
-        StartCoroutine(magicButton());
+        StartCoroutine(_MagicButton());
 
-        IEnumerator magicButton()
+        IEnumerator _MagicButton()
         {
-            //Non blocking wait till sendView() is finished
-            yield return sendView("/scroll/apply");
+            yield return SendView("/scroll/apply");
+
             if (currentMmtAnswer == null)
             {
-                Debug.Log("DAS HAT NICHT GEKLAPPT");
+                Debug.LogError("Magic FAILED");
                 PushoutFactFailEvent.Invoke(null, null);
             }
             else
             {
-                Debug.Log(currentMmtAnswer);
+                if (VerboseURI)
+                    Debug.Log("Magic answers:\n" + currentMmtAnswer);
+
                 Scroll.ScrollApplicationInfo pushout = JsonConvert.DeserializeObject<Scroll.ScrollApplicationInfo>(currentMmtAnswer);
+
                 if (pushout.acquiredFacts.Count == 0)
                     PushoutFactFailEvent.Invoke(null, pushout);
-                readPushout(pushout.acquiredFacts);
+
+                ReadPushout(pushout.acquiredFacts);
             }
         }
     }
 
-    public void newAssignmentTrigger()
+    public void NewAssignmentTrigger()
     {
-        if (this.automaticHintGenerationActive || this.dynamicScrollDescriptionsActive)
-            StartCoroutine(newAssignment());
+        if (AutomaticHintGenerationActive || DynamicScrollDescriptionsActive)
+            StartCoroutine(_NewAssignment());
 
-        IEnumerator newAssignment()
+        IEnumerator _NewAssignment()
         {
             //Non blocking wait till sendView() is finished
-            yield return sendView("/scroll/dynamic");
+            yield return SendView("/scroll/dynamic");
 
             if (currentMmtAnswer == null)
             {
-                Debug.Log("DAS HAT NICHT GEKLAPPT");
+                Debug.LogError("Dynamic Scroll FAILED");
             }
             else
             {
@@ -124,17 +132,22 @@ IEnumerator newAssignment()
         }
     }
 
-    IEnumerator sendView(string endpoint)
+    private IEnumerator SendView(string endpoint)
     {
+        while(ParameterDisplays == null) // Wait for server
+            yield return null;
+
         string body = prepareScrollAssignments();
-        System.DateTime startTime = System.DateTime.UtcNow;
 
         using UnityWebRequest www = UnityWebRequest.Put(ServerAdress + endpoint, body);
         www.method = UnityWebRequest.kHttpVerbPOST;
         www.SetRequestHeader("Content-Type", "application/json");
-        yield return www.SendWebRequest();
 
-        System.DateTime twoTime = System.DateTime.UtcNow;
+        System.DateTime sendTime = System.DateTime.UtcNow;
+        yield return www.SendWebRequest();
+        if (VerboseURI)
+            Debug.LogFormat("Server answerd in : {0}ms"
+                , (System.DateTime.UtcNow - sendTime).TotalMilliseconds);
 
         if (www.result == UnityWebRequest.Result.ConnectionError
          || www.result == UnityWebRequest.Result.ProtocolError)
@@ -147,100 +160,100 @@ IEnumerator sendView(string endpoint)
             string answer = www.downloadHandler.text;
             currentMmtAnswer = answer;
         }
-        System.DateTime endTime = System.DateTime.UtcNow;
 
-        string diffInSeconds = (endTime - startTime).TotalMilliseconds.ToString();
-        string diff = (twoTime - startTime).TotalMilliseconds.ToString();
-    }
+        string prepareScrollAssignments()
+        {
+            List<Scroll.ScrollAssignment> assignmentList = new();
 
-    private string prepareScrollAssignments()
-    {
-        List<Scroll.ScrollAssignment> assignmentList = new();
+            for (int i = 0; i < ParameterDisplays.Count; i++)
+            {
+                Fact tempFact = ParameterDisplays[i].Fact;
+                if (tempFact != null)
+                    assignmentList.Add(new Scroll.ScrollAssignment(ActiveScroll.requiredFacts[i].@ref.uri, tempFact.Id));
+            }
 
-        for (int i = 0; i < ParameterDisplays.Count; i++)
-        {
-            Fact tempFact = ParameterDisplays[i].GetComponentInChildren<DropHandling>().currentFact;
-            if (tempFact != null)
-                assignmentList.Add(new Scroll.ScrollAssignment(ActiveScroll.requiredFacts[i].@ref.uri, tempFact.Id));
+            return JsonConvert.SerializeObject(new Scroll.FilledScroll(ActiveScroll.@ref, assignmentList));
         }
-
-        return JsonConvert.SerializeObject(new Scroll.FilledScroll(ActiveScroll.@ref, assignmentList));
     }
 
-    private void readPushout(List<MMTDeclaration> pushoutFacts)
+    private void ReadPushout(List<MMTDeclaration> pushoutFacts)
     {
-        mmtAnswerPopUp.GetComponent<PopupBehavior>().hidePopUp(); //close error Window
+        Popup.hidePopUp(); //close error Window
 
         bool samestep = false;
-        for (int i = 0; i < pushoutFacts.Count; i++, samestep = true)
+        for (int i = 0; i < pushoutFacts.Count; i++)
         {
             Fact newFact = ParsingDictionary.parseFactDictionary[pushoutFacts[i].getType()].Invoke(pushoutFacts[i]);
             if (newFact != null)
-                PushoutFactEvent.Invoke(FactManager.AddFactIfNotFound(newFact, out _, samestep, null, ActiveScroll.label), FactObject.FactMaterials.Solution);
-         
+            {
+                PushoutFactEvent.Invoke
+                    (FactManager.AddFactIfNotFound(newFact, out _, samestep, null, ActiveScroll.label)
+                    , FactObject.FactMaterials.Solution);
+
+                samestep = true;
+            }
             else
                 Debug.Log("Parsing on pushout-fact returned null -> One of the dependent facts does not exist");
         }
     }
 
-    public void processScrollDynamicInfo(Scroll.ScrollDynamicInfo scrollDynamicInfo)
+    private void processScrollDynamicInfo(Scroll.ScrollDynamicInfo scrollDynamicInfo)
     {
-        LatestCompletions = scrollDynamicInfo.completions.Count > 0 
-            ? scrollDynamicInfo.completions[0] 
+        LatestCompletions = scrollDynamicInfo.completions.Count > 0
+            ? scrollDynamicInfo.completions[0]
             : new List<Scroll.ScrollAssignment>();
 
-
-        List<string> hintUris = LatestCompletions.Select(completion => completion.fact.uri).ToList();
+        List<string> hintUris = LatestCompletions
+            .Select(completion => completion.fact.uri)
+            .ToList();
 
         //Update Scroll, process data for later hints and update Uri-List for which hints are available
-        hintUris = processRenderedScroll(scrollDynamicInfo.rendered, hintUris);
+        _processRenderedScroll(scrollDynamicInfo.rendered, hintUris);
 
-        if (automaticHintGenerationActive)
+        if (AutomaticHintGenerationActive)
             //Show that Hint is available for ScrollParameter
             HintAvailableEvent.Invoke(hintUris);
-    }
-
-    public List<string> processRenderedScroll(Scroll rendered, List<string> hintUris)
-    {
-        Transform scroll = gameObject.transform.GetChild(1).transform;
 
-        if (this.dynamicScrollDescriptionsActive)
-            //Update scroll-description
-            scroll.GetChild(0).GetComponent<TextMeshProUGUI>().text = rendered.description;
+        return;
 
-        LatestRenderedHints = new List<Fact>();
-        for (int i = 0; i < rendered.requiredFacts.Count; i++)
+        void _processRenderedScroll(Scroll rendered, List<string> hintUris)
         {
-            GameObject obj = ParameterDisplays.Find(x => x.transform.GetChild(0).GetComponent<RenderedScrollFact>().factUri.Equals(rendered.requiredFacts[i].@ref.uri));
-
-            if (this.dynamicScrollDescriptionsActive)
-            {
-                //Update ScrollParameter label
-                obj.transform.GetChild(0).GetComponent<RenderedScrollFact>().Label = rendered.requiredFacts[i].label;
+            if (DynamicScrollDescriptionsActive)
+            { // Update scroll-description
+                Transform scroll = gameObject.transform.GetChild(1).transform;
+                scroll.GetChild(0).GetComponent<TextMeshProUGUI>().text = rendered.description;
             }
 
-            //Check Hint Informations
-            //If ScrollFact is assigned -> No Hint
-            if (obj.transform.GetChild(0).GetComponent<DropHandling>().currentFact == null)
+            LatestRenderedHints = new();
+            for (int i = 0; i < rendered.requiredFacts.Count; i++)
             {
+                RenderedScrollFact RenderedScrollFact = ParameterDisplays
+                    .Find(RSF => RSF.ScrollFactURI.Equals(rendered.requiredFacts[i].@ref.uri));
 
-                //  Debug.Log(" print out " + rendered.requiredFacts[i].getType());
-                Fact currentFact = ParsingDictionary.parseFactDictionary[rendered.requiredFacts[i].getType()].Invoke(rendered.requiredFacts[i]);
-                //If currentFact could be parsed: this fact maybe not yet exists in the global fact-list but there must be a fact
-                // of the same type and the same dependent facts in the fact-list, otherwise currentFact could not have been parsed
+                if (DynamicScrollDescriptionsActive)
+                    //Update ScrollParameter label
+                    RenderedScrollFact.Scroll = rendered;
 
-                //If the fact could not be parsed -> Therefore not all dependent Facts exist -> No Hint
-                //AND if fact has no dependent facts -> No Hint
-                if (currentFact != null && currentFact.HasDependentFacts)
+                //Check Hint Informations
+                //If ScrollFact is assigned -> No Hint
+                if (RenderedScrollFact.Fact == null)
                 {
-                    //Hint available for abstract-problem uri
-                    hintUris.Add(currentFact.Id);
-                    LatestRenderedHints.Add(currentFact);
+                    Fact HintFact = ParsingDictionary.parseFactDictionary[rendered.requiredFacts[i].getType()].Invoke(rendered.requiredFacts[i]);
+                    // If currentFact could be parsed: this fact maybe not yet exists in the global fact-list but there must be a fact
+                    // of the same type and the same dependent facts in the fact-list, otherwise currentFact could not have been parsed
+
+                    //If the fact could not be parsed -> Therefore not all dependent Facts exist -> No Hint
+                    //AND if fact has no dependent facts -> No Hint
+                    if (HintFact != null && HintFact.HasDependentFacts)
+                    { // Hint available for abstract-problem uri
+                        hintUris.Add(HintFact.Id);
+                        LatestRenderedHints.Add(HintFact);
+                    }
                 }
             }
-        }
 
-        return hintUris;
+            return;
+        }
     }
 
     public void animateHint(GameObject scrollParameter, string scrollParameterUri)
@@ -295,11 +308,8 @@ public void removeFactFromAssignment(Fact fact)
         for (int i = 0; i < originalViewport.GetChild(0).childCount; i++)
         {
             RenderedScrollFact scrollFact = originalViewport.GetChild(0).transform.GetChild(i).GetChild(0).gameObject.GetComponent<RenderedScrollFact>();
-            if (scrollFact.Label == fact.Label)
-            {
-                DropHandling dropHandling = originalViewport.GetChild(0).transform.GetChild(i).GetChild(0).gameObject.GetComponent<DropHandling>();
-                dropHandling.OnPointerClick(null);
-            }
+            if (scrollFact.ScrollFactLabel == fact.Label)
+                scrollFact.OnPointerClick(null);
         }
     }
 }
diff --git a/Assets/Scripts/SOMDocManager.cs b/Assets/Scripts/SOMDocManager.cs
index 6ea67b1ba4851b3a48768b9f51d32ea5dc3b8f05..5c2828b5e35f9480ee6f06c79358616d73403c7f 100644
--- a/Assets/Scripts/SOMDocManager.cs
+++ b/Assets/Scripts/SOMDocManager.cs
@@ -337,7 +337,7 @@ public static bool Equivalent(SOMDoc sd1, SOMDoc sd2)
 
         public abstract bool Equivalent(SOMDoc sd2);
 
-        public LambdaExpression PartialInvokeCastingLambdaExpression(out Type[] signature_args, object[] args = null)
+        public LambdaExpression PartialInvokeCastingLambdaExpression(out Type[] signature_args, object[] callArgs = null, bool[] useArgs = null)
         {
             LambdaExpression lambda_orig =
                 GetLambdaExpression(new LambdaExpression[0], new ParameterExpression[0]);
@@ -350,10 +350,11 @@ public LambdaExpression PartialInvokeCastingLambdaExpression(out Type[] signatur
             int n_params = 0;
             for (int i = 0; i < lambda_orig.Parameters.Count; i++)
             {
-                if (args != null && args.Length < i && args[i] != null)
+                if (callArgs != null && callArgs.Length < i 
+                 && (useArgs == null || (useArgs.Length < i && useArgs[i])))
                 {
                     cast_new_to_signature[i] =
-                        Expression.Constant(args[i], lambda_orig.Parameters[i].Type);
+                        Expression.Constant(callArgs[i], lambda_orig.Parameters[i].Type);
                     continue;
                 }
 
@@ -584,7 +585,7 @@ public OMF(float f) : base()
         }
 
         protected override bool EquivalentWrapped(OMF sd2)
-            => this.@float.IsApproximatelyEqual(sd2.@float);
+            => Mathf.Approximately(@float, sd2.@float);
 
         protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_args, ParameterExpression[] bound_params)
             => Expression.Lambda(Expression.Constant(@float, typeof(float)), null);
diff --git a/Assets/Scripts/UI/InGame/PopupBehavior.cs b/Assets/Scripts/UI/InGame/PopupBehavior.cs
index a02a02ce7b84284465a15279abc0f7ae274abd1f..ac145d2d4730752b237d297eb042ed833118c440 100644
--- a/Assets/Scripts/UI/InGame/PopupBehavior.cs
+++ b/Assets/Scripts/UI/InGame/PopupBehavior.cs
@@ -3,6 +3,7 @@
 using UnityEngine;
 using TMPro;
 using UnityEngine.UI;
+using System.Linq;
 using static SOMDocManager;
 
 public class PopupBehavior : MonoBehaviour
@@ -48,7 +49,7 @@ public void showPopUp()
     {
         canvas.SetActive(true);
         StartCoroutine(hideAfter5sec());
-        
+
         IEnumerator hideAfter5sec()
         {
             yield return new WaitForSeconds(5);
@@ -74,21 +75,22 @@ public void onFailedScrollInput(Fact startfact, Scroll.ScrollApplicationInfo err
 
     private string generateHelpfulMessageAndAnimateScrollParam(Scroll.ScrollApplicationInfo errorInfo)
     {
-        if(errorInfo == null)
-        {
+        if (errorInfo == null)
             return ServerErrorMessage;
-        }
+
         int invAssCount = 0;
         errorMessage = "";
-        for (int i = 0; i < errorInfo.errors.Length; i++) { 
+        for (int i = 0; i < errorInfo.errors.Length; i++)
+        {
             Scroll.ScrollApplicationCheckingError error = errorInfo.errors[i];
-            
+
             //check which error ocurred and set Message to a helpful error message.
             if (error.kind == "nonTotal")
             {
                 errorMessage += NonTotalMessage;
                 errorMessage += '\n';
-            } else if (error.kind == "invalidAssignment")
+            }
+            else if (error.kind == "invalidAssignment")
             {
                 invAssCount++;
                 MMTDeclaration fact = parseFactFromError(error);
@@ -99,16 +101,16 @@ private string generateHelpfulMessageAndAnimateScrollParam(Scroll.ScrollApplicat
                     foreach (GameObject g in parameterDisplays)
                     {
                         RenderedScrollFact scrollfact = g.transform.GetChild(0).GetComponent<RenderedScrollFact>();
-                        if (scrollfact.factUri == fact.@ref.uri)
-                        {
+                        if (scrollfact.ScrollFactURI == fact.@ref.uri)
                             scrollfact.ScrollParameterObject.GetComponentInChildren<ImageHintAnimation>().AnimationTrigger();
-                        }
                     }
-                } else
+                }
+                else
                 {
                     Debug.Log("PopupBehavior: Error: scroll or parameterDisplays not set.");
                 }
-            } else if (error.kind == "unknown")
+            }
+            else if (error.kind == "unknown")
             {
                 errorMessage += UnknownErrorMessage;
                 errorMessage += '\n';
@@ -116,10 +118,10 @@ private string generateHelpfulMessageAndAnimateScrollParam(Scroll.ScrollApplicat
         }
 
         //invalid assignment message
-        if(invAssCount > 0)
+        if (invAssCount > 0)
         {
             errorMessage += invAssCount.ToString() + " " + InvalidAssignmentMessage;
-            if(invAssCount > 1) //plural for invalid assignments
+            if (invAssCount > 1) //plural for invalid assignments
             {
                 errorMessage += 's';
             }
@@ -132,10 +134,9 @@ private string generateHelpfulMessageAndAnimateScrollParam(Scroll.ScrollApplicat
     //this should be changed, the Fact Object should be parsed by JSON. This is a workaround because the MMT servers JSON serialization contains a bug
     private MMTDeclaration parseFactFromError(Scroll.ScrollApplicationCheckingError error)
     {
-        if(error == null || error.msg == null)
-        {
+        if (error == null || error.msg == null)
             return null;
-        }
+        
         string message = error.msg;
 
         //cut start of string
@@ -155,17 +156,7 @@ private MMTDeclaration parseFactFromError(Scroll.ScrollApplicationCheckingError
         factUri += "?" + factLabel;
 
         //find the required fact in the active scroll thats invalidly assigned
-        if((activeScroll == null))
-        {
-            return null;
-        }
-        foreach (MMTDeclaration f in activeScroll.requiredFacts)
-        {
-            if (f.@ref.uri.Equals(factUri))
-            {
-                return f;
-            }
-        }
-        return null;
+        return activeScroll?.requiredFacts
+            .FirstOrDefault(decl => decl.@ref.uri.Equals(factUri));
     }
 }
diff --git a/Assets/Scripts/Utility/Extensions/IEnumeratorExtensions.cs b/Assets/Scripts/Utility/Extensions/IEnumeratorExtensions.cs
index 0ad9c67ea45843b0da57abcd7ce4843aa024c1a2..6ad5425cd7fa32b0ac946b94d1622b0b981cd70d 100644
--- a/Assets/Scripts/Utility/Extensions/IEnumeratorExtensions.cs
+++ b/Assets/Scripts/Utility/Extensions/IEnumeratorExtensions.cs
@@ -1,4 +1,6 @@
 using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
 
 public static class IEnumeratorExtensions
 {
@@ -13,4 +15,15 @@ public static IEnumerator YieldBreak()
     {
         yield break;
     }
+
+    public static IEnumerator<float> WaitForSeconds(float time)
+    {
+        if (time < 0) 
+            yield break;
+
+        for (float current_time = 0; time > current_time; current_time += Time.deltaTime)
+            yield return current_time;
+
+        yield return time;
+    }
 }