[Header("移动参数")]
public float speed=8f;
public float crouchSpeedDivisor=3f;
[Header("跳跃参数")]
public float jumpForce=6.3f;
public float jumpHoldForce=1.9f;
public float jumpHoldDuration=0.1f;
public float crouchJumpBoost=2.8f;
public float hangingJumpForce=15f;
float jumpTime;
[Header("状态")]
public bool isOnGround;
public bool isJump;
public bool isCrouch;
public bool isHeadBlocked;
public bool isHanging;
[Header("环境检测")]
public float footOffSet=0.4f;
public float headClearance=0.5f;
public float groundDistance=0.2f;
float PlayerHeight;
public float eyeHeight=1.5f;
public float grabDistance=0.4f;
public float reachOffset=0.7f;
public LayerMask groundLayer;
public float xVelocity;
//按键设置
bool jumpPressed;
bool jumpHeld;
bool crouchHeld;
[SerializeField]bool crouchPressed;
[SerializeField]bool ePressed;
//碰撞体尺寸
Vector2 clStandSize;
Vector2 clStandOffSet;
Vector2 clCrouchSize;
Vector2 clCrouchOffSet;
void Start()
{
rb=GetComponent<Rigidbody2D>();
cl=GetComponent<BoxCollider2D>();
PlayerHeight=cl.size.y;
clStandSize=cl.size;
clStandOffSet=cl.offset;
clCrouchSize=new Vector2(cl.size.x,cl.size.y/2f);
clCrouchOffSet=new Vector2(cl.offset.x,cl.offset.y/2f);
}
void Update()
{
//判断按键响应
if(Input.GetButtonDown("Jump"))
jumpPressed=true;
jumpHeld=Input.GetButton("Jump");
crouchHeld=Input.GetButton("Crouch");
if(Input.GetButtonDown("Crouch"))
crouchPressed=true;
if(Input.GetButtonDown("Save"))
ePressed=true;
}
private void FixedUpdate() {
PhysicsCheck();
GroundMovement();
MidAirMovement();
KeyPressClear();
}
//检测当前角色所处位置
void PhysicsCheck()
{
//左右脚射线检测
RaycastHit2D leftCheck=Raycast(new Vector2(-footOffSet,0.1f),Vector2.down,groundDistance,groundLayer);
RaycastHit2D rightCheck=Raycast(new Vector2(footOffSet,0.1f),Vector2.down,groundDistance,groundLayer);
if(leftCheck||rightCheck)
isOnGround=true;
else
isOnGround=false;
//头顶射线检测
RaycastHit2D headCheck=Raycast(new Vector2(0,cl.size.y),Vector2.up,headClearance,groundLayer);
isHeadBlocked=headCheck;
//悬挂检测
float direction =transform.localScale.x;
Vector2 grabDirection=new Vector2(direction,0f);
RaycastHit2D blockedCheck=Raycast(new Vector2(footOffSet*direction,PlayerHeight),grabDirection,grabDistance,groundLayer);
RaycastHit2D wallCheck=Raycast(new Vector2(footOffSet*direction,eyeHeight),grabDirection,grabDistance,groundLayer);
RaycastHit2D ledgeCheck=Raycast(new Vector2(reachOffset*direction,PlayerHeight),Vector2.down,grabDistance,groundLayer);
if(!isOnGround && rb.velocity.y<0f && ledgeCheck && wallCheck && !blockedCheck)
{
Vector3 pos=transform.position;
pos.x+=(wallCheck.distance-0.05f)*direction;
pos.y-=ledgeCheck.distance;
transform.position=pos;
rb.bodyType=RigidbodyType2D.Static;
isHanging=true;
}
}
//在地面移动
void GroundMovement()
{
if(isHanging)
return;
if(crouchHeld&&!isCrouch&&isOnGround)
{
Crouch();
}
else if(isCrouch&&!crouchHeld&&!isHeadBlocked)
{
StandUp();
}
else if(!isOnGround&&isCrouch)
{
StandUp();
}
xVelocity=Input.GetAxis("Horizontal");
if(isCrouch)
xVelocity/=crouchSpeedDivisor;
rb.velocity=new Vector2(xVelocity*speed,rb.velocity.y);
FilpDirection();
}
void MidAirMovement()
{
//悬挂跳跃或下落
if(isHanging)
{
if(jumpPressed)
{
rb.bodyType=RigidbodyType2D.Dynamic;
rb.velocity=new Vector2(rb.velocity.x,hangingJumpForce);
isHanging=false;
}
if(crouchPressed)
{
rb.bodyType=RigidbodyType2D.Dynamic;
isHanging=false;
}
}
if(jumpPressed&&isOnGround&&!isJump&&!isHeadBlocked)
{
if(isCrouch&&isOnGround)
{
//蹲跳
StandUp();
rb.AddForce(new Vector2(0f,crouchJumpBoost),ForceMode2D.Impulse);
}
//普通跳跃
isOnGround=false;
isJump=true;
jumpTime=Time.time+jumpHoldDuration;
rb.AddForce(new Vector2(0f,jumpForce),ForceMode2D.Impulse);
Debug.Log("1");
AudioManager.PlayJumpAudio();
}
else if(isJump)
{
Debug.Log("2");
if(jumpHeld)
{
rb.AddForce(new Vector2(0f,jumpHoldForce),ForceMode2D.Impulse);
jumpPressed = false;
}
if(jumpTime<Time.time)
isJump=false;
}
}
void FilpDirection()
{
if(xVelocity<0)
transform.localScale=new Vector3(-1,1,1);
if(xVelocity>0)
transform.localScale=new Vector3(1,1,1);
}
//蹲下
void Crouch()
{
isCrouch=true;
cl.size=clCrouchSize;
cl.offset=clCrouchOffSet;
}
//蹲下
void StandUp()
{
isCrouch=false;
cl.size=clStandSize;
cl.offset=clStandOffSet;
}
RaycastHit2D Raycast(Vector2 offSet,Vector2 rayDirection,float length,LayerMask layer)
{
Vector2 pos = transform.position;
RaycastHit2D hit=Physics2D.Raycast(pos+offSet,rayDirection,length,layer);
Color color=hit?Color.red:Color.green;
Debug.DrawRay(pos+offSet,rayDirection*length,color);
return hit;
}
//清空按键
void KeyPressClear()
{
if(jumpPressed)
jumpPressed=false;
if(crouchPressed)
crouchPressed=false;
}
Unity2D[平台跳跃移动代码]
最新推荐文章于 2024-05-19 20:55:03 发布