/// <summary> /// jumping 和 falling 状态判断,以及他们的攀爬点检测 /// </summary> public void Jumping() { //掉落 if (rigid.velocity.y < 0 && currentSort != Climbingsort.Falling) { currentSort = Climbingsort.Falling; oldRotation = transform.rotation; } if (rigid.velocity.y > 0 && currentSort != Climbingsort.Jumping) { currentSort = Climbingsort.Jumping; } //跳起的时候检测点往上移一点点,预测 if (currentSort == Climbingsort.Jumping) { CheckForSpots(HandTrans.position + fallHandOffset, -transform.up, 0.1f, CheckingSort.nomal); } //下落的时候,检测的点往下移一点点. if (currentSort == Climbingsort.Falling) { CheckForSpots(HandTrans.position + fallHandOffset + transform.rotation * new Vector3(0.02f, -0.6f, 0), -transform.up, 0.4f, CheckingSort.nomal); transform.rotation = oldRotation; } }
public void MoveTowardsPoint() { transform.position = Vector3.Lerp(transform.position, (TargetPoint - transform.rotation * HandTrans.localPosition), Time.deltaTime * ClimbForce); Quaternion lookRotation = Quaternion.LookRotation(-TargetNormal); transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * ClimbForce); animator.SetBool("OnGround", false); float distance = Vector2.Distance(transform.position, (TargetPoint - transform.rotation * HandTrans.localPosition)); float percent = -9 * (BeginDistance - distance) / BeginDistance; animator.SetFloat("Jump", percent); if (distance <= 0.01f && currentSort == Climbingsort.ClimbingTowardsPoint) { transform.position = TargetPoint - transform.rotation * HandTrans.localPosition; transform.rotation = lookRotation; lastTime = Time.time; currentSort = Climbingsort.Climbing; } if (distance <= 0.25f && currentSort == Climbingsort.ClimbingTowardsPlateau) { transform.position = TargetPoint - transform.rotation * HandTrans.localPosition; transform.rotation = lookRotation; lastTime = Time.time; currentSort = Climbingsort.Walking; rigid.isKinematic = false; TPUC.enabled = true; } }
public void UpdateStats() { //若没在走路状态,然后又落在地上,并且不是爬墙状态.那么变走路状态,并启动移动按钮 if (currentSort != Climbingsort.Walking && TPC.m_IsGrounded && currentSort != Climbingsort.ClimbingTowardsPoint) { currentSort = Climbingsort.Walking; TPUC.enabled = true; rigid.isKinematic = false; } //走路状态但是不在地上,那么改变为跳跃状态 if (currentSort == Climbingsort.Walking && !TPC.m_IsGrounded) { currentSort = Climbingsort.Jumping; } //走路状态并且只要在移动(包括惯性),那么开始检查面前是否有墙可爬 if (currentSort == Climbingsort.Walking && (Input.GetAxis("Vertical") != 0 || Input.GetAxis("Horizontal") != 0)) { CheckForClimbStart(); } if (!TPC.m_IsGrounded && (currentSort == Climbingsort.Climbing || currentSort == Climbingsort.ClimbingTowardPlateau || currentSort == Climbingsort.ClimbingTowardsPoint)) { animator.SetBool("Climbing", true); } else { animator.SetBool("Climbing", false); animator.SetBool("ClimbUp", false); animator.SetBool("ClimbDown", false); rigid.isKinematic = false; } }
private void Update() { if (TPC.m_IsGrounded) { return; } if (currentSort == Climbingsort.None) { Jumping(); } else { Climb(); } if (nextClimbPoint.CanGoToPoint) { Debug.Log("nextClimbPoint.point = " + nextClimbPoint.point); //Debug.Log("CanGoToPoint"); if (currentSort == Climbingsort.None) { TPUC.enabled = false; currentSort = Climbingsort.Climbing; } MoveTowardsPoint(); } }
/// <summary> /// 爬向寻找好的spot /// </summary> public void MoveTowardsPoint() { float distance = Vector3.Distance(transform.position, (TargetPoint - transform.rotation * HandTrans.localPosition)); if (distance < 0.5f || b_HorizontalMove || currentSort == Climbingsort.ClimbingTowardPlateau) { Debug.Log("MoveTowardsPoint::进入阈值了,直接吸附到指定点"); //爬动 transform.position = Vector3.Lerp(transform.position, (TargetPoint - transform.rotation * HandTrans.localPosition), Time.deltaTime * ClimbForce); rigid.isKinematic = true; } //面朝向点法线相反的方向(因为可能是斜坡.) Quaternion lookrotation = Quaternion.LookRotation(-TargetNormal); transform.rotation = Quaternion.Slerp(transform.rotation, lookrotation, Time.deltaTime * ClimbForce); animator.SetBool("OnGround", false); //跳跃动画程度控制 float percent = -9 * (BeginDistance - distance) / BeginDistance; //Debug.Log("percent = " + percent); animator.SetFloat("Jump", percent); //阈值.爬到了 if (distance <= 0.1f && currentSort == Climbingsort.ClimbingTowardsPoint) { Debug.Log("MoveTowardsPoint::结束阈值,爬向点"); b_HorizontalMove = false; transform.position = TargetPoint - transform.rotation * HandTrans.localPosition; transform.rotation = lookrotation; lasttime = Time.time; currentSort = Climbingsort.Climbing; } //往上爬平台.快到的时候,就直接切换为Walking if (distance <= 0.25f && currentSort == Climbingsort.ClimbingTowardPlateau) { Debug.Log("MoveTowardsPoint::结束阈值,爬向平台"); transform.position = TargetPoint - transform.rotation * HandTrans.localPosition; transform.rotation = lookrotation; lasttime = Time.time; currentSort = Climbingsort.Walking; rigid.isKinematic = false; rigid.useGravity = true; TPUC.enabled = true; } }
public void CheckForClimbStart() { RaycastHit hit2; Vector3 dir = transform.forward - transform.up / 0.8f; if (!Physics.Raycast(transform.position + transform.rotation * RayCastPosition, dir, 1.6f) && !Input.GetButton("Jump")) { currentSort = Climbingsort.checkingForClimbStart; if (Physics.Raycast(transform.position + new Vector3(0, 1.1f, 0), -transform.up, out hit2, 1.6f, SpotLayer)) { FindSpot(hit2, CheckingSort.falling); } } }
public void UpdateStats() { if (currentSort != Climbingsort.Walking && TPC.m_IsGrounded && currentSort != Climbingsort.ClimbingTowardsPoint) { currentSort = Climbingsort.Walking; TPUC.enabled = true; rigid.isKinematic = false; } if (currentSort == Climbingsort.Walking && !TPC.m_IsGrounded) { currentSort = Climbingsort.Jumping; } if (currentSort == Climbingsort.Walking && (Input.GetAxis("Vertical") != 0 || Input.GetAxis("Horizontal") != 0)) { CheckForClimbStart(); } }
//检查是否可以爬墙,查找可以爬的点 public void CheckForClimbStart() { RaycastHit hit2; //爬墙射线检测方向.从身上发射到前下方 Vector3 dir = transform.forward - transform.up / 0.8f; //Debug.DrawRay(transform.position + transform.rotation * raycastPosition, dir, Color.yellow); //Debug.Log("CheckForClimbStart"); //Debug.LogError("CheckForClimbStart"); if (!Physics.Raycast(transform.position + transform.rotation * raycastPosition, dir, 1.6f) && !Input.GetButton("Jump")) { currentSort = Climbingsort.checkingForClimbStart; //从玩家身上往下发射射线寻找点.因为是从跳跃开始,在落下过程中寻找攀爬点.所以是从人身体胸部左右位置往下发射射线 //Debug.DrawRay(transform.position + new Vector3(0, 1.1f, 0), -transform.up, Color.yellow); //Debug.LogError("寻找攀爬点"); if (Physics.Raycast(transform.position + new Vector3(0, 1.1f, 0), -transform.up, out hit2, 1.6f, SpotLayer)) { FindSpot(hit2, CheckingSort.falling); } } }
/// <summary> /// 查找墙边点 改变状态 /// </summary> /// <param name="h">所使用检测到的射线</param> /// <param name="sort">当前的状态</param> #region public void FindSpot(RaycastHit h, CheckingSort sort) { //若是该攀爬点跟世界的角度过大(过于倾斜),则不能抓 if (Vector3.Angle(h.normal, Vector3.up) < MaxAngle) { RayInfo ray = new RayInfo(); if (sort == CheckingSort.nomal) { ray = GetClosetPoint(h.transform, h.point + new Vector3(0, -0.01f, 0), transform.forward / 2.5f); } else if (sort == CheckingSort.turning) { ray = GetClosetPoint(h.transform, h.point + new Vector3(0, -0.01f, 0), transform.forward / 2.5f - transform.right * Input.GetAxis("Horizontal")); } else if (sort == CheckingSort.falling) { ray = GetClosetPoint(h.transform, h.point + new Vector3(0, -0.01f, 0), -transform.forward / 2.5f); } TargetPoint = ray.point; TargetNormal = ray.nomal; //如果该点能攀爬 if (ray.CanGoToPoint) { //若不是攀爬状态,并且不是爬动状态 if (currentSort != Climbingsort.Climbing && currentSort != Climbingsort.ClimbingTowardsPoint) { //爬向最近的spot.爬动时人物控制取消,刚体取消,不在地上 Debug.Log("FindSpot::找到要爬的点了 TargetPoint = " + TargetPoint); rigid.isKinematic = true; TPUC.enabled = false; TPC.m_IsGrounded = false; } currentSort = Climbingsort.ClimbingTowardsPoint; BeginDistance = Vector3.Distance(transform.position, (TargetPoint - transform.rotation * HandTrans.localPosition)); } } }
public void CheckForPlateau() { RaycastHit hit2; Vector3 dir = transform.up + transform.forward / 2; if (!Physics.Raycast(HandTrans.position + transform.rotation * VerticalHandOffset, dir, out hit2, 1.5f, SpotLayer)) { currentSort = Climbingsort.ClimbingTowardsPlateau; if (Physics.Raycast(HandTrans.position + dir * 1.5f, -Vector3.up, out hit2, 1.7f, SpotLayer)) { TargetPoint = HandTrans.position + dir * 1.5f; } else { TargetPoint = HandTrans.position + dir * 1.5f - transform.rotation * new Vector3(0, -0.2f, 0.25f); } TargetNormal = -transform.forward; animator.SetBool("Crouch", true); animator.SetBool("OnGround", true); } }
/// <summary> /// 检测是否可站立的平台 /// </summary> public void CheckForPlateau() { //Debug.Log("CheckForPlateau"); RaycastHit hit2; Vector3 dir = transform.up + transform.forward / 4; //Debug.LogError("CheckForPlateau11111"); //上前方没有障碍物了,说明上面是平台顶端 if (!Physics.Raycast(HandTrans.position + transform.rotation * VerticalHandOffset, dir, out hit2, 1.5f, SpotLayer)) { currentSort = Climbingsort.ClimbingTowardPlateau; animator.SetBool("ClimbUp", true); //Debug.LogError("CheckForPlateau"); //上方 if (Physics.Raycast(HandTrans.position + dir * 1.5f, -Vector3.up, out hit2, 1.7f, SpotLayer)) { Debug.Log("这里有墙可以踩"); //TargetPoint = HandTrans.position + dir * 1.5f; //TargetPoint - transform.rotation * HandTrans.localPosition TargetPoint = hit2.point + transform.rotation * HandTrans.localPosition + transform.up * 0.5f; } else { //这里没墙了,应该是抓到了树枝边上,准备跳吧 TargetPoint = HandTrans.position + dir * 1.5f + transform.rotation * new Vector3(0, -0.2f, 0.25f); } TargetNormal = -transform.forward; //Debug.DrawRay(HandTrans.position + dir * 1.5f, -Vector3.up*1.7f, Color.yellow); //Debug.Log("TargetPoint = " + TargetPoint); //Debug.LogError("CheckForPlateau"); animator.SetBool("Crouch", true); animator.SetBool("OnGround", true); } }
public void FindSpot(RaycastHit h, CheckingSort sort) { if (Vector3.Angle(h.normal, Vector3.up) < MaxAngle) { RayInfo ray = new RayInfo(); if (sort == CheckingSort.normal) { ray = GetClosestPoint(h.transform, h.point + new Vector3(0, -0.01f, 0), transform.forward / 2.5f); } else if (sort == CheckingSort.turning) { ray = GetClosestPoint(h.transform, h.point + new Vector3(0, -0.01f, 0), transform.forward / 2.5f - transform.right * Input.GetAxis("Horizontal")); } else if (sort == CheckingSort.falling) { ray = GetClosestPoint(h.transform, h.point + new Vector3(0, -0.01f, 0), -transform.forward / 2.5f); } TargetPoint = ray.point; TargetNormal = ray.normal; if (ray.CanGoToPoint) { if (currentSort != Climbingsort.Climbing && currentSort != Climbingsort.ClimbingTowardsPoint) { TPUC.enabled = false; rigid.isKinematic = true; TPC.m_IsGrounded = false; } currentSort = Climbingsort.ClimbingTowardsPoint; BeginDistance = Vector3.Distance(transform.position, (TargetPoint - transform.rotation * HandTrans.localPosition)); } } }
public void Jumping() { if (rigid.velocity.y < 0 && currentSort != Climbingsort.Falling) { currentSort = Climbingsort.Falling; oldRotation = transform.rotation; } if (rigid.velocity.y > 0 && currentSort != Climbingsort.Jumping) { currentSort = Climbingsort.Jumping; } if (currentSort == Climbingsort.Jumping) { CheckForSpots(HandTrans.position + FallHandOffset, -transform.up, 0.1f, CheckingSort.normal); } if (currentSort == Climbingsort.Falling) { CheckForSpots(HandTrans.position + FallHandOffset + transform.rotation * new Vector3(0.02f, -0.6f, 0), -transform.up, 0.4f, CheckingSort.normal); transform.rotation = oldRotation; } }
/// <summary> /// 爬动方法.进行下一次爬动的预先计算 /// </summary> public void Climb() { if (Time.time - lasttime > CoolDown && currentSort == Climbingsort.Climbing) { //上下爬动检测 if (Input.GetAxis("Vertical") > 0) { //Debug.LogError(12); CheckForSpots(HandTrans.position + transform.rotation * VerticalHandOffset + transform.up * ClimbRange * 0.5f, -transform.up, ClimbRange * 0.5f, CheckingSort.nomal); //当没有检测到上面有障碍物,就爬平台 if (currentSort != Climbingsort.ClimbingTowardsPoint) { CheckForPlateau(); } } if (Input.GetAxis("Vertical") < 0) { CheckForSpots(HandTrans.position - transform.rotation * (VerticalHandOffset + new Vector3(0, 0.3f, 0)), -transform.up, ClimbRange, CheckingSort.nomal); if (currentSort != Climbingsort.ClimbingTowardsPoint) { rigid.isKinematic = false; TPUC.enabled = true; currentSort = Climbingsort.Falling; oldRotation = transform.rotation; animator.SetBool("ClimbDown", true); } } //左右爬动检测 if (Input.GetAxis("Horizontal") != 0) { CheckForSpots(HandTrans.position + transform.rotation * HorizontalHandOffset, transform.right * Input.GetAxis("Horizontal") - transform.up / 3.5f, ClimbRange / 2, CheckingSort.nomal); if (currentSort != Climbingsort.ClimbingTowardsPoint) { CheckForSpots(HandTrans.position + transform.rotation * HorizontalHandOffset, transform.right * Input.GetAxis("Horizontal") - transform.up / 1.5f, ClimbRange / 3, CheckingSort.nomal); } if (currentSort != Climbingsort.ClimbingTowardsPoint) { CheckForSpots(HandTrans.position + transform.rotation * HorizontalHandOffset, transform.right * Input.GetAxis("Horizontal") - transform.up / 6f, ClimbRange / 1.5f, CheckingSort.nomal); } if (currentSort != Climbingsort.ClimbingTowardsPoint) { int hor = 0; if (Input.GetAxis("Horizontal") < 0) { hor = -1; } if (Input.GetAxis("Horizontal") > 0) { hor = 1; } CheckForSpots(HandTrans.position + transform.rotation * HorizontalHandOffset + transform.right * hor * SmallestEdge / 4, transform.forward - transform.up * 2, ClimbRange / 3f, CheckingSort.turning); if (currentSort != Climbingsort.ClimbingTowardsPoint) { CheckForSpots(HandTrans.position + transform.rotation * HorizontalHandOffset + transform.right * 0.2f, transform.forward - transform.up * 2 + transform.right * hor / 1.5f, ClimbRange / 3, CheckingSort.turning); } } } } }
public void Climb() { if (Time.time - lastTime > CoolDown && currentSort == Climbingsort.Climbing) { if (Input.GetAxis("Vertical") > 0) { CheckForSpots(HandTrans.position + transform.rotation * VerticalHandOffset + transform.up * ClimbRange, -transform.up, ClimbRange, CheckingSort.normal); if (currentSort != Climbingsort.ClimbingTowardsPoint) { CheckForPlateau(); } } if (Input.GetAxis("Vertical") < 0) { CheckForSpots(HandTrans.position - transform.rotation * (VerticalHandOffset + new Vector3(0, 0.3f, 0)), -transform.up, ClimbRange, CheckingSort.normal); if (currentSort != Climbingsort.ClimbingTowardsPoint) { rigid.isKinematic = false; TPUC.enabled = true; currentSort = Climbingsort.Falling; oldRotation = transform.rotation; } } if (Input.GetAxis("Horizontal") != 0) { CheckForSpots(HandTrans.position + transform.rotation * HorizontalHandOffset, transform.right * Input.GetAxis("Horizontal") - transform.up / 3.5f, ClimbRange / 2, CheckingSort.normal); if (currentSort != Climbingsort.ClimbingTowardsPoint) { CheckForSpots(HandTrans.position + transform.rotation * HorizontalHandOffset, transform.right * Input.GetAxis("Horizontal") - transform.up / 1.5f, ClimbRange / 3, CheckingSort.normal); } if (currentSort != Climbingsort.ClimbingTowardsPoint) { CheckForSpots(HandTrans.position + transform.rotation * HorizontalHandOffset, transform.right * Input.GetAxis("Horizontal") - transform.up / 6, ClimbRange / 1.5f, CheckingSort.normal); } if (currentSort != Climbingsort.ClimbingTowardsPoint) { int hor = 0; if (Input.GetAxis("Horizontal") < 0) { hor = -1; } if (Input.GetAxis("Horizontal") > 0) { hor = 1; } CheckForSpots(HandTrans.position + transform.rotation * HorizontalHandOffset + transform.right * hor * SmallesEdge / 4, transform.forward - transform.up * 2, ClimbRange / 3, CheckingSort.turning); if (currentSort != Climbingsort.ClimbingTowardsPoint) { CheckForSpots(HandTrans.position + transform.rotation * HorizontalHandOffset + transform.right * 0.2f, transform.forward - transform.up * 2 + transform.right * hor / 1.5f, ClimbRange / 3, CheckingSort.turning); } } } } }