private void CheckInitiatePull() { //checks if there is anything in reach we can drag var topObject = MouseUtils.GetOrderedObjectsUnderMouse(null, go => go.GetComponent <PushPull>() != null).FirstOrDefault(); if (topObject != null) { PushPull pushPull = null; // If the topObject has a PlayerMove, we check if he is buckled // The PushPull object we want in this case, is the chair/object on which he is buckled to if (topObject.TryGetComponent <PlayerMove>(out var playerMove) && playerMove.IsBuckled) { pushPull = playerMove.BuckledObject.GetComponent <PushPull>(); } else { pushPull = topObject.GetComponent <PushPull>(); } if (pushPull != null) { pushPull.TryPullThis(); } }
private void Update() { if (state == State.SELECTING) { // ignore when we are over UI if (EventSystem.current.IsPointerOverGameObject()) { return; } //check which objects we are over, pick the top one to spawn if (CommonInput.GetMouseButtonDown(0)) { //NOTE: Avoiding multiple enumeration by converting IEnumerables to lists. var hitGOs = MouseUtils.GetOrderedObjectsUnderMouse(layerMask, go => go.GetComponent <CustomNetTransform>() != null).ToList(); //warn about objects which cannot be cloned var nonPooledHits = hitGOs .Where(go => Spawn.DeterminePrefab(go) == null).ToList(); if (nonPooledHits.Any()) { foreach (GameObject nonPooled in nonPooledHits) { Logger.LogWarningFormat("Object {0} does not have a PoolPrefabTracker component and its name" + " did not match one of our existing prefabs " + "therefore cannot be cloned (because we wouldn't know which prefab to instantiate). " + "Please attach this component to the object and specify the prefab" + " to allow it to be cloned.", Category.ItemSpawn, nonPooled.name); } } var pooledHits = hitGOs.Where(go => Spawn.DeterminePrefab(go) != null).ToList(); if (pooledHits.Any()) { toClone = pooledHits.First(); ToState(State.DRAWING); } } } else if (state == State.DRAWING) { cursorObject.transform.position = Camera.main.ScreenToWorldPoint(CommonInput.mousePosition); if (CommonInput.GetMouseButtonDown(0)) { Vector3Int position = cursorObject.transform.position.RoundToInt(); position.z = 0; if (MatrixManager.IsPassableAt(position, false)) { if (CustomNetworkManager.IsServer) { Spawn.ServerClone(toClone, position); } else { DevCloneMessage.Send(toClone, (Vector3)position); } } } } }
/// <summary> /// Try to build cable /// </summary> private void Build() { if (startPoint == endPoint || Mathf.Abs(startPointVector.x - endPointVector.x) > 2.5 || Mathf.Abs(startPointVector.y - endPointVector.y) > 2.5) { return; } GameObject target = MouseUtils.GetOrderedObjectsUnderMouse().FirstOrDefault(); ConnectionApply cableApply = ConnectionApply.ByLocalPlayer(target, startPoint, endPoint, null); //if HandObject is null, then its an empty hand apply so we only need to check the receiving object if (cableApply.HandObject != null) { //get all components that can contains CableApply interaction var cableAppliables = cableApply.HandObject.GetComponents <MonoBehaviour>() .Where(c => c != null && c.enabled && (c is IBaseInteractable <ConnectionApply>)); foreach (var cableAppliable in cableAppliables.Reverse()) { var hap = cableAppliable as IBaseInteractable <ConnectionApply>; if (hap.ClientCheckAndTrigger(cableApply)) { return; } } } }
private bool CheckClick() { ChangeDirection(); //currently there is nothing for ghosts to interact with, they only can change facing if (PlayerManager.LocalPlayerScript.IsGhost) { return(false); } bool ctrlClick = KeyboardInputManager.IsControlPressed(); if (!ctrlClick) { var handApplyTargets = MouseUtils.GetOrderedObjectsUnderMouse(layerMask); //go through the stack of objects and call any interaction components we find foreach (GameObject applyTarget in handApplyTargets) { if (CheckHandApply(applyTarget)) { return(true); } } } return(false); }
private void CheckHover() { //can only hover on things within FOV if (lightingSystem.enabled && !lightingSystem.IsScreenPointVisible(CommonInput.mousePosition)) { if (lastHoveredThing) { lastHoveredThing.transform.SendMessageUpwards("OnHoverEnd", SendMessageOptions.DontRequireReceiver); } lastHoveredThing = null; return; } var hit = MouseUtils.GetOrderedObjectsUnderMouse(layerMask).FirstOrDefault(); if (hit != null) { if (lastHoveredThing != hit) { if (lastHoveredThing) { lastHoveredThing.transform.SendMessageUpwards("OnHoverEnd", SendMessageOptions.DontRequireReceiver); } hit.transform.SendMessageUpwards("OnHoverStart", SendMessageOptions.DontRequireReceiver); lastHoveredThing = hit; } hit.transform.SendMessageUpwards("OnHover", SendMessageOptions.DontRequireReceiver); } }
private void CheckDragV2() { if (EventSystem.current.IsPointerOverGameObject()) { //currently UI is not a part of interaction framework V2 return; } //currently there is nothing for ghosts to interact with, they only can change facing if (PlayerManager.LocalPlayerScript.IsGhost) { return; } var draggable = MouseUtils.GetOrderedObjectsUnderMouse(layerMask, go => go.GetComponent <MouseDraggable>() != null && go.GetComponent <MouseDraggable>().CanBeginDrag(PlayerManager.LocalPlayer)) //get the root gameobject of the draggable .Select(sr => sr.GetComponentInParent <MouseDraggable>().gameObject) //only want distinct game objects even if we hit multiple renderers on one object. .Distinct() .FirstOrDefault(); if (draggable != null) { //start dragging the first draggable we found draggable.GetComponent <MouseDraggable>().BeginDrag(); } }
public void OnHover() { if (!UIManager.IsMouseInteractionDisabled && UIManager.Hands.CurrentSlot != null) { // get mouse position Vector3 mousePosition = Camera.main.ScreenToWorldPoint(CommonInput.mousePosition); // round mouse position Vector3Int roundedMousePosition = Vector3Int.RoundToInt(mousePosition); // if distance is greater than interaction distance if (Vector2.Distance(transform.position, (Vector3)roundedMousePosition) > PlayerScript.interactionDistance) { DisableVisualisation(); return; } // if position has changed and player has cable in hand if (roundedMousePosition != lastMouseWordlPositionInt && Validations.HasItemTrait(UIManager.Hands.CurrentSlot.ItemObject, CommonTraits.Instance.Cable)) { lastMouseWordlPositionInt = roundedMousePosition; // get metaTileMap and top tile // MetaTileMap metaTileMap = MatrixManager.AtPoint(roundedMousePosition, false).MetaTileMap; // LayerTile topTile = metaTileMap.GetTile(metaTileMap.WorldToCell(mousePosition), true); // *code above works only on Station matrix // TODO: replace GetComponent solution with some built-in method? var hit = MouseUtils.GetOrderedObjectsUnderMouse().FirstOrDefault(); MetaTileMap metaTileMap = hit.GetComponentInChildren <MetaTileMap>(); if (metaTileMap) { LayerTile topTile = metaTileMap.GetTile(metaTileMap.WorldToCell(roundedMousePosition), true); if (topTile && (topTile.LayerType == LayerType.Base || topTile.LayerType == LayerType.Underfloor)) { // move cable placement visualisation to rounded mouse position and enable it cablePlacementVisualisation.transform.position = roundedMousePosition - new Vector3(0.5f, 0.5f, 0);; cablePlacementVisualisation.SetActive(true); } // disable visualisation if active else { DisableVisualisation(); } } else { DisableVisualisation(); } } } else { DisableVisualisation(); } }
/// <summary> /// Checks for a click within the interaction framework v2. Until everything is moved over to V2, /// this will have to be used alongside the old one. /// </summary> private bool CheckClickV2() { //currently there is nothing for ghosts to interact with, they only can change facing if (PlayerManager.LocalPlayerScript.IsGhost) { return(false); } bool ctrlClick = KeyboardInputManager.IsControlPressed(); if (!ctrlClick) { var handApplyTargets = MouseUtils.GetOrderedObjectsUnderMouse(layerMask, go => go.GetComponent <RegisterTile>() != null) //get the root gameobject of the dropped-on sprite renderer .Select(sr => sr.GetComponentInParent <RegisterTile>().gameObject) //only want distinct game objects even if we hit multiple renderers on one object. .Distinct(); //object in hand var handObj = UIManager.Hands.CurrentSlot.Item; //go through the stack of objects and call any drop components we find foreach (GameObject applyTarget in handApplyTargets) { HandApply info = new HandApply(PlayerManager.LocalPlayer, handObj, applyTarget.gameObject); //call the used object's handapply interaction methods if it has any, for each object we are applying to //if handobj is null, then its an empty hand apply so we only need to check the receiving object if (handObj != null) { foreach (IInteractable <HandApply> handApply in handObj.GetComponents <IInteractable <HandApply> >()) { var result = handApply.Interact(info); if (result.SomethingHappened) { //we're done checking, something happened return(true); } } } //call the hand apply interaction methods on the target object if it has any foreach (IInteractable <HandApply> handApply in applyTarget.GetComponents <IInteractable <HandApply> >()) { var result = handApply.Interact(info); if (result.SomethingHappened) { //something happened, done checking return(true); } } } } return(false); }
private void FindObjectToOrbitUnderMouse() { var possibleTargets = MouseUtils.GetOrderedObjectsUnderMouse(); foreach (var possibleTarget in possibleTargets) { if (possibleTarget.TryGetComponent <PushPull>(out var pull) || possibleTarget.TryGetComponent <Singularity>(out var loose)) { CmdServerOrbit(possibleTarget); return; } } }
/// <summary> /// Load/enable cable cutting window and initialize it /// </summary> public void OpenCableCuttingWindow() { // get mouse position Vector3 mousePosition = MouseUtils.MouseToWorldPos(); // round mouse position Vector3Int roundedMousePosition = Vector3Int.RoundToInt(mousePosition); targetWorldPosition = roundedMousePosition; // check if window can be enabled, if not - return if (!CanWindowBeEnabled()) { return; } // get matrix GameObject hit = MouseUtils.GetOrderedObjectsUnderMouse().FirstOrDefault(); Matrix matrix = hit.GetComponentInChildren <Matrix>(); // return if matrix is null if (matrix == null) { return; } Vector3Int cellPosition = matrix.MetaTileMap.WorldToCell(mousePosition); // if window exist, just initialize it if (cableCuttingWindow != null) { cableCuttingWindow.InitializeCableCuttingWindow(matrix, cellPosition, mousePosition); } // else, load window from resources, store reference and initialize else { // only load from resources if the prefab is null if (cableCuttingWindowPrefab == null) { cableCuttingWindowPrefab = Resources.Load <GameObject>(PATH_TO_WINDOW_PREFAB); } cableCuttingWindow = Instantiate(cableCuttingWindowPrefab).GetComponentInChildren <CableCuttingWindow>(); cableCuttingWindow.InitializeCableCuttingWindow(matrix, cellPosition, mousePosition); } // enable window cableCuttingWindow.SetWindowActive(true); isWindowActive = true; itemInHand = PlayerManager.LocalPlayerScript.DynamicItemStorage.GetActiveHandSlot().ItemObject; }
private void CheckForInteractions(AiActivate.ClickTypes clickType) { var handApplyTargets = MouseUtils.GetOrderedObjectsUnderMouse(); //go through the stack of objects and call AiActivate interaction components we find foreach (GameObject applyTarget in handApplyTargets) { var behaviours = applyTarget.GetComponents <IBaseInteractable <AiActivate> >() .Where(mb => mb != null && (mb as MonoBehaviour).enabled); var aiActivate = new AiActivate(gameObject, null, applyTarget, Intent.Help, clickType); InteractionUtils.ClientCheckAndTrigger(behaviours, aiActivate); } }
private void CheckInitiatePull() { //checks if there is anything in reach we can drag var topObject = MouseUtils.GetOrderedObjectsUnderMouse(layerMask, go => go.GetComponent <PushPull>() != null).FirstOrDefault(); if (topObject != null) { var pushPull = topObject.GetComponent <PushPull>(); if (pushPull != null) { topObject.GetComponent <PushPull>().TryPullThis(); } } }
private void OnDragEnd() { UIManager.IsMouseInteractionDisabled = false; Destroy(shadowObject); shadowObject = null; if (lightingSystem.enabled && !lightingSystem.IsScreenPointVisible(CommonInput.mousePosition)) { //do nothing, the point is not visible. return; } //check what we dropped on, which may or may not have mousedrop interaction components //can only drop on things that have a RegisterTile var dropTargets = MouseUtils.GetOrderedObjectsUnderMouse(dropLayers, go => go.GetComponent <RegisterTile>() != null) //get the root gameobject of the dropped-on sprite renderer .Select(sr => sr.GetComponentInParent <RegisterTile>().gameObject) //only want distinct game objects even if we hit multiple renderers on one object. .Distinct(); //go through the stack of objects and call any drop components we find foreach (GameObject dropTarget in dropTargets) { MouseDrop info = new MouseDrop(PlayerManager.LocalPlayer, gameObject, dropTarget.gameObject); //call this object's mousedrop interaction methods if it has any, for each object we are dropping on foreach (IInteractable <MouseDrop> mouseDrop in mouseDrops) { var result = mouseDrop.Interact(info); if (result.SomethingHappened) { //we're done checking, something happened return; } } //call the mousedrop interaction methods on the dropped-on object if it has any foreach (IInteractable <MouseDrop> mouseDropTarget in dropTarget.GetComponents <IInteractable <MouseDrop> >()) { var result = mouseDropTarget.Interact(info); if (result.SomethingHappened) { //something happened, done checking return; } } } }
/// <summary> /// Load/enable cable cutting window and initialize it /// </summary> public void OpenCableCuttingWindow() { // get mouse position Vector3 mousePosition = Camera.main.ScreenToWorldPoint(CommonInput.mousePosition); // round mouse position Vector3Int roundedMousePosition = Vector3Int.RoundToInt(mousePosition); targetWorldPosition = roundedMousePosition; // check if window can be enabled, if not - return if (!CanWindowBeEnabled()) { return; } // get matrix GameObject hit = MouseUtils.GetOrderedObjectsUnderMouse().FirstOrDefault(); Matrix matrix = hit.GetComponentInChildren <Matrix>(); // return if matrix is null if (matrix == null) { return; } Vector3Int cellPosition = matrix.MetaTileMap.WorldToCell(mousePosition); // if window exist, just initialize it if (cableCuttingWindow != null) { cableCuttingWindow.InitializeCableCuttingWindow(matrix, cellPosition, mousePosition); } // else, load window from resources, store reference and initialize else { cableCuttingWindow = Instantiate(cableCuttingWindowPrefab).GetComponentInChildren <CableCuttingWindow>(); cableCuttingWindow.InitializeCableCuttingWindow(matrix, cellPosition, mousePosition); } // enable window cableCuttingWindow.SetWindowActive(true); isWindowActive = true; itemInHand = UIManager.Hands.CurrentSlot.ItemObject; }
public void StopDrag() { if (!DropInteracted && DraggedItem != null) { var mouseDrops = DraggedItem.GetComponents <IBaseInteractable <MouseDrop> >(); // check for MouseDrop interactions in the world if we didn't drop on a UI slot // check what we dropped on, which may or may not have mousedrop interaction components var dropTargets = MouseUtils.GetOrderedObjectsUnderMouse(); // go through the stack of objects and call any drop components we find foreach (GameObject dropTarget in dropTargets) { MouseDrop info = MouseDrop.ByLocalPlayer(DraggedItem, dropTarget.gameObject); // call this object's mousedrop interaction methods if it has any, for each object we are dropping on if (InteractionUtils.ClientCheckAndTrigger(mouseDrops, info) != null) { break; } var targetComps = dropTarget.GetComponents <IBaseInteractable <MouseDrop> >() .Where(mb => mb != null && (mb as MonoBehaviour).enabled); if (InteractionUtils.ClientCheckAndTrigger(targetComps, info) != null) { break; } } } DropInteracted = false; isDragging = false; dragDummy.enabled = false; if (FromSlotCache != null) { if (FromSlotCache.Item != null) { FromSlotCache.RefreshImage(); } } FromSlotCache = null; DraggedItem = null; ResetInteractable(); }
private void OnDragEnd() { UIManager.IsMouseInteractionDisabled = false; Destroy(shadowObject); shadowObject = null; if (lightingSystem.enabled && !lightingSystem.IsScreenPointVisible(CommonInput.mousePosition)) { //do nothing, the point is not visible. return; } //check what we dropped on, which may or may not have mousedrop interaction components //can only drop on things that have a RegisterTile var dropTargets = MouseUtils.GetOrderedObjectsUnderMouse(dropLayers); //go through the stack of objects and call any drop components we find foreach (GameObject dropTarget in dropTargets) { MouseDrop info = MouseDrop.ByLocalPlayer(gameObject, dropTarget.gameObject); //call this object's mousedrop interaction methods if it has any, for each object we are dropping on foreach (IInteractable <MouseDrop> mouseDrop in mouseDrops) { var interacted = mouseDrop.Interact(info); if (interacted) { //we're done checking, something happened return; } } //call the mousedrop interaction methods on the dropped-on object if it has any foreach (IInteractable <MouseDrop> mouseDropTarget in dropTarget.GetComponents <IInteractable <MouseDrop> >() .Where(mb => mb != null && (mb as MonoBehaviour).enabled)) { var interacted = mouseDropTarget.Interact(info); if (interacted) { //something happened, done checking return; } } } }
private void UpdateMe() { // check which objects we are over, pick the top one to delete if (CommonInput.GetMouseButtonDown(0)) { var hits = MouseUtils.GetOrderedObjectsUnderMouse(layerMask, go => go.GetComponent <CustomNetTransform>() != null); if (hits.Any()) { if (CustomNetworkManager.IsServer) { _ = Despawn.ServerSingle(hits.First().GetComponentInParent <CustomNetTransform>().gameObject); } else { DevDestroyMessage.Send(hits.First().GetComponentInParent <CustomNetTransform>().gameObject); } } } }
private void CheckHover() { var hit = MouseUtils.GetOrderedObjectsUnderMouse(layerMask).FirstOrDefault(); if (hit != null) { if (lastHoveredThing != hit) { if (lastHoveredThing) { lastHoveredThing.transform.SendMessageUpwards("OnHoverEnd", SendMessageOptions.DontRequireReceiver); } hit.transform.SendMessageUpwards("OnHoverStart", SendMessageOptions.DontRequireReceiver); lastHoveredThing = hit; } hit.transform.SendMessageUpwards("OnHover", SendMessageOptions.DontRequireReceiver); } }
/// <summary> /// Checks if there is a MouseDraggable under current mouse position. Returns it if so. Doesn't initiate /// the drag. /// </summary> /// <returns>draggable found, null if none found</returns> private MouseDraggable GetDraggable() { //currently there is nothing for ghosts to interact with, they only can change facing if (PlayerManager.LocalPlayerScript.IsGhost) { return(null); } var draggable = MouseUtils.GetOrderedObjectsUnderMouse(layerMask, go => go.GetComponent <MouseDraggable>() != null && go.GetComponent <MouseDraggable>().CanBeginDrag(PlayerManager.LocalPlayer)) .FirstOrDefault(); if (draggable != null) { var dragComponent = draggable.GetComponent <MouseDraggable>(); return(dragComponent); } return(null); }
private bool CheckClick() { ChangeDirection(); //currently there is nothing for ghosts to interact with, they only can change facing if (PlayerManager.LocalPlayerScript.IsGhost) { return(false); } bool ctrlClick = KeyboardInputManager.IsControlPressed(); if (!ctrlClick) { var handApplyTargets = MouseUtils.GetOrderedObjectsUnderMouse(); //go through the stack of objects and call any interaction components we find foreach (GameObject applyTarget in handApplyTargets) { if (CheckHandApply(applyTarget)) { return(true); } } //check empty space positional hand apply var posHandApply = PositionalHandApply.ByLocalPlayer(null); if (posHandApply.HandObject != null) { var handAppliables = posHandApply.HandObject.GetComponents <IBaseInteractable <PositionalHandApply> >() .Where(c => c != null && (c as MonoBehaviour).enabled); if (InteractionUtils.ClientCheckAndTrigger(handAppliables, posHandApply) != null) { return(true); } } } return(false); }
private void OnDragEnd() { // Get the world position of the shadow object before destroying it. var shadowLoc = shadowObject.transform.position; UIManager.IsMouseInteractionDisabled = false; Destroy(shadowObject); shadowObject = null; if (lightingSystem.enabled && !lightingSystem.IsScreenPointVisible(CommonInput.mousePosition)) { //do nothing, the point is not visible. return; } //check what we dropped on, which may or may not have mousedrop interaction components //can only drop on things that have a RegisterTile var dropTargets = MouseUtils.GetOrderedObjectsUnderMouse(); //go through the stack of objects and call any drop components we find foreach (GameObject dropTarget in dropTargets) { MouseDrop info = MouseDrop.ByLocalPlayer(gameObject, dropTarget.gameObject); info.ShadowWorldLocation = shadowLoc; //info. //call this object's mousedrop interaction methods if it has any, for each object we are dropping on if (InteractionUtils.ClientCheckAndTrigger(mouseDrops, info) != null) { return; } var targetComps = dropTarget.GetComponents <IBaseInteractable <MouseDrop> >() .Where(mb => mb != null && (mb as MonoBehaviour).enabled); if (InteractionUtils.ClientCheckAndTrigger(targetComps, info) != null) { return; } } }
/// <summary> /// Create an AimAPply for the local player aiming at the current mouse position with the item in their /// active hand slot. /// </summary> /// <param name="buttonState">state of mouse (initial click vs. being held after a click)</param> /// <returns></returns> public static AimApply ByLocalPlayer(MouseButtonState buttonState) { //Check for self aim if (PLAYER_LAYER_MASK == -1) { PLAYER_LAYER_MASK = LayerMask.GetMask("Players"); } var targetVector = (Vector2)Camera.main.ScreenToWorldPoint(CommonInput.mousePosition) - (Vector2)PlayerManager.LocalPlayer.transform.position; //check for self aim if target vector is sufficiently small so we can avoid raycast var selfAim = false; if (targetVector.magnitude < 0.5) { selfAim = MouseUtils.GetOrderedObjectsUnderMouse(PLAYER_LAYER_MASK, go => go == PlayerManager.LocalPlayer).Any(); } return(new AimApply(PlayerManager.LocalPlayer, UIManager.Hands.CurrentSlot.ItemObject, UIManager.Hands.CurrentSlot.ItemSlot, buttonState, selfAim ? Vector2.zero : targetVector, UIManager.CurrentIntent)); }
/// <summary> /// Create an AimAPply for the local player aiming at the current mouse position with the item in their /// active hand slot. /// </summary> /// <param name="buttonState">state of mouse (initial click vs. being held after a click)</param> /// <returns></returns> public static AimApply ByLocalPlayer(MouseButtonState buttonState) { //Check for self aim if (PLAYER_LAYER_MASK == -1) { PLAYER_LAYER_MASK = LayerMask.GetMask("Players"); } var targetVector = (Vector2)MouseUtils.MouseToWorldPos() - (Vector2)PlayerManager.LocalPlayer.transform.position; //check for self aim if target vector is sufficiently small so we can avoid raycast var selfAim = false; if (targetVector.magnitude < 0.6) { selfAim = MouseUtils.GetOrderedObjectsUnderMouse(PLAYER_LAYER_MASK, go => go == PlayerManager.LocalPlayer).Any(); } return(new AimApply(PlayerManager.LocalPlayer, PlayerManager.LocalPlayerScript.DynamicItemStorage.GetActiveHandSlot().ItemObject, PlayerManager.LocalPlayerScript.DynamicItemStorage.GetActiveHandSlot(), buttonState, selfAim ? Vector2.zero : targetVector, UIManager.CurrentIntent)); }
private void Update() { // return if visualisation is disabled or distance is greater than interaction distance if (!cablePlacementVisualisation.activeSelf) { return; } // get releative mouse position Vector2 releativeMousePosition = Camera.main.ScreenToWorldPoint(CommonInput.mousePosition) - cablePlacementVisualisation.transform.position; // get nearest point int x = Mathf.RoundToInt(releativeMousePosition.x * 2); int y = 2 - Mathf.RoundToInt(releativeMousePosition.y * 2); // clamp to be sure that value is in range <0, 2> x = Mathf.Clamp(x, 0, 2); y = Mathf.Clamp(y, 0, 2); Vector2Int point = new Vector2Int(x, y); Connection currentConnection = GetConnectionByPoint(point); // if mouse down - start drawing if (CommonInput.GetMouseButtonDown(0)) { startPoint = currentConnection; target = MouseUtils.GetOrderedObjectsUnderMouse().FirstOrDefault(); SetConnectionPointColor(startPoint, startPointColor); } // if mouse up - stop drawing and check if can build else if (CommonInput.GetMouseButtonUp(0)) { endPoint = currentConnection; Build(); ResetValues(); return; } // check if position has changed if (currentConnection != lastConnection) { // check if last point isn't startPoint or endPoint (to not override color) if (lastConnection != startPoint && lastConnection != endPoint) { SetConnectionPointColor(lastConnection, defaultPointColor); } SetConnectionPointColor(currentConnection, onHoverPointColor); if (startPoint != Connection.NA) { lineRenderer.SetPositions(new Vector3[] { connectionPointRenderers[startPoint].transform.localPosition, // position of start point connectionPointRenderers[currentConnection].transform.localPosition // position of current point }); } lastConnection = currentConnection; } }