学习游戏制作记录(各种优化)
1.改进击退方向
Entity脚本:
public int knockbackDir { get; private set; }//击退方向
public virtual void SetupKnocbackDir(Transform _damageDir)//设置击退方向
{
if (_damageDir.position.x > transform.position.x)
knockbackDir = -1;
else if(_damageDir.position.x<transform.position.x)
knockbackDir=1;
}
protected virtual IEnumerator HitKonockback()
{
isKnockback = true;
rb.velocity = new Vector2(KnockbackPower.x * knockbackDir,KnockbackPower.y);//应用
yield return new WaitForSeconds(KnockbackDuration);
isKnockback = false;
}
CharactorState脚本:
public virtual void DoDamage(CharactorState _target)
{
if(TargetCanAvoidAttack(_target))
{
return;
}
_target.GetComponent<Entity>().SetupKnocbackDir(transform);//设置击退方向
int totalDamage =damage.GetValue()+strength.GetValue();
if(CanCrit())
{
totalDamage = CaculateCritDamage(totalDamage);
}
totalDamage =TargetCheckArmor(_target,totalDamage);
_target.TakeDamage(totalDamage);
DoMagicDamage(_target);
}
Clone_skill_control脚本:
private void AttackTrigger()
{
Collider2D[] collider2Ds = Physics2D.OverlapCircleAll(attackCheck.position, attackCheckRadius);
foreach (var hit in collider2Ds)
{
if (hit.GetComponent<Enemy>() != null)
{
//player.state.DoDamage(hit.GetComponent<CharactorState>());
hit.GetComponent<Entity>().SetupKnocbackDir(transform);//设置克隆的击退攻击
PlayerStats playerStats =player.GetComponent<PlayerStats>();
EnemyStats enemyStats =hit.GetComponent<EnemyStats>();
playerStats.CloneDoDamge(enemyStats, attackMultiplier);
if(player.skill.clone.canApplyOnHitEffect)
{
ItemData_Equipment itemData_Equipment = Inventory.instance.GetEquipment(EquipmentType.Weapon);
if (itemData_Equipment != null)
{
itemData_Equipment.Effect(hit.transform);
}
}
if (canDuplicateClone)
{
if(Random.Range(0,100)<chanceToDuplicateClone)
{
SkillManage.instance.clone.CreatClone(hit.transform,new Vector3(.5f*facingDir,0));
}
}
}
}
}
Crystal_Skill_Control脚本:
public void AnimationExplodeEvent()
{
Collider2D[] collider2Ds = Physics2D.OverlapCircleAll(transform.position,cd.radius);
foreach (var hit in collider2Ds)
{
if (hit.GetComponent<Enemy>() != null)
{
hit.GetComponent<Entity>().SetupKnocbackDir(transform);
player.state.DoMagicDamage(hit.GetComponent<CharactorState>());//设置水晶攻击的击退方向
ItemData_Equipment itemAmulet = Inventory.instance.GetEquipment(EquipmentType.Amulet);
if(itemAmulet != null)
{
itemAmulet.Effect(hit.transform);
}
}
}
}
2.改进玩家角色
PlayerWallSlideState脚本:
public override void Update()
{
base.Update();
if (_Player.isWallDetected() == false)//检测是否在墙上,修复bug
_PlayerStateMachine.ChangeState(_Player.airState);
Entity脚本:
public virtual void SetupKnockBackPower(Vector2 _knockbackPower) => KnockbackPower = _knockbackPower;//设置击退的大小
protected virtual void SetZeroKnockBackPower()//用来重写
{
}
protected virtual IEnumerator HitKonockback()
{
isKnockback = true;
rb.velocity = new Vector2(KnockbackPower.x * knockbackDir,KnockbackPower.y);
yield return new WaitForSeconds(KnockbackDuration);
isKnockback = false;
SetZeroKnockBackPower();//每次击退后恢复击退大小为0,仅对玩家
}
Player脚本:
protected override void SetZeroKnockBackPower()//设置为0
{
KnockbackPower = new Vector2(0, 0);
}
PlayerStats脚本:
protected override void DecreaseHealth(int _damage)
{
base.DecreaseHealth(_damage);
if(isDead)
{
return;
}
if(_damage>GetMaxHealth()*.3f)/如果玩家受到极大的伤害
{
player.SetupKnockBackPower(new Vector2(10, 6));//设置击退大小
int randomSound = Random.Range(34, 35);
AudioManager.instance.PlaySFX(randomSound, null);//播放击退音效
}
ItemData_Equipment itemData_Armor = Inventory.instance.GetEquipment(EquipmentType.Armor);
if(itemData_Armor != null)
{
itemData_Armor.Effect(player.transform);
}
}
3.改进骷髅敌人
Enemy脚本:
public float minAttackCooldown;
public float maxAttackCooldown;
SkeletonBattleState脚本:
public override void Enter()
{
base.Enter();
player =PlayerManage.instance.player.transform;
if (player.GetComponent<PlayerStats>().isDead)//确保玩家死后敌人不会再攻击
enemyStateMachine.ChangeState(enemy.moveState);
}
public bool canAttack()
{
if (Time.time >= enemy.lastAttackTime + enemy.attackCooldown)
{
enemy.attackCooldown=Random.Range(enemy.minAttackCooldown,enemy.maxAttackCooldown//设置随机攻击的冷却时间);
enemy.lastAttackTime = Time.time;
return true;
}
else return false;
}
4.实现打开背包游戏暂停的功能
GameManager脚本:
public void Pause(bool _pause)//传入是否暂停
{
if(_pause)
{
Time.timeScale = 0;
}
else
{
Time.timeScale=1;
}
}
UI脚本:
public void SwithTo(GameObject _menu)
{
for(int i=0;i<transform.childCount;i++)
{
bool isfadeScreen =transform.GetChild(i).GetComponent<UI_Fadescreen>()!=null;
if(isfadeScreen==false)
transform.GetChild(i).gameObject.SetActive(false);
}
if(_menu != null)
{
AudioManager.instance.PlaySFX(7, null);
_menu.gameObject.SetActive(true);
}
if(GameManager.instance != null)//如果当前菜单不是游戏内ui则暂停游戏
{
if (_menu == UI_InGame)
GameManager.instance.Pause(false);
else
GameManager.instance.Pause(true);
}
}
Player脚本:
protected override void Update()
{
if (Time.timeScale == 0) return;//如果为0则取消一切接受
5.实现死亡区域
创建一个空对象,装载box碰撞器,设置为触发器
创建DeadZone脚本:
private void OnTriggerEnter2D(Collider2D collision)//进入该区域时死亡
{
if(collision.GetComponent<CharactorState>() != null)
{
collision.GetComponent<CharactorState>().KillEntity();
}
else
Destroy(collision.gameObject);
}
CharactorState脚本:
public void KillEntity()//清除实体
{
if(!isDead)
{
Die();
}
}
EnemyStats脚本:
protected override void Die()
{
base.Die();
enemy.Die();
PlayerManage.instance.currency += soulDrop.GetValue();
myDropSystem.GenerateDrop();
Destroy(gameObject, 5f);//敌人死后销毁实体
}
6.实现冲刺时的无敌状态
CharactorState脚本:
public bool isVincibale { get; private set; }//是否无敌
public void MakeInvicibale(bool _isvicibale)=>isVincibale = _isvicibale;//设置
public virtual void TakeDamage(int _damage)
{
if(isVincibale)//无敌则直接返回
{
return;
}
DecreaseHealth(_damage);
GetComponent<Entity>().DamageImpact();
entityFX.StartCoroutine("FlashFX");
if (currentHealth <= 0&&!isDead)
{
Die();
}
}
PlayerDashState脚本:
public override void Enter()
{
base.Enter();
_Player.skill.dash.CloneOnDash();
stateTimer = _Player.dashDuration;
_Player.state.MakeInvicibale(true);//进入冲刺状态时设置玩家为无敌
}
public override void Exit()
{
base.Exit();
_Player.SetVelocity(0, rb.velocity.y);
_Player.skill.dash.CloneOnArrival();
_Player.state.MakeInvicibale(false);//退出恢复
}