Introduction
原理:
角色位置改变时,每隔一段时间记录角色的位置,然后在记录的位置上放置一个图片,在图片出现之后过一段时间就让图片渐渐消失
简述实现步骤:
1.在Unity中Create Empty(空物体),在其下面放置角色的图片
2.写代码
3.测试,修复Bug
最终效果:
Dash and SpeedUp
PlayerDash.cs(脚本挂在player上面)
变量声明
[Header("Player")]
private SpriteRenderer playerSr;
private Rigidbody2D rb;
private Vector2 movement = Vector2.zero;
public float spriteRate = 0.02f;
[Header("UpgradeSpeed")]
public float upSpeed = 5f;
public float upSpeedTime = 5f;
public float spriteUpSpeedRate = 0.25f;
private bool isUpSpeeding = false;
private GameObject[] spritePoolSpeedUp;
private float upCounter = 0;
[Header("Dash")]
public float dashTime = 0.1f;
public float dashSpeed = 20f;
public float dashRate = 2f;
private Vector2 dir= Vector2.zero;
private bool isDashing = false;
private float dashRateCounter = 0f;
private GameObject[] spritePoolDash;
private float couter = 0f;
Awake()
private void Awake()
{
rb = GetComponent<Rigidbody2D>();
playerSr = GetComponent<SpriteRenderer>();
//找到Hierarchy面板中放置Dash图片的空物体
Transform dashPool = GameObject.Find("SpritePoolDash").transform;
spritePoolDash = new GameObject[dashPool.childCount];
for (int i = 0; i < spritePoolDash.Length; i++)
{
spritePoolDash[i] = dashPool.GetChild(i).gameObject;
}
//找到Hierarchy面板中放置SpeedUp图片的空物体
Transform speedUpPool = GameObject.Find("SpritePoolSpeedUp").transform;
spritePoolSpeedUp = new GameObject[speedUpPool.childCount];
for (int i = 0; i < spritePoolSpeedUp.Length; i++)
{
spritePoolSpeedUp[i] = speedUpPool.GetChild(i).gameObject;
}
}
Update()
private void Update()
{
movement.x = Input.GetAxisRaw("Horizontal");
movement.y = Input.GetAxisRaw("Vertical");
//如果冷却时间 > 0,开始冷却倒计时
if (dashRateCounter > 0)
{
dashRateCounter -= Time.deltaTime;
}
//按下空格键,并且角色正在移动,Dash
if (Input.GetKeyDown(KeyCode.Space) && movement != Vector2.zero)
{
//如果正在Dash 或 SpeedUp 或 Dash技能的冷却时间 > 0,则不执行Dash方法
if (isDashing || isUpSpeeding || dashRateCounter > 0)
return;
dir = movement.normalized * 5;
StartCoroutine(Dash());
}
//按下“B”键,SpeedUp
if (Input.GetKeyDown(KeyCode.B))
{
if (isDashing || isUpSpeeding)
return;
StartCoroutine(UpGradeSpeed());
}
}
Dash部分
private IEnumerator Dash()
{
//重置冷却计时器
dashRateCounter = dashRate;
//图片出现时间间隔
spriteRate = 0.02f;
//
StartCoroutine(DashSprites());
couter = 0;
//记录player当前的状态,正在冲刺,不可以进行其他技能的操作
isDashing = true;
while (couter <= dashTime)
{
couter += Time.deltaTime;
//角色朝着按键方向Dash
rb.position = Vector2.MoveTowards(rb.position, rb.position + dir, dashSpeed * Time.deltaTime);
if (couter > dashTime)
{
isDashing = false;
}
yield return null;
}
}
//放置图片
private IEnumerator DashSprites()
{
for (int i = 0; i < spritePool.Length; i++)
{
//将图片设为可见
spritePool[i].SetActive(true);
//重置图片的颜色(其实是重置其透明度,重置alpha为255)
spritePool[i].GetComponent<SpriteRenderer>().color = Color.white;
//设置图片的朝向,与角色图片的朝向一致
spritePool[i].GetComponent<SpriteRenderer>().flipX = playerSr.flipX;
//在角色当前的位置上放置一张图片
spritePool[i].transform.position = transform.position;
//相隔0.02秒放置一张
yield return new WaitForSeconds(spriteRate);
}
}
SpeedUp部分
private IEnumerator UpGradeSpeed()
{
//修改图片出现的时间间隔
spriteRate = 0.25f;
isUpSpeeding = true;
StartCoroutine(UpSpeedSprites());
//设置一个计时器
upCounter = upSpeedTime;
while (upCounter >= 0f)
{
//计时器>=0就让其倒计时
upCounter -= Time.deltaTime;
rb.position = Vector2.MoveTowards(rb.position, rb.position + movement, upSpeed * Time.deltaTime);
//SpeedUp结束
if (upCounter <= 0)
{
isUpSpeeding = false;
}
yield return null;
}
}
private IEnumerator UpSpeedSprites()
{
for (int i = 0; i < spritePoolUpSpeed.Length; i++)
{
spritePoolUpSpeed[i].SetActive(true);
spritePoolUpSpeed[i].GetComponent<SpriteRenderer>().color = Color.white;
spritePoolUpSpeed[i].GetComponent<SpriteRenderer>().flipX = playerSr.flipX;
spritePoolUpSpeed[i].transform.position = transform.position;
yield return new WaitForSeconds(spriteRate);
}
}
SpriteFade.cs(脚本挂在以下物体上面)
using System.Collections;
using UnityEngine;
public class SpriteFade : MonoBehaviour
{
//图片从 不透明 到 透明 的速率
public float spriteFadeTime = 0.01f;
//获取脚本所挂在的物体的图片的SpriteRenderer,用来改变其颜色
private SpriteRenderer sr;
private void Awake()
{
sr = GetComponent<SpriteRenderer>();
}
private void Update()
{
//如果图片在Hierarchy面板上面显示(表示触发了Dash技能,图片出现了)
if (gameObject.activeInHierarchy)
{
StartCoroutine(FadeSprite());
}
}
private IEnumerator FadeSprite()
{
while (gameObject.activeInHierarchy)
{
//渐渐消失
sr.color = Color.Lerp(sr.color, Color.clear, spriteFadeTime * Time.deltaTime);
//消失之后,将图片隐藏
if(sr.color == Color.clear)
{
gameObject.SetActive(false);
}
//每帧执行
yield return null;
}
}
}