4月16日
movement的关键是通过接触的判断来对玩家的不同状态进行判定,比如说,在墙上,不在墙上,在地面上,不在地面上,是否在冲刺,对状态区分的细致程度决定了你游戏的操作手感
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movement : MonoBehaviour
{
private Rigidbody2D rb;
private Animator ani;
private Collision coll;
public float speed = 4;
public float jumpForce = 8;
public float wallJumpLerp = 4;
public float jumpTime = 0;
public int jumpCount = 1;
public float dashSpeed = 20;
public float slideSpeed = 5;
public bool isJump = false;
public bool canMove;
public bool wallGrab;
public bool wallJump;
public bool wallSlide;
public bool isDashing;
private bool groundTouch;
public bool hasDashed;
public int side = 1;
// Start is called before the first frame update
void Start()
{
canMove = true;
rb = GetComponent<Rigidbody2D>();
ani = GetComponent<Animator>();
coll = GetComponent<Collision>();
}
// Update is called once per frame
void Update()
{
}
private void FixedUpdate()
{
float x = Input.GetAxis("Horizontal");
float y = Input.GetAxis("Vertical");
float xRaw = Input.GetAxisRaw("Horizontal");
float yRaw = Input.GetAxisRaw("Vertical");
Vector2 dir = new Vector2(x, y);
Move(dir);
if(rb.velocity.x <= 1f&& rb.velocity.x>=-1f)
{
ani.SetBool("IsRun", false);
}
if (rb.velocity.x > 1 || rb.velocity.x < -1)
{
ani.SetBool("IsRun", true);
}
if (coll.onWall && Input.GetButton("Fire3") && canMove)
//在墙上,按住爬墙键
{
if (side != coll.wallSide)
{
//爬墙动画
}
wallGrab = true;
wallSlide = false;
}
if(Input.GetButtonUp("Fire3") || !coll.onWall || !canMove)
//在墙上,松开爬墙键
{
wallGrab = false;
wallSlide = false;
}
if (coll.onGround && !isDashing)
//在地面上,并且不在冲刺
{
wallJump = false;
GetComponent<BetterJump>().enabled = true;
jumpCount = 1;
}
if(wallGrab && !isDashing)
//在爬墙,并且不在冲刺
{
rb.gravityScale = 0;
if (x > .2f || x < -.2f)
rb.velocity = new Vector2(rb.velocity.x, 0);
float speedModifier = y > 0 ? .5f : 1;
rb.velocity = new Vector2(rb.velocity.x, y * (speed * speedModifier));
}
else
{
rb.gravityScale = 1;
}
if (coll.onWall && !coll.onGround)
//在墙上且没有接触地面
{
if (x != 0 && !wallGrab)
{
wallSlide = true;
WallSlide();
}
}
if (!coll.onWall || coll.onGround)
//在地面上且没有接触墙面
{
wallSlide = false;
jumpCount = 1;
}
if (Input.GetButtonDown("Jump"))
//在地面上则普通跳跃,在墙上则弹墙跳
{
if (coll.onGround)
Jump(Vector2.up);
if (coll.onWall && !coll.onGround)
WallJump();
}
if (Input.GetButtonDown("Fire1") && !hasDashed)
//冲刺
{
if (xRaw != 0 || yRaw != 0)
Dash(xRaw, 0);
}
//接触地面以后回复
if (coll.onGround && !groundTouch)
{
GroundTouch();
groundTouch = true;
}
if (!coll.onGround && groundTouch)
{
groundTouch = false;
}
if (wallGrab || wallSlide || !canMove)
return;
if (x > 0)
{
side = 1;
}
if (x < 0)
{
side = -1;
}
}
private void Move(Vector2 dir)
{
if (!canMove)
return;
if (wallGrab)
return;
if (dir.x > 0)
{
transform.eulerAngles = new Vector3(0, 0, 0);
}
else if (dir.x < 0)
{
transform.eulerAngles = new Vector3(0, 180, 0);
}
if (!wallJump)
{
rb.velocity = (new Vector2(dir.x * speed, rb.velocity.y));
}
else
{
rb.velocity = Vector2.Lerp(rb.velocity, (new Vector2(dir.x * speed, rb.velocity.y)), wallJumpLerp * Time.deltaTime);
}
}
private void Jump(Vector2 dir)
{
isJump = true;
rb.velocity = new Vector2(rb.velocity.x, 0);
rb.velocity += dir * jumpForce;
}
private void WallClimb()
{
rb.velocity = new Vector3(0, 2, 0);
}
private void WallJump()
{
if ((side == 1 && coll.onRightWall) || side == -1 && !coll.onRightWall)
{
side *= -1;
//动画
}
//
StopCoroutine(DisableMovement(0));
StartCoroutine(DisableMovement(.1f));
//
Vector2 wallDir = coll.onRightWall ? Vector2.left : Vector2.right;
Jump((Vector2.up / 1.5f + wallDir / 1.5f));
wallJump = true;
}
private void WallSlide()
{
if (coll.wallSide != side)
{ }
//anim.Flip(side * -1);滑墙动画
if (!canMove)
return;
bool pushingWall = false;
if ((rb.velocity.x > 0 && coll.onRightWall) || (rb.velocity.x < 0 && coll.onLeftWall))
{
pushingWall = true;
}
float push = pushingWall ? 0 : rb.velocity.x;
rb.velocity = new Vector2(push, -slideSpeed);
}
private void Dash(float x, float y)
{
//Camera.main.transform.DOComplete();
//Camera.main.transform.DOShakePosition(.2f, .5f, 14, 90, false, true);
//FindObjectOfType<RippleEffect>().Emit(Camera.main.WorldToViewportPoint(transform.position));
hasDashed = true;
//anim.SetTrigger("dash");
rb.velocity = Vector2.zero;
Vector2 dir = new Vector2(x, y);
rb.velocity += dir.normalized * dashSpeed;
//
StartCoroutine(DashWait());
//
}
void GroundTouch()
{
hasDashed = false;
isDashing = false;
//side = anim.sr.flipX ? -1 : 1;
//jumpParticle.Play();
}
IEnumerator DisableMovement(float time)
{
canMove = false;
yield return new WaitForSeconds(time);
canMove = true;
}
IEnumerator GroundDash()
{
yield return new WaitForSeconds(.15f);
if (coll.onGround)
hasDashed = false;
}
IEnumerator DashWait()
{
//FindObjectOfType<GhostTrail>().ShowGhost();
StartCoroutine(GroundDash());
//DOVirtual.Float(14, 0, .8f, RigidbodyDrag);
//dashParticle.Play();
rb.gravityScale = 0;
GetComponent<BetterJump>().enabled = false;
wallJump = true;
isDashing = true;
yield return new WaitForSeconds(.3f);
//dashParticle.Stop();
rb.gravityScale = 3;
GetComponent<BetterJump>().enabled = true;
wallJump = false;
isDashing = false;
}
int ParticleSide()
{
int particleSide = coll.onRightWall ? 1 : -1;
return particleSide;
}
}