学习游戏制作记录(存档点和丢失货币的保存以及敌人的货币掉落)8.27
1.实现存档点
创建存档对象,有激活和非激活的动画
创建Checkpoint脚本:
private Animator anim;
public string id;//存档点的id
public bool activeStatus;//是否激活
private void Awake()
{
anim = GetComponent<Animator>();
}
[ContextMenu("Generate id")]
private void GenerateID()//用来生成随机id
{
id=System.Guid.NewGuid().ToString();
}
private void OnTriggerEnter2D(Collider2D collision)//触发器
{
ActiveCheckPoints();//玩家靠近时激活
}
public void ActiveCheckPoints()//激活函数
{
activeStatus=true;
anim.SetBool("active", true);//设置激活动画
}
GameManager脚本:
[SerializeField] public Checkpoint[] checkpoints;//获取所有存档点
[SerializeField] public string closetcheckpointID;//最近存档点的id
public void Awake()
{
if (instance != null)
{
Destroy(instance.gameObject);
}
else
{
instance = this;
}
checkpoints = FindObjectsOfType<Checkpoint>();
}
public void RestartScence()
{
SaveManager.instance.SaveData();//重新加载场景时保存数据
Scene scene =SceneManager.GetActiveScene();
SceneManager.LoadScene(scene.name);
}
public void LoadDate(GameData gameData)
{
foreach (KeyValuePair<string, bool> pair in gameData.checkpoints)
{
foreach (Checkpoint checkpoint in checkpoints)
{
if (checkpoint.id == pair.Key && pair.Value == true)
{
checkpoint.ActiveCheckPoints();//加载已激活的存档点
}
}
}
closetcheckpointID = gameData.closetCheckpointID;//获取最近id
Invoke("PlacePlayerAtclosetCheckpoint", .1f);//延迟引用
}
private void PlacePlayerAtclosetCheckpoint()
{
foreach (Checkpoint checkpoint in checkpoints)
{
if (closetcheckpointID == checkpoint.id)
{
PlayerManage.instance.player.transform.position = checkpoint.transform.position;//找到最近存档点更换位置
}
}
}
public void SaveDate(ref GameData gameData)
{
gameData.closetCheckpointID = FindClosetCheckPoint().id;
gameData.checkpoints.Clear();
foreach (Checkpoint checkpoint in checkpoints)
{
gameData.checkpoints.Add(checkpoint.id, checkpoint.activeStatus);
}
}
public Checkpoint FindClosetCheckPoint()//找到最近的存档点
{
float closetDistance=Mathf.Infinity;
Checkpoint closetcheckpoint = null;
foreach(var checkpoint in checkpoints)
{
float distanceToCheckpoint=Vector2.Distance(PlayerManage.instance.player.transform.position,checkpoint.transform.position);
if(distanceToCheckpoint<closetDistance&&checkpoint.activeStatus==true)
{
closetDistance = distanceToCheckpoint;
closetcheckpoint = checkpoint;
}
}
return closetcheckpoint;
}
GameData脚本:
public SerializbleDictionary<string, bool> checkpoints;//所有存档点
public string closetCheckpointID;//最近的id
2.实现货币随时间推移而增加
UI_InGame脚本:
[SerializeField] private float soulAmounts;
[SerializeField] private float increseRate = 100;
private void UpdataSoulUI()//在Updata()中调用
{
if (soulAmounts <= PlayerManage.instance.GetCurrentCurrency())
soulAmounts += Time.deltaTime * increseRate;//缓慢增长
else
soulAmounts = PlayerManage.instance.GetCurrentCurrency();
CurrencySlots.text = ((int)soulAmounts).ToString();
}
3.实现敌人货币的掉落
EnemyStats脚本:
public State soulDrop;//掉落灵魂的数量
protected override void Start()
{
soulDrop.SetDefaultValue(100);//设置基础值
ApplyLevelModifier();
base.Start();
enemy = GetComponent<Enemy>();
myDropSystem = GetComponent<ItemDrop>();
}
Modify(soulDrop);//ApplyLevelModifier()中调用,应用等级修改器
protected override void Die()
{
base.Die();
enemy.Die();
myDropSystem.GenerateDrop();
PlayerManage.instance.currency += soulDrop.GetValue();//玩家的灵魂数量提高
}
4.实现玩家死亡时货币的掉落
创建一个玩家死亡的预制体,添加触发器
创建LostCurrencyControl脚本挂载在预制体上:
public int currency;//尸体对应的灵魂数量
private void OnTriggerEnter2D(Collider2D collision)
{
if(collision.GetComponent<Player>() != null)
{
PlayerManage.instance.currency += currency;//被捡起来
Destroy(gameObject);
}
}
GameData脚本:
public float lostcurrencyX;//位置
public float lostcurrencyY;
public int lostcurrencyAmount;//数量
GameManager脚本:
[Header("Lost currency")]
[SerializeField] GameObject lostcurrencyPrefab;//尸体的预制体
public int lostcurrencyAmount;
[SerializeField] private float lostcurrenctX;
[SerializeField] protected float lostcurrenctY;
public void LoadDate(GameData gameData)=>StartCoroutine(LoadWithDelay(gameData));
private void LoadLostcurrency(GameData gameData)//加载尸体的位置和数量
{
lostcurrencyAmount = gameData.lostcurrencyAmount;
lostcurrenctX = gameData.lostcurrencyX;
lostcurrenctY = gameData.lostcurrencyY;
if(lostcurrencyAmount>0)//如果玩家有灵魂,则创建预制体
{
GameObject newlostcurrency = Instantiate(lostcurrencyPrefab, new Vector3(lostcurrenctX, lostcurrenctY), Quaternion.identity);
newlostcurrency.GetComponent<LostCurrencyControl>().currency=lostcurrencyAmount;//设置数量
}
lostcurrencyAmount = 0;//如果连续死亡两次则清空灵魂数量
}
private IEnumerator LoadWithDelay(GameData gameData)
{
yield return new WaitForSeconds(.1f);//统一延迟启用
LoadCheckpoints(gameData);//提取的方法
LoadClosetCheckPoint(gameData);
LoadLostcurrency(gameData);
}
public void SaveDate(ref GameData gameData)
{
gameData.lostcurrencyAmount = lostcurrencyAmount;//加载数量
gameData.lostcurrencyX=player.position.x;
gameData.lostcurrencyY=player.position.y;
if(FindClosetCheckPoint()!=null)
gameData.closetCheckpointID = FindClosetCheckPoint().id;
gameData.checkpoints.Clear();
foreach (Checkpoint checkpoint in checkpoints)
{
gameData.checkpoints.Add(checkpoint.id, checkpoint.activeStatus);
}
}
PlayerStats脚本:
protected override void Die()
{
base.Die();
player.Die();
GameManager.instance.lostcurrencyAmount = PlayerManage.instance.GetCurrentCurrency();//掉落所有灵魂
PlayerManage.instance.currency = 0;
GetComponent<PlayerItemDrop>().GenerateDrop();
}