Unity3D学习 ② 物体的正常跳跃、二段跳、冲刺
1.物体正常跳跃与二段跳
1.1 物体正常跳跃
限制物体在按下跳跃键的时候只能跳跃一次。而不是能够无限跳跃。
具体实现思路是:给地面设置标签,检测物体是否和地面碰撞。
1.1.1 地面(plane)标签设置
我们为了物体能够正常跳跃,需要给地面添加一个标签。
点击地面plane 再点击 tag 下面的AddTag选项
在AddTag页面点击➕号,创建Ground标签
创建完成后,在plane上标签中选中为Ground
1.1.2 物体跳跃代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move : MonoBehaviour
{
public float moveSpeed = 5f;
public float rotateSpeed = 5f;
public float jumpSpeed = 8f;
// 判断是否在地面上
private bool isGround = true;
Vector3 moveAmount;
Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
Vector3 moveDir = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")).normalized;
moveAmount = moveDir * moveSpeed * Time.deltaTime;
Vector3 targetDir = Vector3.Slerp(transform.forward, moveDir, rotateSpeed * Time.deltaTime);
transform.rotation = Quaternion.LookRotation(targetDir);
if (Input.GetButtonDown("Jump"))
{
//如果物体在地面上
if (isGround)
{
//瞬移效果
//transform.Translate(Vector3.up * Time.deltaTime * jumpSpeed);
// 实现跳跃效果
rb.AddForce(Vector3.up * jumpSpeed);
// 此时物体不在地面上
isGround = false;
}
}
}
private void FixedUpdate()
{
rb.MovePosition(rb.position + moveAmount);
}
// 碰撞检测
private void OnCollisionEnter(Collision collision)
{
// 物体碰触到地面
if(collision.gameObject.tag == "Ground")
{
// 物体在地面上
isGround = true;
}
}
}
1.2 物体二段跳
二段跳的实现:新增两个变量,一个控制物体能否进行二段跳,一个监测物体是否在进行跳跃
物体进行二段跳的条件:当物体不在地面上&&物体能进行二段跳&&物体正在一段跳。
物体二段跳代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move : MonoBehaviour
{
// 移动速度
public float moveSpeed = 5f;
// 旋转速度
public float rotateSpeed = 5f;
// 跳跃速度
public float jumpSpeed = 8f;
// 是否在地上
private bool isGround = true;
// 物体是否能进行二段跳,因为设置为可操控,所以为public
public bool isDoubleJump = false;
// 物体是否在一段跳
private bool isJump = true;
Vector3 moveAmount;
Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
Vector3 moveDir = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")).normalized;
moveAmount = moveDir * moveSpeed * Time.deltaTime;
Vector3 targetDir = Vector3.Slerp(transform.forward, moveDir, rotateSpeed * Time.deltaTime);
transform.rotation = Quaternion.LookRotation(targetDir);
if (Input.GetButtonDown("Jump"))
{
if (isGround)
{
//瞬移效果
//transform.Translate(Vector3.up * Time.deltaTime * jumpSpeed);
rb.AddForce(Vector3.up * jumpSpeed);
// 物体正在一段跳
isJump = true;
// 物体不在地面上
isGround = false;
}
// 如果物体能进行二段跳&&物体不在地面上&&物体在跳跃
else if (isDoubleJump&&!isGround&&isJump)
{
// 再进行一次跳跃操作
rb.AddForce(Vector3.up * jumpSpeed);
// 物体不再一段跳
isJump = false;
}
}
}
private void FixedUpdate()
{
rb.MovePosition(rb.position + moveAmount);
}
private void OnCollisionEnter(Collision collision)
{
if(collision.gameObject.tag == "Ground")
{
isGround = true;
}
}
}
此处记得打勾,物体才能进行二段跳。
2.物体的冲刺
设置sprintSpeed 将按下冲刺键时候的物体速度更改为sprintSpeed即可。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move : MonoBehaviour
{
public float moveSpeed = 5f;
public float rotateSpeed = 5f;
public float jumpSpeed = 8f;
public float sprintSpeed = 10f;
private bool isGround = true;
public bool isDoubleJump = false;
private bool isJump = true;
Vector3 moveAmount;
Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
Vector3 moveDir = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")).normalized;
moveAmount = moveDir * moveSpeed * Time.deltaTime;
Vector3 targetDir = Vector3.Slerp(transform.forward, moveDir, rotateSpeed * Time.deltaTime);
transform.rotation = Quaternion.LookRotation(targetDir);
if (Input.GetButtonDown("Jump"))
{
if (isGround)
{
//瞬移效果
//transform.Translate(Vector3.up * Time.deltaTime * jumpSpeed);
rb.AddForce(Vector3.up * jumpSpeed);
isJump = true;
isGround = false;
}
else if (isDoubleJump&&!isGround&&isJump)
{
rb.AddForce(Vector3.up * jumpSpeed);
isJump = false;
}
}
// 按住左shift键实现冲刺效果
if (Input.GetKey(KeyCode.LeftShift))
{
moveAmount = moveDir * sprintSpeed * Time.deltaTime;
}
}
private void FixedUpdate()
{
rb.MovePosition(rb.position + moveAmount);
}
private void OnCollisionEnter(Collision collision)
{
if(collision.gameObject.tag == "Ground")
{
isGround = true;
}
}
}