(一)使用混合树优化跳跃动画
使用15个跳跃的序列帧来制作混合树,每一帧对应一个速度,且在更新动画状态机值的时候对速度值进行更新。
、
(二)受伤状态
当玩家触碰毒水和攻击时,会受伤。
1.水面脚本 使用触发器实现
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class water : MonoBehaviour
{
Damage damage;
/* private void start()
{
damage = transform.GetComponent<Damage>();
}*/
private void Awake()
{
damage = transform.GetComponent<Damage>();
}//调用类最好在awake中,因为在start中DAMAGE类可能未被实例化,
private void OnCollisionEnter2D(Collision2D collision)
{
//对游戏物体造成伤害
damage.onDamage(collision.gameObject);
//血量减少
}
}
注意点:
Awake在脚本被实例化的时候就会被调用(不管脚本是不是enable的),而且在脚本的生命周期中只会被调用一次。Awake是在所有对象实例化之后,所以我们可以放心大胆地去使用诸如GmeObject.Fine之类的方法来在Awake中给各个组件之间添加引用 关系。Awake会在所有对象的Start之前调用,但是注意不同对象之间的Awake顺序是不得而知的。
Start是在对象被第一次enable之后,在Update之前调用的,Start在脚本的生命周期中也只可能被调用一次。Start可能不会被立刻调用,比如我们之前没有让其enable,当脚本被enable时,Start才会被调用。
官方文档的建议是:尽量在Awake函数中进行初始化操作,除非有A依赖B,B必须在A实例化之前完成初始化,那么A在Start,B放在Awake中可以保证A在B之后才被初始化(不过个人感觉还是应该尽量都在Awake中进行对象间的引用,然后手动调用Init函数进行初始化,这样可以自己控制初始化的顺序)。
相关概念
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DamageAble : MonoBehaviour
{
public int health; //生命值
public Action OnHurt;
public Action OnDead;
public bool isEnable = true;
//控制当前是否能受伤
public void Enable()
{
isEnable = true;
}
public void DisEnable()
{
isEnable = false;
}
public void TakeDamage(int damage)
{
if(isEnable == false) { return; }
//血量减少
Debug.Log("SDA1" + health);
health--;
if (health == 0)
{
if(OnDead!=null)
OnDead();
}
else
{
Debug.Log("SDA" + health);
if(OnHurt!=null)
OnHurt();
}
}
// Update is called once per frame
void Update()
{
}
}
3.伤害脚本 用来控制伤害一个物体或者多个物体
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Damage : MonoBehaviour
{
public int damage;//伤害
//对一个游戏物体造成伤害
public void onDamage(GameObject gameObject)
{
//是否能够受伤
DamageAble dam = gameObject.GetComponent<DamageAble>();
if (dam == null)
{
return;
}
dam.TakeDamage(this.damage);
}
//对多个游戏物体造成伤害
public void onDamage(GameObject[] gameObject)
{
for(int i = 0; i < gameObject.Length; i++)
{
onDamage(gameObject[i]);
}
}
// Update is called once per frame
void Update()
{
}
}
4.在PlayController的awake方法完成死亡和受伤事件的注册并实现受伤和死亡的方法,在start方法中完成血量的初始化
private Awake(){
playerdam = GetComponent<DamageAble>();
playerdam.OnDead += this.onDead;//注册死亡事件
playerdam.OnHurt += this.onHurt;//注册受伤事件
}
private void Start()
{
GamePanel._instance.InitHp(playerdam.health);
}
#region 受伤相关方法
public void onHurt()
{
anim.SetTrigger("isHurt");//播放受伤动画
anim.SetBool ("isWuDi", true);
GamePanel._instance.UpdateHp(playerdam.health);
playerdam.DisEnable();
Invoke("ResetDamageable", 1);
}
public void ResetDamageable()
{
anim.SetBool("isWuDi", false);
playerdam.Enable();
}
public void onDead()
{
}
public void onAttack()
{
}
#endregion
5.游戏中的面板脚本:这里用来做血量的更新
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GamePanel : SingletonView<GamePanel>
{
public GameObject hp_item_prefb;
Transform hp_parent;
GameObject[] hp_table;
protected override void Awake()
{
base.Awake();
hp_parent = transform.Find("Hp");
}
public void InitHp(int count)
{
hp_table = new GameObject[count];
for (int i = 0; i < count; i++)
{
hp_table[i] = GameObject.Instantiate(hp_item_prefb, hp_parent);//hp item 血量的预制体初始化
}
}
public void UpdateHp(int count) //更新
{
for (int i = count; i <hp_table.Length; i++)
{
if (hp_table[i].GetComponent<Toggle>().isOn)
{
hp_table[i].GetComponent<Toggle>().isOn = false;
}
//显示特效
}
}
}