Example #1
0
        /// <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);
        }