/// 分割时间 private static void MathT(BezierData sBezierData) { sBezierData.tArr = new List <float>(); float disTotal = 0f; float disAdd = 0f; for (int index = 0; index < sBezierData.pointArr.Count - 1; index++) { disTotal += Vector3.Distance(sBezierData.pointArr[index], sBezierData.pointArr[index + 1]); } for (int index = 0; index < sBezierData.pointArr.Count - 1; index++) { disAdd += Vector3.Distance(sBezierData.pointArr[index], sBezierData.pointArr[index + 1]); sBezierData.tArr.Add(disAdd / disTotal); } }
public static BezierData GetBezier(List <Vector3> sPoints, List <float> sTArr, float sT) { BezierData bezierData = new BezierData(); bezierData.pointArr = sPoints; /// 分割锚点 MathCPPoint(bezierData); /// 分割时间 bezierData.tArr = sTArr; if (sTArr == null) { MathT(bezierData); } /// 真正计算值的地方 return(GetBezier(bezierData, sT)); }
/// 所有点已经缓存好,可以进行高效计算。血省啊 public static BezierData GetBezier(BezierData sBezierData, float sT) { int index = 0; /// 找出当前相近的时间 for (index = 0; index < sBezierData.tArr.Count - 1; index++) { if (sBezierData.tArr[index] > sT) { break; } } float t = (sT - (index == 0 ? 0f : sBezierData.tArr[index - 1])) / (sBezierData.tArr[index] - (index == 0 ? 0f : sBezierData.tArr[index - 1])); /// 计算出贝塞尔曲线 sBezierData.result = MathBezier(sBezierData.pointArr[index], sBezierData.pointPCArr[index][0], sBezierData.pointPCArr[index][1], sBezierData.pointArr[index + 1], t); sBezierData.t = sT; return(sBezierData); }
/// 分割锚点 private static void MathCPPoint(BezierData sBezierData) { sBezierData.pointPCArr = new List <Vector3[]>(); /// 分割锚点 for (int index = 0; index < sBezierData.pointArr.Count - 1; index++) { sBezierData.pointPCArr.Add(new Vector3[] { Vector3.zero, Vector3.zero }); Vector3 pointA = Vector3.zero; Vector3 pointB = Vector3.zero; Vector3 pointC = Vector3.zero; /// 计算 P2点 pointA = (sBezierData.pointArr[index] + sBezierData.pointArr[index + 1]) * 0.5f; pointB = (sBezierData.pointArr[index] + sBezierData.pointArr[Mathf.Abs(index - 1)]) * 0.5f; pointC = (pointA + pointB) * 0.5f; sBezierData.pointPCArr[index][0] = (sBezierData.pointArr[index] - pointC) + pointA; /// 计算P3点 pointB = (sBezierData.pointArr[index + 1] + sBezierData.pointArr[Mathf.Min(index + 2, sBezierData.pointArr.Count - 1)]) * 0.5f; pointC = (pointA + pointB) * 0.5f; sBezierData.pointPCArr[index][1] = (sBezierData.pointArr[index + 1] - pointC) + pointA; } }
public void Execute(int index) { var modifiers = LineTool.Data.Modifiers; var jp1 = LineJoinPoints[index].A; var jp2 = LineJoinPoints[index].B; var pointAIsConnected = JoinPoints.Exists(jp1.JoinToPointEntity); var pointBIsConnected = JoinPoints.Exists(jp2.JoinToPointEntity); var pointA = jp1.Pivot; var pointB = jp2.Pivot; // Two curves b1, b2 float3x3 b1, b2; // c0 is the origin b1.c0 = pointA; b2.c0 = pointB; // If join points invalid or not connected initialise to facing other point jp1.Direction = jp1.Direction.Equals(float3.zero) || float.IsNaN(jp1.Direction.x) || !pointBIsConnected && !pointAIsConnected ? Normalize(pointB - pointA) : jp1.Direction; jp2.Direction = jp2.Direction.Equals(float3.zero) || float.IsNaN(jp2.Direction.x) || !pointAIsConnected && !pointBIsConnected ? Normalize(pointA - pointB) : jp2.Direction; var forwards = new float3x2(jp1.Direction, jp2.Direction); var distances = new float2( Distance(pointA, pointB, forwards.c0), Distance(pointB, pointA, forwards.c1)); var scales = new float2( Scale(modifiers.From.Size, distances.x), Scale(modifiers.To.Size, distances.y)); if (pointAIsConnected && !pointBIsConnected) { distances.y = 0f; b1.c1 = GetOrigin(); jp2.Direction = Normalize(b1.c1 - b2.c0); b1.c2 = Target(b1.c1, b2.c0, distances.x, distances.y, scales.x, scales.y, modifiers.From.Ratio); b2.c2 = b2.c1 = b2.c0; } else if (!pointAIsConnected && pointBIsConnected) { distances.x = 0f; b2.c1 = GetEnd(); // Do Rotate jp1.Direction = Normalize(b2.c1 - b1.c0); b2.c2 = Target(b2.c1, b1.c0, distances.y, distances.x, scales.y, scales.x, modifiers.To.Ratio); b1.c2 = b1.c1 = b1.c0; } else { if (!pointAIsConnected) { jp1.Direction = Normalize(b2.c0 - b1.c0); } if (!pointBIsConnected) { jp2.Direction = Normalize(b1.c0 - b2.c0); } b1.c1 = GetOrigin(); b2.c1 = GetEnd(); b1.c2 = Target(b1.c1, b2.c1, distances.x, distances.y, scales.x, scales.y, modifiers.From.Ratio); b2.c2 = Target(b2.c1, b1.c1, distances.y, distances.x, scales.y, scales.x, modifiers.To.Ratio); } BezierData[index] = new BezierData { B1 = b1, B2 = b2 }; LineJoinPoints[index] = new JoinPointPair { A = jp1, B = jp2 }; float3 GetOrigin() { return(GetControlPoint(forwards.c0, pointA, distances.x, scales.x, modifiers.From.Ratio)); } float3 GetEnd() { return(GetControlPoint(forwards.c1, pointB, distances.y, scales.y, modifiers.To.Ratio)); }
private IEnumerator EmitEffectImpl(GameObject prefab, int count, RectTransform startPoint, RectTransform endPoint, string rewardType, int rewardIndex) { float interval = 1; float controlPointLength = 400; for (int i = 0; i < count; i++) { yield return(new WaitForSeconds(0.06f)); GameObject instance = Instantiate <GameObject>(prefab); RectTransform rectTransform = instance.GetComponent <RectTransform>(); rectTransform.SetParent(transform, false); rectTransform.anchoredPosition = startPoint.anchoredPosition; BezierMover mover = instance.GetComponent <BezierMover>(); BezierData bezierData = null; Vector2 diff = endPoint.anchoredPosition - startPoint.anchoredPosition; if (rewardType == "playercash") { bezierData = new BezierData { Interval = interval, Type = BezierType.Quadratic, Target = instance.GetComponent <RectTransformPositionObject>(), Points = new Vector3[] { startPoint.anchoredPosition, diff * 0.5f + diff.normalized.Orthogonal() * UnityEngine.Random.Range(-controlPointLength, 0), endPoint.anchoredPosition }, OnComplete = g => Destroy(g) }; } else if (rewardType == "companycash") { bezierData = new BezierData { Interval = interval, Type = BezierType.Quadratic, Target = instance.GetComponent <RectTransformPositionObject>(), Points = new Vector3[] { startPoint.anchoredPosition, diff * 0.5f + diff.normalized.Orthogonal() * UnityEngine.Random.Range(0, controlPointLength), endPoint.anchoredPosition }, OnComplete = g => Destroy(g) }; } else { bezierData = new BezierData { Interval = interval, Type = BezierType.Quadratic, Target = instance.GetComponent <RectTransformPositionObject>(), Points = new Vector3[] { startPoint.anchoredPosition, diff * 0.5f + diff.normalized.Orthogonal() * UnityEngine.Random.Range(-controlPointLength * 0.5f, controlPointLength * 0.5f), endPoint.anchoredPosition }, OnComplete = g => Destroy(g) }; } mover.Setup(bezierData); ColorAnimator colorAnimator = instance.GetComponent <ColorAnimator>(); colorAnimator.StartAnimation(AnimUtils.GetColorAnimData(new Color(1, 1, 1, 1f), Color.white, 0.3f, EaseType.EaseInOutQuad, rectTransform, BosAnimationMode.Single, () => { colorAnimator.StartAnimation(AnimUtils.GetColorAnimData(Color.white, new Color(1, 1, 1, 1f), 0.4f, EaseType.EaseInOutQuad, rectTransform, BosAnimationMode.Single, () => { })); })); Vector3Animator scaleAnimator = instance.GetComponent <Vector3Animator>(); scaleAnimator.StartAnimation(new Vector3AnimationData { AnimationMode = BosAnimationMode.PingPong, Duration = 0.2f, EaseType = EaseType.EaseInOutQuad, StartValue = new Vector3(1, 1, 1), EndValue = new Vector3(2f, 2f, 1), Target = instance, OnStart = rectTransform.UpdateScaleFunctor(), OnUpdate = rectTransform.UpdateScaleTimedFunctor(), OnEnd = rectTransform.UpdateScaleFunctor() }); FloatAnimator rotationAnimator = instance.GetComponent <FloatAnimator>(); rotationAnimator.StartAnimation(new FloatAnimationData { Duration = interval, AnimationMode = BosAnimationMode.Single, EaseType = EaseType.Linear, StartValue = 0, EndValue = 720, Target = instance, OnStart = rectTransform.UpdateZRotation(), OnUpdate = rectTransform.UpdateZRotationTimed(), OnEnd = rectTransform.UpdateZRotation() }); } yield return(new WaitForSeconds(interval - 0.1f)); CompleteRewardIndex(rewardIndex); }