/// <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); }
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); }
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)); }
/// <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); }
/// <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); }
/// <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); }