using UnityEngine;
using UnityEngine.AI;
public class SpaceJump : MonoBehaviour
{
public float distance = 5f;
public float hight = 8f;
public float useTime = 1.5f;
public KeyCode JumpKeyCode = KeyCode.Space;
public bool isJumping = false;//是否在跳跃中
public bool isContinueJump = true;//是否允许连跳
public int jumpCountMax = 5;//最高允许连跳几次
public int currJumpCount = 0;//当前连跳次数
Vector3 addForce;
private Rigidbody rigidbody;
private NavMeshAgent agent;
void Awake()
{
rigidbody = GetComponent<Rigidbody>();
agent = GetComponent<NavMeshAgent>();
}
void FixedUpdate()
{
if (Input.GetKeyDown(JumpKeyCode)) Jump();
if (isJumping && rigidbody && rigidbody.velocity.y == 0) JumpOver();// 落地
}
/// <summary>
/// 跳跃结束
/// </summary>
public void JumpOver()
{
isJumping = false;
if (rigidbody)
{
currJumpCount = 0;
addForce = Vector3.zero;
rigidbody.velocity = Vector3.zero;
}
}
void iTweenJump()
{
Vector3 p2;//角色落点
Vector3 p1;//最高点
Vector3 dir = GetToMouseDir();//方向是跳向鼠标,transform.forward是跳向前方
p1 = transform.position + dir * (distance / 2) + transform.up * hight;//第二个点:起始位置前方几米处上方几米的坐标.
p2 = transform.position + dir * distance;
//找到碰撞器 落脚点
RaycastHit raycastHit; //碰撞体信息
if (Physics.Raycast(p2, Vector3.down, out raycastHit, 81f))
{
p2 = raycastHit.point;
}
Vector3[] paths = new Vector3[3];
paths[0] = transform.position;
paths[1] = p1;
paths[2] = p2;
iTween.MoveTo(gameObject, iTween.Hash("path", paths, "movetopath", true, "time", useTime, "oncomplete", "JumpOver"));//movetopath=false按点移动,=true按照点构成的曲线路径移动
}
/// <summary>
///角色坐标 到 鼠标位置的方向
/// </summary>
Vector3 GetToMouseDir()
{
Vector3 dir = Vector3.forward;
//从射相机的近裁剪面 开始并穿过 屏幕中鼠标像素坐标 的射线,从摄像机通过一个屏幕点的射线
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit = new RaycastHit();
if (Physics.Raycast(ray, out hit))
{
Vector3 hitPos = hit.point;
Vector3 playerPos = transform.position;
//向量减法 和y无关,所以同步一下高度
playerPos.y = hitPos.y;
//向量减法,得到一个向量,包含方向和距离
dir = (hitPos - playerPos);
//归一化 去除距离 ,只要方向,如果不去除距离 ,那么角色闪到鼠标点击的位置
dir = dir.normalized;
}
return dir;
}
void RigidbodyJump()
{
if (isJumping)
{
if (isContinueJump)
{
if (currJumpCount >= jumpCountMax)
{
return;
}
}
else
{
return;
}
}
currJumpCount += 1;
//打开刚体移动
rigidbody.constraints = RigidbodyConstraints.None;
rigidbody.constraints = RigidbodyConstraints.FreezeRotation;
//角色当前刚体速度
float xSpeed = 0;
float zSpeed = 0;
if (agent == null || agent.enabled == false)
{
xSpeed = rigidbody.velocity.x;
zSpeed = rigidbody.velocity.z;
}
else
{
xSpeed = agent.velocity.x;
zSpeed = agent.velocity.z;
agent.enabled = false;
}
Vector3 add;
if (xSpeed == 0 && zSpeed == 0)
{//站立状态:向上眺
add = transform.up * hight;
rigidbody.velocity += add;
}
else
{//移动状态:向鼠标方向跳
Vector3 dir = GetToMouseDir();
add = dir * distance + transform.up * hight;
if (addForce == Vector3.zero)
{//判断是第一次跳跃,就跳固定值高度
rigidbody.velocity = add;
}
else
{
rigidbody.velocity += add;
}
}
addForce += add;
//Debug.LogError("Rigidbody" + GetComponent<Rigidbody>().velocity+"zSpeed:" + zSpeed+ "xSpeed:"+ xSpeed+"dir:" + dir+"add" + add+"rigidbody.velocity = " +rigidbody.velocity + "force" + addForce);
rigidbody.AddForce(addForce);
// 设置 角色状态 动画 等为跳跃
}
public void Jump()
{
if (rigidbody)
{
RigidbodyJump();
}
else
{
iTweenJump();
}
isJumping = true;
}
}