赞
踩
在做人物跳跃功能的时候发现官方的方法在视觉效果上很差,其他一些方案比如加刚体等等都效果不好,于是自己写了一个模拟力作用的跳跃算法。
首先定义了5个全局变量来完成跳跃算法的实现
public float jumpSpeed = 2;//跳跃速度
public float gravity = 2;//模拟重力
public bool isJump = false;//是否在跳跃
public float jumpTime= 0.5f;//跳跃时间
public float jumpTimeFlag = 0;//累计跳跃时间用来判断是否结束跳跃
在Update()方法中实现在按下相应按键的时候改变人物状态
if(Input.GetKey(KeyCode.W)&& Input.GetKeyDown(KeyCode.Space)&& !isJump) { isJump = true; playState = PlayState.Jump; characterController.Move(transform.forward * speed*Time.deltaTime); } else if (Input.GetKey(KeyCode.W)) { isMoving = true; playState = PlayState.Moving; characterController.Move(transform.forward * speed * Time.deltaTime); } else if (Input.GetKeyDown(KeyCode.Space)&&!isJump) { isJump = true; playState = PlayState.Jump; }else { playState = PlayState.Idle; isMoving = false; }
** 如果在跳跃状态,并且当前时间没有到达跳跃时间,则持续向上移动如果到达跳跃时间,那么持续下降直到遇到地面**
if (isJump) { if (jumpTimeFlag<jumpTime) { characterController.Move(transform.up * jumpSpeed*Time.deltaTime); jumpTimeFlag += Time.deltaTime; }else if(jumpTime < jumpTimeFlag) { characterController.Move(transform.up * -gravity * Time.deltaTime); } if(characterController.collisionFlags == CollisionFlags.Below) { jumpTimeFlag = 0; isJump = false; } }
在不是跳跃状态的时候使人物始终接触地面
else
{
if (characterController.collisionFlags != CollisionFlags.Below)
characterController.Move(transform.up * -gravity * Time.deltaTime);
}
附完整代码
using System.Collections; using System.Collections.Generic; using UnityEngine; public enum PlayState { Moving, Idle, Jump } public class PlayerMove : MonoBehaviour { //private PlayerDir dir; private CharacterController characterController; public float speed = 3; public float jumpSpeed = 2;//跳跃速度 public float gravity = 2;//模拟重力 public PlayState playState = PlayState.Idle; public bool isMoving = false; public bool isJump = false;//是否在跳跃 public float jumpTime= 0.5f;//跳跃时间 public float jumpTimeFlag = 0;//累计跳跃时间用来判断是否结束跳跃 private void Start() { //dir = this.GetComponent<PlayerDir>(); characterController = this.GetComponent<CharacterController>(); } // Update is called once per frame void Update() { //float distance = Vector3.Distance(dir.GetTargetPosition(),this.transform.position); if(Input.GetKey(KeyCode.W)&& Input.GetKeyDown(KeyCode.Space)&& !isJump) { isJump = true; playState = PlayState.Jump; characterController.Move(transform.forward * speed*Time.deltaTime); } else if (Input.GetKey(KeyCode.W)) { isMoving = true; playState = PlayState.Moving; characterController.Move(transform.forward * speed * Time.deltaTime); } else if (Input.GetKeyDown(KeyCode.Space)&&!isJump) { isJump = true; playState = PlayState.Jump; }else { playState = PlayState.Idle; isMoving = false; } if (isJump) { if (jumpTimeFlag<jumpTime) { characterController.Move(transform.up * jumpSpeed*Time.deltaTime); jumpTimeFlag += Time.deltaTime; }else if(jumpTime < jumpTimeFlag) { characterController.Move(transform.up * -gravity * Time.deltaTime); } if(characterController.collisionFlags == CollisionFlags.Below) { jumpTimeFlag = 0; isJump = false; } } else { if (characterController.collisionFlags != CollisionFlags.Below) characterController.Move(transform.up * -gravity * Time.deltaTime); } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。