protected override void OnPopulateMesh(VertexHelper vh) { vh.Clear(); if (sprite == null) { return; } var rect = rectTransform.rect; var rectSize = new Vector2(rect.width, rect.height); var size = new Vector4(0, 0, rectSize.x, rectSize.y); var uv = DataUtility.GetOuterUV(sprite); var pivotSize = Vector2.Dot(rectSize, direction) + spacing; var basePos = TransformUtility.CheckOffsetBiased(rectTransform, direction, spacing, count); int e = 0; for (; e < Mathf.Min(value, count); ++e) { var pos = basePos + e * pivotSize * direction; MeshUtility.AddSimple(vh, Color.white, pos, size, uv); } if (option == null) { return; } uv = DataUtility.GetOuterUV(option); for (; e < count; ++e) { var pos = basePos + e * pivotSize * direction; MeshUtility.AddSimple(vh, Color.white, pos, size, uv); } }
protected override void OnPopulateMesh(VertexHelper vh) { vh.Clear(); if (sprite == null) { return; } var rect = rectTransform.rect; var rectSize = new Vector2(rect.width, rect.height); var size = new Vector4(0, 0, rectSize.x, rectSize.y); var uv = DataUtility.GetOuterUV(sprite); var pivotSize = Vector2.Dot(rectSize, direction) + spacing; var countInteger = Mathf.FloorToInt(count); var countFract = count - countInteger; var basePos = TransformUtility.CheckOffsetBiased(rectTransform, direction, spacing, count); for (int e = 0; e < countInteger; ++e) { var pos = basePos + e * pivotSize * direction; MeshUtility.AddSimple(vh, Color.white, pos, size, uv); } if (countFract > 0) { var posLast = basePos + countInteger * pivotSize * direction; #if SCALED_FRACTIONAL posLast.x += width * countFract * 0.5f; MeshUtility.AddSimple(vh, Color.white, posLast, size * countFract, uv); #else //clipped factional size.z *= countFract; uv.z = uv.x + (uv.z - uv.x) * countFract; MeshUtility.AddSimple(vh, Color.white, posLast, size, uv); #endif } }
public override EM_SpawnLocationData GetSpawnLocation(SE_SkillObject skillObj) { updateParamsChanged(); var data = new EM_SpawnLocationData(); baseLocation = transform.position - transform.right * (length / 2); baseLocation += transform.right * (getPositionRatioByLocationMode(skillObj) * length); float spanAngle = -Mathf.PI * 2f * angle / 360; Vector3 dir = TransformUtility.Get3DCirclePoint(spanAngle, 1, Vector3.zero, -transform.right, transform.up); data.Location = baseLocation; data.Foward = dir; debugLine.Enqueue(data); if (debugLine.Count > 10) { debugLine.Dequeue(); } return(data); }
public override EM_SpawnLocationData GetSpawnLocation(SE_SkillObject skillObj) { updateParamsChanged(); var data = new EM_SpawnLocationData(); float spanAngle = -(arcOffset / 360) * (Mathf.PI * 2f); spanAngle -= getSpanAngleByLocationMode(skillObj); Vector3 a = transform.up; float radiusByType = radius - (radiusThickness) * radius * Random.value; //zero radius cannot generate correct rotation if (radiusByType == 0) { radiusByType = 0.001f; } spanAngle *= bReverseDirection ? -1 : 1; baseLocation = TransformUtility.Get3DCirclePoint(spanAngle, radiusByType, transform.position, a, transform.right); data.Location = baseLocation; data.Foward = (baseLocation - transform.position).normalized; debugLine.Enqueue(data); if (debugLine.Count > 10) { debugLine.Dequeue(); } return(data); }
protected void GetRotation() { switch (editSpace) { case EditSpace.World: rotation = Quaternion.identity; break; case EditSpace.Transform: rotation = TransformUtility.GetRotation(editor.matrix); break; case EditSpace.Spline: if (editor.evaluate == null) { Debug.LogError("Unassigned handler evaluate for Spline Editor."); break; } if (selectedPoints.Count == 1) { editor.evaluate((double)selectedPoints[0] / (points.Length - 1), evalResult); rotation = evalResult.rotation; } else { rotation = Quaternion.identity; } break; } }
public override ActionResult DoAction() { if (MeshSelection.selectedObjectCount < 1) { return(ActionResult.NoSelection); } Object[] objects = new Object[MeshSelection.selectedObjectCount * 2]; for (int i = 0, c = MeshSelection.selectedObjectCount; i < c; i++) { objects[i] = MeshSelection.topInternal[i]; objects[i + c] = MeshSelection.topInternal[i].transform; } UndoUtility.RegisterCompleteObjectUndo(objects, "Set Pivot"); foreach (var mesh in MeshSelection.topInternal) { TransformUtility.UnparentChildren(mesh.transform); mesh.CenterPivot(mesh.selectedIndexesInternal); mesh.Optimize(); TransformUtility.ReparentChildren(mesh.transform); } ProBuilderEditor.Refresh(); return(new ActionResult(ActionResult.Status.Success, "Set Pivot")); }
public override void Event_MoveFxToOpponent(AnimationEvent animEvent) { if (currentSkill == null || currentSkill is Object && currentSkill.Equals(null)) { return; } if (!_opponents.Any()) { return; } currentOpponent = _opponents[animEvent.intParameter]; if (currentOpponent == null || currentOpponent is Object && currentOpponent.Equals(null)) { return; } var fx = currentSkill.GetEffect(animEvent.stringParameter, _baseCharacter); if (fx == null || fx is Object && fx.Equals(null)) { return; } var frameRate = animEvent.animatorClipInfo.clip.frameRate; var length = CalculatorUtility.TimeByFrame(animEvent.floatParameter, frameRate); StartCoroutine(TransformUtility.MoveToTarget(fx, fx.transform.position, currentOpponent.hitPoint.transform.position, length, () => { Destroy(fx.gameObject); })); }
public override void DrawModuleHelper() { Vector3 _topOffset = topOffset; updateParamsChanged(); UnityEditor.Handles.color = Color.green; UnityEditor.Handles.DrawWireDisc(transform.position, transform.forward, radius); UnityEditor.Handles.DrawWireDisc(transform.position + _topOffset + transform.forward * length, transform.forward, coneTopRadius); float spanAngle = 0; int drawLineCount = 4; for (int i = 0; i < drawLineCount; i++) { spanAngle += Mathf.PI * 2f / drawLineCount; coneBaseLocation = TransformUtility.Get3DCirclePoint(spanAngle, radius, transform.position, transform.forward, transform.right); coneTopLocation = TransformUtility.Get3DCirclePoint(spanAngle, coneTopRadius, transform.position + _topOffset + transform.forward * length, transform.forward, transform.right); UnityEditor.Handles.DrawLine(coneBaseLocation, coneTopLocation); } UnityEditor.Handles.color = Color.white; foreach (var item in debugLine) { UnityEditor.Handles.DrawLine(item.Location, item.Location + item.Foward); } }
public void UpdateReferences() { #if UNITY_2018_3_OR_NEWER #else if (AssetDatabase.Contains(gameObject)) { return; } #endif editorChildCount = 0; TransformUtility.GetChildCount(transform, ref editorChildCount); discoveredProperties.Clear(); GetBendableObjects(transform, ref discoveredProperties); if (objectProperties.Length != discoveredProperties.Count) { objectProperties = discoveredProperties.ToArray(); } else { for (int i = 0; i < discoveredProperties.Count; i++) { objectProperties[i] = discoveredProperties[i]; } } CalculateBounds(); }
public GameObject Unprefabricate(GameObject patternObject) { var groupPrefab = Resources.Load <GameObject>(Constants.GROUP_PREFAB); var prefabGo = Instantiate(groupPrefab, Vector3.zero, Quaternion.identity); var group = prefabGo.GetComponent <Group>(); if (group.IsNotNull()) { var patternGroup = patternObject.GetComponent <Group>(); var pixelsInPatternGroup = patternGroup.pixels; foreach (var pixel in pixelsInPatternGroup) { // PixelManager.instance.AddPixel(pixel); var pixelTransform = pixel.transform; var instancePixel = Instantiate(pixel, pixelTransform.localPosition, pixelTransform.rotation); instancePixel.name = pixel.name; group.AddPixel(instancePixel); pixelManager.AddPixel(instancePixel); } var groups = patternGroup.groupChildren; group.CloneGroup(groups, true); // Compute pivot of group var pixelsInGroup = group.GetPixelsInChildren(); var selectedPoints = pixelsInGroup.Select(x => x.transform.position).ToArray(); var centerPoint = TransformUtility.ComputeCenterPoint(selectedPoints); // var groupPosition = centerPoint.ToVector2().Snap2(); var pivot = group.GetComponentInChildren <GroupPivot>(); pivot.transform.position = new Vector3(centerPoint.x, centerPoint.y, pivot.transform.position.z); } group.SetEnabledPivot(false); return(prefabGo); }
protected override void OnPopulateMesh(VertexHelper vh) { vh.Clear(); //TODO extend direction var offset = new Vector2(0, 0); var width = 0f; var height = rectTransform.rect.height * 0.5f; var center = TransformUtility.CheckCenter(rectTransform); var centerLocal = center; Vector4 uv, uvInner; Vector4 rect, border; if (middle != null) { width = middle.rect.width * 0.5f; offset = new Vector2(width, 0); uv = DataUtility.GetOuterUV(middle); uvInner = DataUtility.GetInnerUV(middle); rect = new Vector4(-width, -height, width, height); if (uv == uvInner) { MeshUtility.AddSimple(vh, color, centerLocal, rect, uv); } else { border = middle.border; MeshUtility.AddSliced(vh, color, centerLocal, rect, uv, uvInner, border); } } width = rectTransform.rect.width * 0.5f - width; //handle width < 0 if (mirrored == null || width <= 0) { return; } //Debug.Log($"{width}"); uv = DataUtility.GetOuterUV(mirrored); uvInner = DataUtility.GetInnerUV(mirrored); rect = new Vector4(-width, -height, 0, height); if (uv == uvInner) { centerLocal = center - offset; MeshUtility.AddSimple(vh, color, centerLocal, rect, uv); centerLocal = center + offset; rect.x = -rect.x; MeshUtility.AddSimple(vh, color, centerLocal, rect, uv); } else { border = mirrored.border; centerLocal = center - offset; MeshUtility.AddSliced(vh, color, centerLocal, rect, uv, uvInner, border); centerLocal = center + offset; rect.x = -rect.x; MeshUtility.AddSliced(vh, color, centerLocal, rect, uv, uvInner, border); } }
public void UnparentChildrenAndReparentChildren_HasSameAmountOfChildren() { Assume.That(m_Parent.childCount, Is.EqualTo(k_ChildCount)); TransformUtility.UnparentChildren(m_Parent); Assume.That(m_Parent.childCount, Is.EqualTo(0)); TransformUtility.ReparentChildren(m_Parent); Assert.That(m_Parent.childCount, Is.EqualTo(k_ChildCount)); }
public void SpawnProcess(GameTime dt) { if (_state.Equals(EditorState.None) && Keyboard.GetState().IsKeyDown(Keys.C)) { var scrollEvent = _inputAggregator.GetEvent <ScrollEvent>(); if (scrollEvent != null && scrollEvent.Delta != 0) { double scrollDirection = scrollEvent.Delta / 120.0; int direction; if (scrollDirection < 0) { direction = ( int )Math.Floor(scrollDirection); } else { direction = ( int )Math.Ceiling(scrollDirection); } _selectedPrefab += direction; while (_selectedPrefab < 0) { _selectedPrefab += _prefabs.Count; } _selectedPrefab = _selectedPrefab % _prefabs.Count; } HintManager.Instance.SpawnHint("Spawning entity:" + _prefabs[_selectedPrefab], new Vector2(20f, 16f), 50, 5, null, 1); if (Mouse.GetState().LeftButton.Equals(ButtonState.Pressed)) { string generatedName = GenerateEntityName(_prefabs[_selectedPrefab]); Vector3 m3D = SceneManager.Instance.IntersectScreenRayWithPlane(_lastSelectedZ); Vector3 position = new Vector3(m3D.X, m3D.Y, _lastSelectedZ); if (_inputAggregator.HasEvent(UISButton.LeftControl) || _inputAggregator.HasEvent(UISButton.RightControl)) { position = TransformUtility.SnapToGridXY(position, OperationBigIncrement); } else if (_inputAggregator.HasEvent(UISButton.LeftShift) || _inputAggregator.HasEvent(UISButton.RightShift)) { position = TransformUtility.SnapToGridXY(position, OperationSmallIncrement); } else { position = TransformUtility.SnapToGridXY(position, 1f); } GameWorldManager.Instance.SpawnEntity(_prefabs[_selectedPrefab], generatedName, position, 1f, _lastLayerSelected); _state = EditorState.Selected; _selectedEntity = GameWorldManager.Instance.GetEntity(generatedName); Platform.Instance.PhysicsWorld.Step(0f); } } }
public void UnparentChildren_HasZeroChildren() { Assume.That(m_Parent.childCount, Is.EqualTo(k_ChildCount)); TransformUtility.UnparentChildren(m_Parent); Assert.That(m_Parent.childCount, Is.EqualTo(0)); TransformUtility .ReparentChildren(m_Parent); //This call is to ensure that we clear the child dictionary created by unparent }
protected override void OnPopulateMesh(VertexHelper vh) { vh.Clear(); //TODO extend direction var offset = new Vector2(0, 0); var width = 0f; var height = rectTransform.rect.height * 0.5f; var center = TransformUtility.CheckCenter(rectTransform); var centerLocal = center; Vector4 uv, uvInner; Vector4 rect; if (middle != null) { width = middle.rect.width * 0.5f; offset = new Vector2(width, 0); uv = DataUtility.GetOuterUV(middle); uvInner = DataUtility.GetInnerUV(middle); rect = new Vector4(-width, -height, width, height); if (uv == uvInner) { MeshUtility.AddSimple(vh, color, centerLocal, rect, uv); } else { MeshUtility.AddSliced(vh, color, centerLocal, rect, uv, uvInner, middle.border); } } width = rectTransform.rect.width * 0.5f - width; uv = DataUtility.GetOuterUV(left); uvInner = DataUtility.GetInnerUV(left); rect = new Vector4(-width, -height, 0, height); centerLocal = -offset; if (uv == uvInner) { MeshUtility.AddSimple(vh, color, centerLocal, rect, uv); } else { MeshUtility.AddSliced(vh, color, centerLocal, rect, uv, uvInner, left.border); } uv = DataUtility.GetOuterUV(right); uvInner = DataUtility.GetInnerUV(right); rect = new Vector4(0, -height, width, height); centerLocal = center + offset; if (uv == uvInner) { MeshUtility.AddSimple(vh, color, centerLocal, rect, uv); } else { MeshUtility.AddSliced(vh, color, centerLocal, rect, uv, uvInner, right.border); } }
public override void Event_MoveBack(AnimationEvent animEvent) { if (currentOpponent == null || currentOpponent is Object && currentOpponent.Equals(null)) { return; } var frameRate = animEvent.animatorClipInfo.clip.frameRate; var length = CalculatorUtility.TimeByFrame(animEvent.floatParameter, frameRate); StartCoroutine(TransformUtility.MoveToTarget(transform, currentOpponent.impactPoint.transform.position, _originalPosition, length)); }
public void SetRotation(Quaternion newRot) { if (MainBody != null && PhysicsEntity.Enabled) { PhysicsEntity.SetRotation(MainBody, TransformUtility.GetAngleRollFromQuaternion(newRot)); } else { MainNode.SetRotation(newRot); } }
void Awake() { PlayerRespawner.allRespawners.Add(this); if (!string.IsNullOrEmpty(this._bgFadeCamera)) { this.backCam = TransformUtility.GetByName <Camera>(this._bgFadeCamera); if (this.backCam != null) { this.startFadeColor = this.backCam.backgroundColor; } } }
private static void GroupToFolder(MenuCommand command) { if (!EditorUtility.IsNewFrame(ref lastFrame)) { return; } var transforms = Selection.transforms; var newParent = TransformUtility.CreateGroup(transforms, GroupingMode.Folder); Selection.activeTransform = newParent; }
public static bool GetSpawnPoint(string doorName, out Vector3 pos, out Vector3 dir) { SceneDoor byName = TransformUtility.GetByName <SceneDoor>(doorName); if (byName != null) { pos = byName.transform.TransformPoint(byName._spawnOffset); dir = -byName.transform.forward; return(true); } pos = (dir = Vector3.zero); return(false); }
public void should_find_five_testmethods() { var s = @" { [TestMethod] public void test1() { } [TestMethod] public void test2() { } [TestMethod] public void test3() { } [TestMethod] public void test4() { } [TestMethod] public void test5() { } public void test6() { } public void test7() { } "; List <string> result = new TransformUtility().GetTestMethodSignatures(s); CollectionAssert.AreEqual(new string[] { "public void test1()", "public void test2()", "public void test3()", "public void test4()", "public void test5()", }, result); }
public void UnparentChildrenAndReparentChildren_ChildrenAreInSameOrder() { Assume.That(m_Parent.childCount, Is.EqualTo(k_ChildCount)); TransformUtility.UnparentChildren(m_Parent); Assume.That(m_Parent.childCount, Is.EqualTo(0)); TransformUtility.ReparentChildren(m_Parent); Assume.That(m_Parent.childCount, Is.EqualTo(k_ChildCount)); for (int i = 0; i < k_ChildCount; ++i) { Assert.That(m_Parent.GetChild(i), Is.EqualTo(m_Children[i])); } }
public override void DrawModuleHelper() { updateParamsChanged(); UnityEditor.Handles.color = Color.white; foreach (var item in debugLine) { UnityEditor.Handles.DrawLine(item.Location, item.Location + item.Foward); } UnityEditor.Handles.color = Color.green; if (arc == 0) { return; } if (arc == 360) { UnityEditor.Handles.DrawWireDisc(transform.position, transform.up, radius); UnityEditor.Handles.DrawWireDisc(transform.position, transform.up, radius * (1 - radiusThickness)); } else { float spanAngle = -Mathf.PI * 2f * (arcOffset / 360); if (radiusThickness != 0) { int drawLineCount = 2; Vector3[] points = new Vector3[2]; for (int i = 0; i < drawLineCount; i++) { Vector3 from = TransformUtility.Get3DCirclePoint(spanAngle, radius, transform.position, transform.up, transform.right); Vector3 to = TransformUtility.Get3DCirclePoint(spanAngle, radius * (1 - radiusThickness), transform.position, transform.up, transform.right); UnityEditor.Handles.DrawLine(from, to); spanAngle -= Mathf.PI * 2f * (arc / 360); if (i == 0) { points[0] = from; points[1] = to; } } UnityEditor.Handles.DrawWireArc(transform.position, transform.up, points[0] - points[1], arc, radius); UnityEditor.Handles.DrawWireArc(transform.position, transform.up, points[0] - points[1], arc, radius * (1 - radiusThickness)); } else { Vector3 from = TransformUtility.Get3DCirclePoint(spanAngle, radius, transform.position, transform.up, transform.right); UnityEditor.Handles.DrawWireArc(transform.position, transform.up, from - transform.position, arc, radius); } } }
private void OnEnable() { emitterWidth = 194; emitterHeight = 49; moduleHeight = 35; int padding = 15; moduleStyle = new GUIStyle(); moduleStyle.normal.background = MakeTex(2, 2, TransformUtility.hexToColor("3b3e4a")); moduleStyle.border = new RectOffset(12, 12, 12, 12); moduleStyle.padding = new RectOffset(padding, padding, padding, padding); moduleStyle.normal.textColor = Color.white; refreshStaticReference(); }
/** EXAMPLE FOR ENUM * //emitFrom = (EmitFrom) FieldInspectorHelper.ShowDropdownField("Emit From", System.Enum.GetNames(typeof(EmitFrom)), (int)emitFrom, skin); */ public static int ShowDropdownField(string fieldName, string[] valueList, int value, GUISkin skin) { for (int i = 0; i < valueList.Length; i++) { valueList[i] = TransformUtility.AddSpacesToSentence(valueList[i]); } GUILayout.BeginVertical(); GUILayout.BeginHorizontal(); EditorGUILayout.LabelField(fieldName, skin.label, FieldLabelGUIOption, FieldDefaultHeightGUIOption); var output = EditorGUILayout.Popup(value, valueList, skin.GetStyle("Dropdown"), FieldMaxWidthGUIOption); GUILayout.EndHorizontal(); GUILayout.EndVertical(); return(output); }
public void SetRotation(Body center, float newRotation) { float modifier = newRotation - center.Rotation; foreach (Body b in _bodies.Values) { TransformUtility.RotateBodyAroundPoint(b, center.Position, modifier); } foreach (var p in _paths.Values) { foreach (var b in p.Bodies) { TransformUtility.RotateBodyAroundPoint(b, center.Position, modifier); } } }
private void Awake() { pixelShader = Resources.Load <Material>("Materials/PixelSnapMat"); ground = Resources.Load <Tile>("Tiles/Ground_Tile"); backGround = Resources.Load <Tile>("Tiles/BackGround_Tile"); SpawnerPrefab = Resources.Load <GameObject>("Prefabs/Spawner"); chunkSize = GameManager.Instance.Settings.chunkSize; width = worldInfo.worldSizeInChunks.x; heigth = worldInfo.worldSizeInChunks.y; if (worldInfo.chunks == null) { worldInfo.chunks = new ChunkInfo[width][]; for (int i = 0; i < width; i++) { worldInfo.chunks[i] = new ChunkInfo[heigth]; } } SetWorldColor(worldInfo.color); Physics2D.gravity = new Vector2(0, worldInfo.gravity); int layers = 2; for (int i = 0; i < layers; i++) { tileMaps.Add(SetupTilemap()); } SetDungeons(); SetUpWorld(); navMesh = NodeNavMesh.CreateNavMesh(gameObject, tileMaps[0]); tileMaps[0].GetComponent <TilemapRenderer>().material = Resources.Load <Material>("Materials/GoundMat"); tileMaps[0].GetComponent <TilemapRenderer>().material.SetColor("_Color1", worldInfo.color); SetSpawners(); SetWorldLimits(); FindObjectOfType <Player>().OnDiggingToDir += CheckDestruction; worldInfo.Save(); TransformUtility.ChangeLayersRecursively(transform, gameObject.layer); }
public void Load(string creatureName) { Clear(); CreatureData data = JsonUtility.FromJson <CreatureData>(SaveUtility.Load(creatureName + ".json")); for (int i = 0; i < data.bones.Count; i++) { Bone bone = data.bones[i]; Add(i, bone.Position, bone.Rotation, bone.Size); } for (int i = 0; i < data.attachedBodyParts.Count; i++) { AttachedBodyPart attachedBodyPart = data.attachedBodyParts[i]; BodyPartController bpc = Instantiate(DatabaseManager.GetDatabaseEntry <BodyPart>("Body Parts", attachedBodyPart.BodyPartID).Prefab, root.GetChild(attachedBodyPart.BoneIndex)).GetComponent <BodyPartController>(); bpc.gameObject.name = attachedBodyPart.BodyPartID; TransformUtility.RecurseUpdate(bpc.transform, attachedBodyPart.Transform); SetupBodyPart(bpc); AttachBodyPart(bpc); AddToStatistics(bpc.name); if (Mathf.Abs(bpc.transform.position.x) > settings.MergeThreshold) { bpc.Flipped.transform.position = new Vector3(-bpc.transform.position.x, bpc.transform.position.y, bpc.transform.position.z); bpc.Flipped.transform.rotation = Quaternion.Euler(bpc.transform.rotation.eulerAngles.x, -bpc.transform.rotation.eulerAngles.y, -bpc.transform.rotation.eulerAngles.z); } else { bpc.Flipped.gameObject.SetActive(false); } } SetColours(data.primaryColour, data.secondaryColour); SetPattern(data.patternID); SetSelected(false); SetTextured(Textured); SetInteractable(Interactable); }
private void Shoot() { GameObject bGo = Instantiate(bullet, bulletSpawnTr.position, Quaternion.identity) as GameObject; TransformUtility.RotateTransformTowards(bGo.transform, targetTr.position); Rigidbody2D bRb = bGo.GetComponent <Rigidbody2D>(); bRb.velocity = (targetTr.position - bulletSpawnTr.position).normalized * bulletSpeed; Sprite original = handSpriteRenderer.sprite; handSpriteRenderer.sprite = fireHandSprite; coroutines.WaitThenExecute(0.1f, () => { if (handSpriteRenderer) //if we didn't die in the meantime, so the rendered still exists { handSpriteRenderer.sprite = original; } }); sfx.TryPlayOnce("Shoot"); }
private void GunFaceTarget() { if (tr.localScale.x > 0) //if looking right { TransformUtility.RotateTransformTowards(armRotationPivot, targetTr.position); } //if looking left, create a new position vector, which is a projection of //targetTr.position through armRotationPivot's position. #region further_explanation //imagine a line from targetTr.position to armRotPiv.position. Now //imagine a line that is perpendicular to this line. This new line //acts as a mirror and the projected point is the mirror image of //targetTr.position #endregion further_explanation else { Vector3 proj = 2 * armRotationPivot.position - targetTr.position; TransformUtility.RotateTransformTowards(armRotationPivot, proj); } }