最终效果
前言
今天使用对象池实现一个简单的冲锋残影效果
对象池
新增ObjectPool对象池脚本
using System.Collections.Generic;
using UnityEngine;
public class ObjectPool
{
// /**
// * 我们希望不同的物体可以被分开存储,在这种情况下使用字典是最合适的
// * 所以声明一个字典objectPool作为对象池主体,以字符串类型的物体的名字作为key
// * 使用队列存储物体来作为value,这里使用队列只是因为入队和出队的操作较为方便,也可以换成其他集合方式
// * 然后实例化这个字典以备后续使用
// * /
private static Dictionary<string, Queue<GameObject>> objectPools = new Dictionary<string, Queue<GameObject>>(); // 对象池字典
private static GameObject pool; // 为了不让窗口杂乱,声明一个对象池父物体,作为所有生成物体的父物体
public static GameObject GetObject(GameObject prefab)
{
if (pool == null) pool = new GameObject("ObjectPool"); // 如果对象池父物体不存在,则创建一个新的对象池父物体
GameObject childPool = GameObject.Find(prefab.name + "Pool"); // 查找该对象的子对象池
if (!childPool)
{
childPool = new GameObject(prefab.name + "Pool"); // 如果该对象的子对象池不存在,则创建一个新的子对象池
childPool.transform.SetParent(pool.transform); // 将该子对象池加入对象池父物体中
}
GameObject _object = null;
if (objectPools.ContainsKey(prefab.name) && objectPools[prefab.name].Count > 0)
{
//从对象池中取出一个对象实例
_object = objectPools[prefab.name].Dequeue();
}
if(_object == null){
// 如果对象池中没有这种类型的对象,实例化一个新对象
_object = GameObject.Instantiate(prefab);
PushObject(_object); // 将新对象放回对象池
}
_object.SetActive(true); // 激活对象
_object.transform.SetParent(childPool.transform); // 将新的对象加入该对象的子对象池中
return _object;
}
public static void PushObject(GameObject prefab) // 将对象加入对象池中
{
//获取对象的名称,因为实例化的物体名都会加上"(Clone)"的后缀,需要先去掉这个后缀才能使用名称查找
string _name = prefab.name.Replace("(Clone)", string.Empty);
if (!objectPools.ContainsKey(_name))
objectPools.Add(_name, new Queue<GameObject>()); // 如果对象池中没有该对象,则创建一个新的对象池
objectPools[_name].Enqueue(prefab); // 将对象加入对象池中
prefab.SetActive(false); // 将对象禁用
}
}
冲锋残影
新增冲锋残影预制体控制脚本
public class Shadow : MonoBehaviour
{
private Transform player;//玩家角色
private SpriteRenderer thisSprite;//残影图片
private SpriteRenderer playerSprite;//角色图片
// private float alpha;
public float fadeDuration = 1.0f; // 残影淡出的持续时间,单位秒
public Color color;//残影颜色
private float startTime;
private void OnEnable()
{
player = GameObject.FindGameObjectWithTag("Player").transform;
thisSprite = GetComponent<SpriteRenderer>();
playerSprite = player.GetComponent<SpriteRenderer>();
startTime = Time.time;
color.a = 1;
// alpha = 1;
//设置残影图片为角色当前的图片
thisSprite.sprite = playerSprite.sprite;
//设置残影的位置为角色当前的位置
transform.position = player.position;
//设置残影的翻转为角色当前的翻转
transform.localScale = player.localScale;
}
void FixedUpdate()
{
float elapsed = Time.time - startTime;
float fadeAmount = 1.0f - Mathf.Clamp01(elapsed / fadeDuration); // 计算淡出的透明度
// Color color = new Color(0.5f, 0.5f, 1, alpha);
color.a = fadeAmount; // 设置新的透明度
thisSprite.color = color;
if (fadeAmount <= 0.0f)
{
//返回对象池
ObjectPool.PushObject(gameObject);
}
}
}
配置人物冲锋残影预制体
角色再发起冲锋时调用
public override void FixedUpdate()
{
SetVelocity(parameter.dashPostion.x * parameter.facingDirection, parameter.dashPostion.y);
//生成影子
ObjectPool.GetObject(parameter.shadowPrefab);
}
//设置速度
public void SetVelocity(float setVelocityX, float setVelocityY){
parameter.rb.velocity = new Vector2(setVelocityX, setVelocityY);
}
效果
完结
赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注
,以便我第一时间收到反馈,你的每一次支持
都是我不断创作的最大动力。当然如果你发现了文章中存在错误
或者有更好的解决方法
,也欢迎评论私信告诉我哦!
好了,我是向宇
,https://xiangyu.blog.csdn.net
一位在小公司默默奋斗的开发者,出于兴趣爱好,最近开始自学unity,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!php是工作,unity是生活!如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~