void HandleBetweenPoints(Vector3 moveDirection) { Neighbor n = targetPoint.ReturnNeighbor(previousPoint); if (n != null) { if (IsAdjacentToRefDirection(moveDirection, targetPoint.ReturnNeighbor(previousPoint).direction)) { float tempStartWeight = ikStartWeight; ikStartWeight = ikEndWeight; ikEndWeight = tempStartWeight; targetPoint = previousPoint; } //else if (IsAdjacentToRefDirection(moveDirection, previousPoint.ReturnNeighbor(targetPoint).direction)) //{ // // Do nothing //} //else //{ // return; //} } else { targetPoint = currentPoint; } targetPosition = targetPoint.transform.position + (targetPoint.climbPosition == ClimbPosition.climbing ? climbRootOffset : (hangRootOffset + modelTransform.forward * 0.15f)); climbState = ClimbStates.inTransition; targetState = ClimbStates.onPoint; previousPoint = currentPoint; lockInput = true; anim.SetBool("GP_Move", false); }
IEnumerator WrapUpTransition(float t) { yield return(new WaitForSeconds(t)); climbState = targetState; if (climbState == ClimbStates.onPoint) { currentPoint = targetPoint; transitionHint.text = ""; Neighbor n = currentClimbObjManager.GetNeighborForDirection(Vector3.up, currentPoint); if (n != null) { transitionHint.text += "Press [W] to Climb Up\n"; } n = currentClimbObjManager.GetNeighborForDirection(Vector3.down, currentPoint); if (n != null) { transitionHint.text += "Press [S] to Climb Down\n"; } else { transitionHint.text += downBuffered ? "Press [S] to Drop Down\n" : "Press [S] to Drop Down\n"; // originally "press [S] again" } } initTransit = false; lockInput = false; inputDirection = Vector3.zero; waitForWrapUp = false; // double set here to make sure }
void UpdateConnectionTransitionByType(Neighbor n, Vector3 moveDirection) { Vector3 desiredPosition = Vector3.zero; currentConnectionType = n.cType; Vector3 direction = (targetPoint.transform.position - currentPoint.transform.position).normalized; TransitionType tType; switch (currentConnectionType) { case ConnectionType.inBetween: // mid point float distance = Vector3.Distance(currentPoint.transform.position, targetPoint.transform.position); desiredPosition = currentPoint.transform.position + (direction * (distance / 2)) + (currentPoint.climbPosition == ClimbPosition.climbing ? climbRootOffset : (hangRootOffset + modelTransform.forward * 0.15f)); targetState = ClimbStates.betweenPoints; tType = GetTransitionType(moveDirection, false); PlayAnimation(tType); break; case ConnectionType.leap: desiredPosition = targetPoint.transform.position; targetState = ClimbStates.onPoint; tType = GetTransitionType(moveDirection, true); PlayAnimation(tType, true); break; case ConnectionType.dismount: desiredPosition = targetPoint.transform.position; anim.SetInteger("GP_ClimbType", 20); anim.SetBool("GP_Move", true); break; } if (targetPoint.climbPosition == ClimbPosition.hanging) { ikStartWeight = 1; ikEndWeight = 0; } else { ikStartWeight = 0; ikEndWeight = 1; } targetPosition = desiredPosition; }
void InitClimbing() { if (!initClimb) { initClimb = true; // IK component initiation if (ik != null) { ik.UpdateAllPointsToTarget(targetPoint); ik.UpdateAllTargetPositions(targetPoint); ik.ForceUpdateAllHelpers(); } currentConnectionType = ConnectionType.leap; targetState = ClimbStates.onPoint; } }
void HandleOnPoint(Vector3 moveDirection) { neighbor = currentClimbObjManager.GetNeighborForDirection(moveDirection, currentPoint); if (neighbor != null) { targetPoint = neighbor.target; previousPoint = currentPoint; climbState = ClimbStates.inTransition; UpdateConnectionTransitionByType(neighbor, moveDirection); lockInput = true; } else if (moveDirection == Vector3.down && !downBuffered) { confirmFallOff = true; return; } confirmFallOff = false; }
void HandleMount() { if (!initTransit) { initTransit = true; isRootMovementEnbled = false; ikFollowSideReached = false; ikLandSideReached = false; _time = 0; _startPosition = transform.position; _endPosition = targetPosition + (targetPoint.climbPosition == ClimbPosition.climbing ? climbRootOffset : (hangRootOffset + modelTransform.forward * 0.15f)); // currentCurve = mountCurve; currentCurve.transform.rotation = targetPoint.transform.rotation; BezierPoint[] trailPoints = currentCurve.GetAnchorPoints(); trailPoints[0].transform.position = _startPosition; trailPoints[trailPoints.Length - 1].transform.position = _endPosition; anim.SetFloat("GP_IsHang", targetPoint.climbPosition == ClimbPosition.climbing ? 0 : 1); } if (isRootMovementEnbled) { _time += Time.deltaTime * 2.5f; } // Snap to end to prevent undesirable boundary behavior if (_time >= 0.99f) { _time = 1; isRootMovementEnbled = false; waitToStartClimb = false; lockInput = false; initTransit = false; ikLandSideReached = false; climbState = targetState; transitionHint.text = ""; Neighbor n = currentClimbObjManager.GetNeighborForDirection(Vector3.up, currentPoint); if (n != null) { transitionHint.text += "Press [W] to Climb Up\n"; } n = currentClimbObjManager.GetNeighborForDirection(Vector3.down, currentPoint); if (n != null) { transitionHint.text += "Press [S] to Climb Down\n"; } else { transitionHint.text += "Press [S] to Drop Down\n"; } } //Debug.Log(_time); Vector3 onCurvePosition = currentCurve.GetPointAt(_time); transform.position = onCurvePosition; // IK application weight UpdateAllIKWeight(_time, a_mountCurve); HandleRotation(); }
void LookForClimbSpot() { // TODO: spaghetti code here, need refactoring // (adjustable player center or a game object as player center origin) float maxDistance = 2; Vector3 playerCenter = transform.position + (modelTransform.rotation * new Vector3(0, 0.9f, -0.3f)); Ray ray = new Ray(playerCenter, modelTransform.forward); Debug.DrawLine(playerCenter, playerCenter + (maxDistance * modelTransform.forward), Color.cyan); RaycastHit hitInfo; LayerMask mask = (1 << 8) | (1 << 30); // dummy, set it later to grid manger layer if (Physics.Raycast(ray, out hitInfo, maxDistance, mask)) { //Debug.Log("Find Climbable!"); ClimbObjManager gm = hitInfo.transform.GetComponentInParent <ClimbObjManager>(); if (gm) { Point closestPoint = gm.ReturnClosest(playerCenter); bool faceTowardsPoint = Vector3.Angle(closestPoint.transform.forward, modelTransform.forward) <= 80; bool notInsideWall = Vector3.Angle(closestPoint.transform.forward, ((closestPoint.transform.position + 0.1f * closestPoint.transform.forward) - playerCenter).normalized) < 90; //Debug.DrawRay(playerCenter, closestPoint.transform.forward, Color.red); //Debug.DrawRay(playerCenter, (closestPoint.transform.position - (playerCenter)).normalized, Color.yellow); //Debug.Log("faceTowardsPoint:" + faceTowardsPoint + " | " + "notInsideWall:" + notInsideWall); if (!(notInsideWall && faceTowardsPoint)) { // just for precaution closestPoint = null; return; } // since point is attached to hip position for ik, parant would be the actual point position float distanceToPoint = Vector3.Distance(playerCenter, closestPoint.transform.parent.position); //Debug.Log(distanceToPoint); if (distanceToPoint < 1.8) { // Enter mount animation, revoke user control mc.SetStateOnClimbGrid(); lockInput = true; climbing = true; currentClimbObjManager = gm; targetPoint = closestPoint; targetPosition = closestPoint.transform.position; currentPoint = closestPoint; targetState = ClimbStates.onPoint; // animation params // Can consider different mount initiation in the future //if (mc.grounded) //{ // anim.CrossFade("Ground_Mount", 0.2f); //} //else //{ // anim.CrossFade("Air_Mount", 0.1f); //} // Can also consider preserving pre-mount velocity anim.CrossFade("Mount", 0.1f); anim.SetBool("GP_OnGrid", true); waitToStartClimb = true; } } } }