/// <summary> /// Do thing when is touched. /// </summary> private void WhenTouched() { Vector3 currPos = Input.mousePosition; if (mDeltaPos == Vector2.zero && mDragDistance == Vector2.zero) { this.mDragStartPosition = currPos; } else { this.mDragging = true; Vector2 dragEndPosition = currPos; this.mDragDistance.x = JCS_Mathf.DistanceOfUnitVector(mDragStartPosition.x, dragEndPosition.x); this.mDragDistance.y = JCS_Mathf.DistanceOfUnitVector(mDragStartPosition.y, dragEndPosition.y); float xDiff = dragEndPosition.x - mDragStartPosition.x; float yDiff = dragEndPosition.y - mDragStartPosition.y; this.mDragDisplacement.x = mDragDistance.x * JCS_Mathf.GetSign(xDiff); this.mDragDisplacement.y = mDragDistance.y * JCS_Mathf.GetSign(yDiff); } #if (UNITY_STANDALONE || UNITY_EDITOR) mDeltaPos = currPos - mPrePos; #elif (UNITY_ANDROID || UNITY_IPHIONE || UNITY_IOS) mDeltaPos = Input.GetTouch(0).deltaPosition; #endif }
/// <summary> /// Check if the character controller top of the box with the /// slop calculation. /// </summary> /// <param name="cap"> character controller to test. </param> /// <param name="rect"> box to test. </param> /// <returns> /// true : is top of box. /// false : vice versa. /// </returns> public static bool TopOfBoxWithSlope(CharacterController cap, BoxCollider rect) { float innerAngle = rect.transform.localEulerAngles.z; // if no angle interact, just use the normal one. if (innerAngle == 0) { return(TopOfBox(cap, rect)); } /* Capsule */ Vector3 capScale = cap.transform.localScale; capScale = JCS_Mathf.AbsoluteValue(capScale); Vector3 cCenter = new Vector3( cap.center.x * capScale.x, cap.center.y * capScale.y, cap.center.z * capScale.z); Vector3 capCenterPos = cap.transform.position + cCenter; float cR = cap.radius * capScale.x; float cH = (cap.height - (cap.radius * 2.0f)) * capScale.y; // capsule botton point position. float cBotBound = cap.transform.position.y + cCenter.y - (cH / 2.0f) - cR; /* Box */ Vector3 rectScale = rect.transform.localScale; rectScale = JCS_Mathf.AbsoluteValue(rectScale); float rectWidth = rect.size.x * rectScale.x; float rectHeight = rect.size.y * rectScale.y; Vector3 rectCenter = new Vector3( rect.center.x * rectScale.x, rect.center.y * rectScale.y, rect.center.z * rectScale.z); Vector3 rectCenterPos = rect.transform.position + rectCenter; float radianInnerAngle = JCS_Mathf.DegreeToRadian(innerAngle); // at here 'rectHeight' are the same as 'adjacent'. // hyp = adj / cos(Θ) /* 斜角度的高度. */ float hypHeight = (rectHeight / Mathf.Cos(radianInnerAngle)) / 2; // 求'水平寬'. // adj = cos(Θ) * hyp float rectLeftToRight = Mathf.Cos(radianInnerAngle) * rectWidth; // 求'垂直高'. float rectTopAndBot = Mathf.Sin(radianInnerAngle) * rectWidth; float distRectLeftToCapCenter = JCS_Mathf.DistanceOfUnitVector( capCenterPos.x, rectCenterPos.x - (rectLeftToRight / 2)); /* Check if the capsule inside the the rect on x-axis. */ { float distCapToBox = JCS_Mathf.DistanceOfUnitVector( capCenterPos.x, rectCenterPos.x); if (distCapToBox > rectLeftToRight / 2) { return(false); } } float heightToCapBot = JCS_Mathf.CrossMultiply( rectLeftToRight, distRectLeftToCapCenter, rectTopAndBot); #if (UNITY_EDITOR) Debug.DrawLine( new Vector3( rectCenterPos.x - (rectLeftToRight / 2) + distRectLeftToCapCenter, rectCenterPos.y - (rectTopAndBot / 2), rectCenterPos.z), new Vector3( rectCenterPos.x - (rectLeftToRight / 2) + distRectLeftToCapCenter, rectCenterPos.y + heightToCapBot + hypHeight - (rectTopAndBot / 2), rectCenterPos.z), Color.cyan); #endif // 在平台上的點. float pointOnPlatform = rectCenterPos.y + heightToCapBot + hypHeight - (rectTopAndBot / 2); if (pointOnPlatform <= cBotBound) { return(true); } return(false); }
/// <summary> /// Set the box collider ontop of the other box collider /// with slop as a variable. /// </summary> /// <param name="setBox"> box we are setting on top of the other box </param> /// <param name="beSetBox"> box be under the setting box </param> /// <returns></returns> public static Vector3 SetOnTopOfBoxWithSlope(BoxCollider topBox, BoxCollider botBox, float offset = 0) { float innerAngle = botBox.transform.localEulerAngles.z; // if no angle interact, just use the normal one. if (innerAngle == 0) { return(SetOnTopOfBox(topBox, botBox)); } /* Top Box */ Vector3 topBoxScale = topBox.transform.localScale; topBoxScale = JCS_Mathf.AbsoluteValue(topBoxScale); Vector2 topBoxWH = GetColliderWidthHeight(topBox); Vector3 topBoxCenter = new Vector3( topBox.center.x * topBoxScale.x, topBox.center.y * topBoxScale.y, topBox.center.z * topBoxScale.z); Vector3 topBoxCenterPos = topBox.transform.position + topBoxCenter; /* Bot Box */ Vector3 rectScale = botBox.transform.localScale; rectScale = JCS_Mathf.AbsoluteValue(rectScale); float rectWidth = botBox.size.x * rectScale.x; float rectHeight = botBox.size.y * rectScale.y; Vector3 rectCenter = new Vector3( botBox.center.x * rectScale.x, botBox.center.y * rectScale.y, botBox.center.z * rectScale.z); Vector3 rectCenterPos = botBox.transform.position + rectCenter; float radianInnerAngle = JCS_Mathf.DegreeToRadian(innerAngle); // at here 'rectHeight' are the same as 'adjacent'. // hyp = adj / cos(Θ) /* 斜角度的高度. */ float hypHeight = (rectHeight / Mathf.Cos(radianInnerAngle)) / 2; // 求'水平寬'. // adj = cos(Θ) * hyp float rectLeftToRight = Mathf.Cos(radianInnerAngle) * rectWidth; // 求'垂直高'. float rectTopAndBot = Mathf.Sin(radianInnerAngle) * rectWidth; float distRectLeftToCapCenter = JCS_Mathf.DistanceOfUnitVector( topBoxCenterPos.x, rectCenterPos.x - (rectLeftToRight / 2)); /* Check if the capsule inside the the rect on x-axis. */ { float distCapToBox = JCS_Mathf.DistanceOfUnitVector( topBoxCenterPos.x, rectCenterPos.x); if (distCapToBox > rectLeftToRight / 2) { return(Vector3.zero); } } float heightToCapBot = JCS_Mathf.CrossMultiply( rectLeftToRight, distRectLeftToCapCenter, rectTopAndBot); #if (UNITY_EDITOR) Debug.DrawLine( new Vector3( rectCenterPos.x - (rectLeftToRight / 2) + distRectLeftToCapCenter, rectCenterPos.y - (rectTopAndBot / 2), rectCenterPos.z), new Vector3( rectCenterPos.x - (rectLeftToRight / 2) + distRectLeftToCapCenter, rectCenterPos.y + heightToCapBot + hypHeight - (rectTopAndBot / 2), rectCenterPos.z), Color.cyan); #endif // 在平台上的點. float pointOnPlatform = rectCenterPos.y + heightToCapBot + hypHeight - (rectTopAndBot / 2); /** ------------------------------------------- **/ Vector3 newPos = topBoxCenterPos; newPos.y = pointOnPlatform + (topBoxWH.y / 2); topBox.transform.position = newPos - topBoxCenter; return(newPos); }
/// <summary> /// Check if two collider collapse. /// </summary> /// <param name="cap"></param> /// <param name="rect"></param> /// <returns></returns> public static bool JcsOnTriggerCheck(CharacterController cap, BoxCollider rect) { Vector3 rectScale = rect.transform.localScale; Vector3 capScale = cap.transform.localScale; rectScale = JCS_Mathf.AbsoluteValue(rectScale); capScale = JCS_Mathf.AbsoluteValue(capScale); float rWidth = rect.size.x * rectScale.x; float rHeight = rect.size.y * rectScale.y; //float widthSqr = JCS_Mathf.Sqr(rWidth); //float heightSqr = JCS_Mathf.Sqr(rHeight); //float diagonal = Mathf.Sqrt(widthSqr + heightSqr); rWidth = JCS_Mathf.AbsoluteValue(rWidth); rHeight = JCS_Mathf.AbsoluteValue(rHeight); Vector3 rectCenter = new Vector3( rect.center.x * rectScale.x, rect.center.y * rectScale.y, rect.center.z * rectScale.z); Vector3 cCenter = new Vector3( cap.center.x * capScale.x, cap.center.y * capScale.y, cap.center.z * capScale.z); float cR = cap.radius * capScale.x; float cH = (cap.height - (cap.radius * 2.0f)) * capScale.y; float offsetY = cCenter.y; float cHalfHeight = cH / 2.0f; if (cH < 0) { cH = 0; } Vector3 topCirclePoint = new Vector3( cap.transform.position.x + cCenter.x, cap.transform.position.y + cHalfHeight + offsetY, cap.transform.position.z + cCenter.z); Vector3 botCirclePoint = new Vector3( cap.transform.position.x + cCenter.x, cap.transform.position.y - cHalfHeight + offsetY, cap.transform.position.z + cCenter.z); float maxDistX = cR + (rWidth / 2.0f); float maxDistY = ((cH / 2.0f) + cR) + (rHeight / 2.0f); float realDistX = JCS_Mathf.DistanceOfUnitVector( cap.transform.position.x + cCenter.x, rect.transform.position.x + rectCenter.x); float realDistY = JCS_Mathf.DistanceOfUnitVector( cap.transform.position.y + cCenter.y, rect.transform.position.y + rectCenter.y); if (realDistX <= maxDistX && realDistY <= maxDistY) { Vector2 rectPosOffset = new Vector2( rect.transform.position.x + rectCenter.x, rect.transform.position.y + rectCenter.y ); Rect r = new Rect(); r.x = rectPosOffset.x - (rWidth / 2.0f); r.y = rectPosOffset.y + (rHeight / 2.0f); r.width = rectPosOffset.x + (rWidth / 2.0f); r.height = rectPosOffset.y - (rHeight / 2.0f); Vector2 topLeft = new Vector2(r.x, r.y); Vector2 topRight = new Vector2(r.width, r.y); Vector2 botRight = new Vector2(r.width, r.height); Vector2 botLeft = new Vector2(r.x, r.height); #if (UNITY_EDITOR) //Debug.DrawLine(topLeft, topCirclePoint); //Debug.DrawLine(topRight, topCirclePoint); //Debug.DrawLine(botRight, topCirclePoint); //Debug.DrawLine(botLeft, topCirclePoint); //Debug.DrawLine(topLeft, botCirclePoint); //Debug.DrawLine(topRight, botCirclePoint); //Debug.DrawLine(botRight, botCirclePoint); //Debug.DrawLine(botLeft, botCirclePoint); #endif // check if point intersect with each other float distance = 0; // top circle distance = Vector2.Distance(topLeft, topCirclePoint); if (distance <= cR) { return(true); } distance = Vector2.Distance(topRight, topCirclePoint); if (distance <= cR) { return(true); } distance = Vector2.Distance(botRight, topCirclePoint); if (distance <= cR) { return(true); } distance = Vector2.Distance(botLeft, topCirclePoint); if (distance <= cR) { return(true); } // bot circle distance = Vector2.Distance(topLeft, botCirclePoint); if (distance <= cR) { return(true); } distance = Vector2.Distance(topRight, botCirclePoint); if (distance <= cR) { return(true); } distance = Vector2.Distance(botRight, botCirclePoint); if (distance <= cR) { return(true); } distance = Vector2.Distance(botLeft, botCirclePoint); if (distance <= cR) { return(true); } } return(false); }