/// <summary>
        /// Set a collider on top of a box collider.
        /// </summary>
        /// <param name="cap"></param>
        /// <param name="rect"></param>
        /// <param name="offset"></param>
        /// <returns></returns>
        public static Vector3 SetOnTopOfBox(CharacterController cap, BoxCollider rect, float offset)
        {
            Vector2 rWH = GetColliderWidthHeight(rect);
            Vector2 cWH = GetColliderWidthHeight(cap);

            Vector3 rectScale = rect.transform.localScale;
            Vector3 capScale  = cap.transform.localScale;

            rectScale = JCS_Mathf.AbsoluteValue(rectScale);
            capScale  = JCS_Mathf.AbsoluteValue(capScale);

            // 取得Collider的中心"相對位置".
            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);

            // * rectCenter 跟 rect.transfrom.position 是"相對位置',
            // 所以要相加才能得到正確的"世界位置"!
            // * cCenter + cap.transform.position 同理.
            Vector3 newPos = cCenter + cap.transform.position;

            newPos.y = rectCenter.y + rect.transform.position.y + (rWH.y / 2.0f) + (cWH.y / 2.0f) + offset;

            // 這裡要扣掉原本的中心位置
            cap.transform.position = newPos - cCenter;

            // optional
            return(newPos);
        }
Esempio n. 2
0
        private void Update()
        {
            if (!mEffect)
            {
                return;
            }

            mDistanceRecorder += JCS_Mathf.AbsoluteValue(mMoveSpeed) * Time.deltaTime;

            if (mDistanceRecorder > mDistance)
            {
                mDistanceRecorder = 0;

                if (!mStayAtLastPosition)
                {
                    this.transform.position = mRecordPosition;
                }

                // if is not loop disable the effect
                if (!mLoop)
                {
                    mEffect = false;
                }
            }


            DoMovement(mAxis, mMoveSpeed);
        }
Esempio n. 3
0
        private void Update()
        {
            if (!mIsYAxis)
            {
                this.mVelocity.x = mMoveSpeed;

                float distance = this.transform.position.x - mOriginPosition.x;
                distance = JCS_Mathf.AbsoluteValue(distance);
                if (distance > mWidth)
                {
                    this.transform.position = mOriginPosition;
                }
            }
            else
            {
                this.mVelocity.y = mMoveSpeed;

                float distance = this.transform.position.y - mOriginPosition.y;
                distance = JCS_Mathf.AbsoluteValue(distance);
                if (distance > mHeight)
                {
                    this.transform.position = mOriginPosition;
                }
            }

            this.transform.position += mVelocity * Time.deltaTime;
        }
        /// <summary>
        /// Difference between target position and current position.
        /// </summary>
        /// <returns></returns>
        public Vector3 PositionDiff()
        {
            JCS_SlidePanel sp      = mSlidePanelsComponents[0];
            Vector3        curPos  = sp.transform.position;
            Vector3        targPos = sp.GetTargetPosition();

            return(JCS_Mathf.AbsoluteValue(curPos - targPos));
        }
Esempio n. 5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="type"></param>
        public void TurnFace(JCS_2DFaceType type)
        {
            Vector3 originalScale         = this.gameObject.transform.localScale;
            float   absoluteOriginalScale = JCS_Mathf.AbsoluteValue(originalScale.x);

            this.gameObject.transform.localScale = new Vector3((int)type * absoluteOriginalScale, originalScale.y, originalScale.z);

            mFace = type;
        }
        /// <summary>
        /// Check if the character controller top of the box without
        /// slope 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 TopOfBox(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;

            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;

            if (cH < 0)
            {
                cH = 0;
            }

            float rTopBound = rect.transform.position.y + rectCenter.y + (rHeight / 2.0f);
            float cBotBound = cap.transform.position.y + cCenter.y - (cH / 2.0f) - cR;

#if (UNITY_EDITOR)
            Debug.DrawLine(rect.transform.position + rectCenter,
                           new Vector3(
                               rect.transform.position.x,
                               rTopBound,
                               rect.transform.position.z)
                           , Color.cyan);

            Debug.DrawLine(cap.transform.position + cCenter,
                           new Vector3(
                               cap.transform.position.x,
                               cBotBound,
                               cap.transform.position.z)
                           , Color.blue);
#endif

            if (rTopBound <= cBotBound)
            {
                return(true);
            }

            return(false);
        }
        /// <summary>
        /// Return CharacterController's collider's center as
        /// a global position.
        /// </summary>
        /// <returns> CharacterController's collider's center as a
        /// global position. </returns>
        public static Vector3 GetColliderCenterPosition(CharacterController cap)
        {
            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;

            return(capCenterPos);
        }
        /// <summary>
        /// Return BoxCollider's center as a global position.
        /// </summary>
        /// <returns> box collider's center as a global position. </returns>
        public static Vector3 GetColliderCenterPosition(BoxCollider rect)
        {
            Vector3 rectScale = rect.transform.localScale;

            rectScale = JCS_Mathf.AbsoluteValue(rectScale);

            // 取得Collider的中心"相對位置".
            Vector3 rectCenter = new Vector3(
                rect.center.x * rectScale.x,
                rect.center.y * rectScale.y,
                rect.center.z * rectScale.z);

            // 所以要相加才能得到正確的"世界位置"!
            // * cCenter + cap.transform.position 同理.
            return(rectCenter + rect.transform.position);
        }
        /// <summary>
        /// Return Box Collider's width and height.
        /// </summary>
        /// <param name="cap"> object we want to take from </param>
        /// <returns> x : width, y : height </returns>
        public static Vector2 GetColliderWidthHeight(BoxCollider rect)
        {
            // holder
            Vector2 widthHeight = Vector2.zero;

            Vector3 rectScale = rect.transform.localScale;

            rectScale = JCS_Mathf.AbsoluteValue(rectScale);

            float rWidth  = rect.size.x * rectScale.x;
            float rHeight = rect.size.y * rectScale.y;

            // apply to holder
            widthHeight.x = rWidth;
            widthHeight.y = rHeight;

            return(widthHeight);
        }
        /// <summary>
        /// Check if a collider under the bottom of the box collider.
        /// </summary>
        /// <param name="cap"></param>
        /// <param name="rect"></param>
        /// <returns></returns>
        public static bool BottomOfBox(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;

            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;

            if (cH < 0)
            {
                cH = 0;
            }

            float cTopBound = cap.transform.position.y + cCenter.y + (cH / 2.0f) + cR;
            float rBotBound = rect.transform.position.y + rectCenter.y - (rHeight / 2.0f);

            if (cTopBound <= rBotBound)
            {
                return(true);
            }

            return(false);
        }
        /// <summary>
        /// Set the page using page index. (y-axis)
        /// </summary>
        /// <param name="page"> Index of the page. </param>
        public void SetPageY(int page)
        {
            int delta = page - (int)this.mCurrentPage.y;

            if (delta == 0)
            {
                return;
            }

            int count = JCS_Mathf.AbsoluteValue(delta);

            for (int countY = 0; countY < count; ++countY)
            {
                if (JCS_Mathf.IsPositive(delta))
                {
                    SwitchScene(JCS_2D4Direction.TOP);
                }
                else
                {
                    SwitchScene(JCS_2D4Direction.BOTTOM);
                }
            }
        }
        /// <summary>
        /// Return Character controller's collider's width and height.
        /// </summary>
        /// <param name="cap"> Character Controller component want to check. </param>
        /// <returns> x : width, y : height </returns>
        public static Vector2 GetColliderWidthHeight(CharacterController cap)
        {
            // holder
            Vector2 capWH = Vector2.zero;

            Vector3 capScale = cap.transform.localScale;

            capScale = JCS_Mathf.AbsoluteValue(capScale);

            float cR = cap.radius * capScale.x;
            float cH = cap.height * capScale.y;

            if (cH < 0)
            {
                cH = 0;
            }

            // apply to holder
            capWH.x = cR * 2;
            capWH.y = cH;

            return(capWH);
        }
        /// <summary>
        /// Set the page using page index. (x-axis)
        /// </summary>
        /// <param name="page"> Index of the page. </param>
        public void SetPageX(int page)
        {
            int delta = page - (int)this.mCurrentPage.x;

            if (delta == 0)
            {
                return;
            }

            int count = JCS_Mathf.AbsoluteValue(delta);

            for (int countX = 0; countX < count; ++countX)
            {
                if (JCS_Mathf.IsPositive(delta))
                {
                    SwitchScene(JCS_2D4Direction.RIGHT);
                }
                else
                {
                    SwitchScene(JCS_2D4Direction.LEFT);
                }
            }
        }
        /// <summary>
        /// Set a collider at the left of the box collider.
        /// </summary>
        /// <param name="rightBox"></param>
        /// <param name="leftBox"></param>
        /// <param name="offset"></param>
        /// <returns></returns>
        public static Vector2 SetOnLeftOfBox(BoxCollider2D rightBox, BoxCollider2D leftBox, float offset = 0)
        {
            // WH stand for Width and Height
            Vector2 rightBoxWH = GetColliderInfo(rightBox);
            Vector2 leftBoxWH  = GetColliderInfo(leftBox);

            Vector3 rightBoxScale = rightBox.transform.localScale;
            Vector3 leftBoxScale  = leftBox.transform.localScale;

            rightBoxScale = JCS_Mathf.AbsoluteValue(rightBoxScale);
            leftBoxScale  = JCS_Mathf.AbsoluteValue(leftBoxScale);

            // 取得Collider的中心"相對位置".
            Vector2 rightBoxCenter = new Vector2(
                rightBox.offset.x * rightBoxScale.x,
                rightBox.offset.y * rightBoxScale.y);

            Vector2 leftBoxCenter = new Vector2(
                leftBox.offset.x * leftBoxScale.x,
                leftBox.offset.y * leftBoxScale.y);

            // * rectCenter 跟 rect.transfrom.position 是"相對位置',
            // 所以要相加才能得到正確的"世界位置"!
            // * cCenter + cap.transform.position 同理.
            Vector2 newPos = new Vector2(
                rightBoxCenter.x + rightBox.transform.position.x,
                rightBoxCenter.y + rightBox.transform.position.y);

            newPos.x = leftBoxCenter.x + leftBox.transform.position.x - (leftBoxWH.x / 2.0f) - (rightBoxWH.x / 2.0f) + offset;

            // 這裡要扣掉原本的中心位置
            rightBox.transform.position = newPos - rightBoxCenter;

            // optional
            return(newPos);
        }
        /// <summary>
        /// Set the box collider ontop of the other box collider
        /// </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 SetOnTopOfBox(BoxCollider topBox, BoxCollider botBox, float offset = 0)
        {
            // WH stand for Width and Height
            Vector2 topBoxWH = GetColliderWidthHeight(topBox);
            Vector2 botBoxWH = GetColliderWidthHeight(botBox);

            Vector3 topBoxScale = topBox.transform.localScale;
            Vector3 botBoxScale = botBox.transform.localScale;

            topBoxScale = JCS_Mathf.AbsoluteValue(topBoxScale);
            botBoxScale = JCS_Mathf.AbsoluteValue(botBoxScale);

            // 取得Collider的中心"相對位置".
            Vector3 topBoxCenter = new Vector3(
                topBox.center.x * topBoxScale.x,
                topBox.center.y * topBoxScale.y,
                topBox.center.z * topBoxScale.z);

            Vector3 botBoxCenter = new Vector3(
                botBox.center.x * botBoxScale.x,
                botBox.center.y * botBoxScale.y,
                botBox.center.z * botBoxScale.z);

            // * rectCenter 跟 rect.transfrom.position 是"相對位置',
            // 所以要相加才能得到正確的"世界位置"!
            // * cCenter + cap.transform.position 同理.
            Vector3 newPos = topBoxCenter + topBox.transform.position;

            newPos.y = botBoxCenter.y + botBox.transform.position.y + (botBoxWH.y / 2.0f) + (topBoxWH.y / 2.0f) + offset;

            // 這裡要扣掉原本的中心位置
            topBox.transform.position = newPos - topBoxCenter;

            // optional
            return(newPos);
        }
        /// <summary>
        /// Returns character controller's infomration.
        /// </summary>
        /// <param name="rect2d"></param>
        /// <returns> width and height </returns>
        public static Vector2 GetColliderInfo(BoxCollider2D rect2d)
        {
            Vector2 widthHeight = Vector2.zero;

            Vector3 rectScale = rect2d.transform.localScale;

            rectScale = JCS_Mathf.AbsoluteValue(rectScale);

            float rWidth  = rect2d.size.x * rectScale.x;
            float rHeight = rect2d.size.y * rectScale.y;

            // apply to holder
            widthHeight.x = rWidth;
            widthHeight.y = rHeight;

#if (UNITY_EDITOR)
            Vector3 right = rect2d.transform.position;
            right.x += widthHeight.x / 2;

            Debug.DrawLine(rect2d.transform.position, right, Color.gray);
#endif

            return(widthHeight);
        }
        /// <summary>
        /// Set a collider at the bottom of the box collider.
        /// </summary>
        /// <param name="botBox"></param>
        /// <param name="topBox"></param>
        /// <param name="offset"></param>
        /// <returns></returns>
        public static Vector2 SetOnBottomOfBox(BoxCollider2D botBox, BoxCollider2D topBox, float offset = 0)
        {
            // WH stand for Width and Height
            Vector2 botBoxWH = GetColliderInfo(botBox);
            Vector2 topBoxWH = GetColliderInfo(topBox);

            Vector3 botBoxScale = botBox.transform.localScale;
            Vector3 topBoxScale = topBox.transform.localScale;

            botBoxScale = JCS_Mathf.AbsoluteValue(botBoxScale);
            topBoxScale = JCS_Mathf.AbsoluteValue(topBoxScale);

            // 取得Collider的中心"相對位置".
            Vector2 botBoxCenter = new Vector2(
                botBox.offset.x * botBoxScale.x,
                botBox.offset.y * botBoxScale.y);

            Vector2 topBoxCenter = new Vector2(
                topBox.offset.x * topBoxScale.x,
                topBox.offset.y * topBoxScale.y);

            // * rectCenter 跟 rect.transfrom.position 是"相對位置',
            // 所以要相加才能得到正確的"世界位置"!
            // * cCenter + cap.transform.position 同理.
            Vector2 newPos = new Vector2(
                botBoxCenter.x + botBox.transform.position.x,
                botBoxCenter.y + botBox.transform.position.y);

            newPos.y = topBoxCenter.y + topBox.transform.position.y - (topBoxWH.y / 2.0f) - (botBoxWH.y / 2.0f) + offset;

            // 這裡要扣掉原本的中心位置
            botBox.transform.position = newPos - botBoxCenter;

            // optional
            return(newPos);
        }
        /// <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>
        /// 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);
        }
Esempio n. 20
0
        /// <summary>
        /// Check weather the "type" in the screen space. (Character Controller)
        /// </summary>
        /// <param name="cap"> character controller to check. (Collider) </param>
        /// <returns>
        /// true: in screen space,
        /// false: not in screen space
        /// </returns>
        public bool CheckInScreenSpace(CharacterController cap)
        {
            // First Step: Find CharacterController's 4 bounds.
            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);

            float cR = cap.radius * capScale.x;
            float cH = (cap.height - (cap.radius * 2.0f)) * capScale.y;

            if (cH < 0)
            {
                cH = 0;
            }

            float cTopBound   = cap.transform.position.y + cCenter.y + (cH / 2.0f) + cR;
            float cBotBound   = cap.transform.position.y + cCenter.y - (cH / 2.0f) - cR;
            float cRightBound = cap.transform.position.x + cCenter.x + cR;
            float cLeftBound  = cap.transform.position.x + cCenter.x - cR;

#if (UNITY_EDITOR)
            Vector3 cOrigin = cap.transform.position + cCenter;
            Debug.DrawLine(cOrigin,
                           new Vector3(cOrigin.x, cTopBound, cOrigin.z));
            Debug.DrawLine(cOrigin,
                           new Vector3(cOrigin.x, cBotBound, cOrigin.z));
            Debug.DrawLine(cOrigin,
                           new Vector3(cRightBound, cOrigin.y, cOrigin.z));
            Debug.DrawLine(cOrigin,
                           new Vector3(cLeftBound, cOrigin.y, cOrigin.z));
#endif

            // Next step: find camera 4 bounds.
            Camera cam = JCS_Camera.main.GetCamera();

            JCS_Canvas jcsCanvas = JCS_Canvas.instance;

            Vector3 camPos = cam.transform.position;
            // only need to know the depth.
            {
                camPos.x = 0;
                camPos.y = 0;
            }
            Vector3 canvasPos = jcsCanvas.transform.position;
            // only need to know the depth.
            {
                canvasPos.x = 0;
                canvasPos.y = 0;
            }
            float camToCanvasDistance = Vector3.Distance(camPos, canvasPos);

            Vector3 gameDepth = new Vector3(0, cap.transform.position.z, 0);
            float   camToGameDepthDistance = Vector3.Distance(camPos, gameDepth);

            //print("To Game depth Distance: " + camToGameDepthDistance);
            //print("To Cavas Distnace: " + camToCanvasDistance);

            Vector2 canvasRect = jcsCanvas.GetAppRect().sizeDelta;
            // transfer rect from screen space to world space
            {
                canvasRect.x *= jcsCanvas.GetAppRect().localScale.x;
                canvasRect.y *= jcsCanvas.GetAppRect().localScale.y;
            }

            Vector3 gameRect = new Vector3(
                camToGameDepthDistance * canvasRect.x / camToCanvasDistance,
                camToGameDepthDistance * canvasRect.y / camToCanvasDistance,
                0);

            // camPos name are named up there.
            // cannot name the same.
            Vector3 cCamPos = cam.transform.position;

            float camTopBound   = cCamPos.y + gameRect.y / 2;
            float camBotBound   = cCamPos.y - gameRect.y / 2;
            float camRightBound = cCamPos.x + gameRect.x / 2;
            float camLeftBound  = cCamPos.x - gameRect.x / 2;

#if (UNITY_EDITOR)
            Vector3 topLeft = cam.transform.position;
            topLeft.x -= gameRect.x / 2;
            topLeft.y += gameRect.y / 2;

            Vector3 topRight = cam.transform.position;
            topRight.x += gameRect.x / 2;
            topRight.y += gameRect.y / 2;

            Vector3 botLeft = cam.transform.position;
            botLeft.x -= gameRect.x / 2;
            botLeft.y -= gameRect.y / 2;

            Vector3 botRight = cam.transform.position;
            botRight.x += gameRect.x / 2;
            botRight.y -= gameRect.y / 2;

            // set depth to the same
            topLeft.z  = mGameDepth;
            topRight.z = mGameDepth;
            botLeft.z  = mGameDepth;
            botRight.z = mGameDepth;

            // Draw the box
            JCS_Debug.DrawRect(topLeft, topRight, botRight, botLeft);
#endif

            if (cRightBound < camLeftBound ||
                camRightBound < cLeftBound ||
                cTopBound < camBotBound ||
                camTopBound < cBotBound)
            {
                // no in the screen
                return(false);
            }

            // in screen
            return(true);
        }
        /// <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);
        }
Esempio n. 22
0
        /// <summary>
        /// Check weather the "type" in the screen space. (Character Controller)
        /// </summary>
        /// <param name="cap"> character controller to check. (Collider) </param>
        /// <returns>
        /// true: in screen space,
        /// false: not in screen space
        /// </returns>
        public bool CheckInScreenSpace(CharacterController cap)
        {
            // First Step: Find CharacterController's 4 bounds.
            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);

            float cR = cap.radius * capScale.x;
            float cH = (cap.height - (cap.radius * JCS_Mathf.D_HALF)) * capScale.y;

            if (cH < 0.0f)
            {
                cH = 0.0f;
            }

            float cTopBound   = cap.transform.position.y + cCenter.y + (cH / JCS_Mathf.D_HALF) + cR;
            float cBotBound   = cap.transform.position.y + cCenter.y - (cH / JCS_Mathf.D_HALF) - cR;
            float cRightBound = cap.transform.position.x + cCenter.x + cR;
            float cLeftBound  = cap.transform.position.x + cCenter.x - cR;

#if (UNITY_EDITOR)
            Vector3 cOrigin = cap.transform.position + cCenter;
            Debug.DrawLine(cOrigin,
                           new Vector3(cOrigin.x, cTopBound, cOrigin.z));
            Debug.DrawLine(cOrigin,
                           new Vector3(cOrigin.x, cBotBound, cOrigin.z));
            Debug.DrawLine(cOrigin,
                           new Vector3(cRightBound, cOrigin.y, cOrigin.z));
            Debug.DrawLine(cOrigin,
                           new Vector3(cLeftBound, cOrigin.y, cOrigin.z));
#endif

            float   depth    = cap.transform.position.z;
            Vector3 gameRect = GameDepthRect(new Vector3(0.0f, depth, 0.0f));
            Camera  cam      = main.GetCamera();

            Vector3 camPos = cam.transform.position;

            float camTopBound   = camPos.y + gameRect.y / JCS_Mathf.D_HALF;
            float camBotBound   = camPos.y - gameRect.y / JCS_Mathf.D_HALF;
            float camRightBound = camPos.x + gameRect.x / JCS_Mathf.D_HALF;
            float camLeftBound  = camPos.x - gameRect.x / JCS_Mathf.D_HALF;

#if (UNITY_EDITOR)
            Vector3 topLeft = cam.transform.position;
            topLeft.x -= gameRect.x / JCS_Mathf.D_HALF;
            topLeft.y += gameRect.y / JCS_Mathf.D_HALF;

            Vector3 topRight = cam.transform.position;
            topRight.x += gameRect.x / JCS_Mathf.D_HALF;
            topRight.y += gameRect.y / JCS_Mathf.D_HALF;

            Vector3 botLeft = cam.transform.position;
            botLeft.x -= gameRect.x / JCS_Mathf.D_HALF;
            botLeft.y -= gameRect.y / JCS_Mathf.D_HALF;

            Vector3 botRight = cam.transform.position;
            botRight.x += gameRect.x / JCS_Mathf.D_HALF;
            botRight.y -= gameRect.y / JCS_Mathf.D_HALF;

            // set depth to the same
            topLeft.z  = depth;
            topRight.z = depth;
            botLeft.z  = depth;
            botRight.z = depth;

            // Draw the box
            JCS_Debug.DrawRect(topLeft, topRight, botRight, botLeft);
#endif

            if (cRightBound < camLeftBound ||
                camRightBound < cLeftBound ||
                cTopBound < camBotBound ||
                camTopBound < cBotBound)
            {
                // no in the screen
                return(false);
            }

            // in screen
            return(true);
        }