【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili

- using System.Collections;
- using System.Collections.Generic;
- using TMPro;
- using UnityEngine;
-
- public class Blackhole_Skill_Controller : MonoBehaviour
- {
- [SerializeField] private GameObject hotKeyPrefab;
- [SerializeField] private List
KeyCodeList; -
- private float maxSize;//最大尺寸
- private float growSpeed;//变大速度
- private float shrinkSpeed;//缩小速度
- private float blackholeTimer;
-
- private bool canGrow = true;//是否可以变大
- private bool canShrink;//缩小
- private bool canCreateHotKeys = true;专门控制后面进入的没法生成热键
- private bool cloneAttackReleased;
-
-
- private int amountOfAttacks = 4;
- private float cloneAttackCooldown = .3f;
- private float cloneAttackTimer;
-
- private List
targets = new List(); - private List
createdHotKey = new List(); -
- public bool playerCanExitState { get; private set; }
-
-
- public void SetupBlackhole(float _maxSize,float _growSpeed,float _shrinkSpeed,int _amountOfAttacks,float _cloneAttackCooldown,float _blackholeDuration)
- {
- maxSize = _maxSize;
- growSpeed = _growSpeed;
- shrinkSpeed = _shrinkSpeed;
- amountOfAttacks = _amountOfAttacks;
- cloneAttackCooldown = _cloneAttackCooldown;
- blackholeTimer = _blackholeDuration;
- }
-
- private void Update()
- {
- blackholeTimer -= Time.deltaTime;
- cloneAttackTimer -= Time.deltaTime;
-
- if(blackholeTimer <= 0)
- {
- blackholeTimer = Mathf.Infinity;//防止重复检测
- if (targets.Count > 0)//只有有target才释放攻击
- {
- ReleaseCloneAttack();//释放攻击
- }
- else
-
- FinishBlackholeAbility();//缩小黑洞
- }
-
- if (Input.GetKeyDown(KeyCode.R)&& targets.Count > 0)
- {
- ReleaseCloneAttack();
- }
-
- CloneAttackLogic();
-
- if (canGrow && !canShrink)
- {
- //这是控制物体大小的参数
- transform.localScale = Vector2.Lerp(transform.localScale, new Vector2(maxSize, maxSize), growSpeed * Time.deltaTime);
- //类似MoveToward,不过是放大到多少大小 https://docs.unity3d.com/cn/current/ScriptReference/Vector2.Lerp.html
- }
- if (canShrink)
- {
- transform.localScale = Vector2.Lerp(transform.localScale, new Vector2(0, 0), shrinkSpeed * Time.deltaTime);
-
- if (transform.localScale.x <= 1f)
- {
- Destroy(gameObject);
- }
- }
- }
-
- private void ReleaseCloneAttack()
- {
- cloneAttackReleased = true;
- canCreateHotKeys = false;
-
- DestroyHotKeys();
- PlayerManager.instance.player.MakeTransprent(true);
- }
-
- private void CloneAttackLogic()
- {
- if (cloneAttackTimer < 0 && cloneAttackReleased&&amountOfAttacks>0)
- {
- cloneAttackTimer = cloneAttackCooldown;
-
- int randomIndex = Random.Range(0, targets.Count);
-
-
- //限制攻击次数和设置攻击偏移量
- float _offset;
-
- if (Random.Range(0, 100) > 50)
- _offset = 1.5f;
- else
- _offset = -1.5f;
-
- SkillManager.instance.clone.CreateClone(targets[randomIndex], new Vector3(_offset, 0, 0));
- amountOfAttacks--;
-
-
- if (amountOfAttacks <= 0)
- {
- Invoke("FinishBlackholeAbility", 0.5f);
- }
- }
- }
-
- private void FinishBlackholeAbility()
- {
- DestroyHotKeys();
- canShrink = true;
- cloneAttackReleased = false;
- playerCanExitState = true;
-
- }
-
- private void OnTriggerEnter2D(Collider2D collision)
- {
- if(collision.GetComponent
()!=null) - {
- collision.GetComponent
().FreezeTime(true); - CreateHotKey(collision);
- }
- }
- private void OnTriggerExit2D(Collider2D collision)
- {
- if (collision.GetComponent
() != null) - {
- collision.GetComponent
().FreezeTime(false); -
- }
- }
-
- private void CreateHotKey(Collider2D collision)
- {
- if(KeyCodeList.Count == 0)//当所有的KeyCode都被去除,就不在创建实例
- {
- return;
- }
-
- if(!canCreateHotKeys)//这是当角色已经开大了,不在创建实例
- {
- return;
- }
-
- //创建实例
- GameObject newHotKey = Instantiate(hotKeyPrefab, collision.transform.position + new Vector3(0, 2), Quaternion.identity);
-
- //将实例添加进列表
- createdHotKey.Add(newHotKey);
-
-
- //随机KeyCode传给HotKey,并且传过去一个毁掉一个
- KeyCode choosenKey = KeyCodeList[Random.Range(0, KeyCodeList.Count)];
-
- KeyCodeList.Remove(choosenKey);
-
- Blackhole_Hotkey_Controller newHotKeyScript = newHotKey.GetComponent
(); -
- newHotKeyScript.SetupHotKey(choosenKey, collision.transform, this);
- }
- public void AddEnemyToList(Transform _myEnemy)
- {
- targets.Add(_myEnemy);
- }
-
- //销毁Hotkey
- private void DestroyHotKeys()
- {
-
- if(createdHotKey.Count <= 0)
- {
- return;
- }
- for (int i = 0; i < createdHotKey.Count; i++)
- {
- Destroy(createdHotKey[i]);
- }
-
- }
-
- }
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class Blackhole_Skill : Skill
- {
-
- [SerializeField]private float maxSize;//最大尺寸
- [SerializeField] private float growSpeed;//变大速度
- [SerializeField] private float shrinkSpeed;//缩小速度
-
- [SerializeField] private GameObject blackholePrefab;
- [Space]
-
- [SerializeField] private float blackholeDuration;
- [SerializeField] int amountOfAttacks = 4;
- [SerializeField] float cloneAttackCooldown = .3f;
-
-
-
-
-
-
- Blackhole_Skill_Controller currentBlackhole;
-
- public override bool CanUseSkill()
- {
- return base.CanUseSkill();
- }
-
- public override void UseSkill()
- {
- base.UseSkill();
-
- GameObject newBlackhole = Instantiate(blackholePrefab,player.transform.position,Quaternion.identity);
-
- currentBlackhole = newBlackhole.GetComponent
(); -
- currentBlackhole.SetupBlackhole(maxSize,growSpeed,shrinkSpeed,amountOfAttacks,cloneAttackCooldown,blackholeDuration);
- }
-
- protected override void Start()
- {
- base.Start();
- }
-
- protected override void Update()
- {
- base.Update();
- }
-
- public bool SkillCompleted()
- {
- if(currentBlackhole == null)
- return false;
- if (currentBlackhole.playerCanExitState)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- }
- using System.Collections;
- using System.Collections.Generic;
- using Unity.VisualScripting;
- using UnityEngine;
-
- public class Player : Entity
- {
- [Header("Attack Details")]
- public Vector2[] attackMovement;//每个攻击时获得的速度组
- public float counterAttackDuration = .2f;
-
-
-
- public bool isBusy{ get; private set; }//防止在攻击间隔中进入move
- //
- [Header("Move Info")]
- public float moveSpeed;//定义速度,与xInput相乘控制速度的大小
- public float jumpForce;
- public float swordReturnImpact;//在player里设置swordReturnImpact作为击退的参数
-
- [Header("Dash Info")]
- [SerializeField] private float dashCooldown;
- private float dashUsageTimer;//为dash设置冷却时间,在一定时间内不能连续使用
- public float dashSpeed;//冲刺速度
- public float dashDuration;//持续时间
- public float dashDir { get; private set; }
-
-
-
-
- #region 定义States
- public PlayerStateMachine stateMachine { get; private set; }
- public PlayerIdleState idleState { get; private set; }
- public PlayerMoveState moveState { get; private set; }
- public PlayerJumpState jumpState { get; private set; }
- public PlayerAirState airState { get; private set; }
- public PlayerDashState dashState { get; private set; }
- public PlayerWallSlideState wallSlide { get; private set; }
- public PlayerWallJumpState wallJump { get; private set; }
-
-
-
- public PlayerPrimaryAttackState primaryAttack { get; private set; }
- public PlayerCounterAttackState counterAttack { get; private set; }
-
- public PlayerAimSwordState aimSword { get; private set; }
- public PlayerCatchSwordState catchSword { get; private set; }
-
- public PlayerBlackholeState blackhole { get; private set; }
-
-
- public SkillManager skill { get; private set; }
- public GameObject sword{ get; private set; }//声明sword
-
-
- #endregion
- protected override void Awake()
- {
-
- base.Awake();
- stateMachine = new PlayerStateMachine();
- //通过构造函数,在构造时传递信息
- idleState = new PlayerIdleState(this, stateMachine, "Idle");
- moveState = new PlayerMoveState(this, stateMachine, "Move");
- jumpState = new PlayerJumpState(this, stateMachine, "Jump");
- airState = new PlayerAirState(this, stateMachine, "Jump");
- dashState = new PlayerDashState(this, stateMachine, "Dash");
- wallSlide = new PlayerWallSlideState(this, stateMachine, "WallSlide");
- wallJump = new PlayerWallJumpState(this, stateMachine, "Jump");//wallJump也是Jump动画
-
-
- primaryAttack = new PlayerPrimaryAttackState(this, stateMachine, "Attack");
- counterAttack = new PlayerCounterAttackState(this, stateMachine, "CounterAttack");
-
- aimSword = new PlayerAimSwordState(this,stateMachine, "AimSword");
- catchSword = new PlayerCatchSwordState(this, stateMachine, "CatchSword");
- blackhole = new PlayerBlackholeState(this, stateMachine, "Jump");
-
- //this 就是 Player这个类本身
- }//Awake初始化所以State,为所有State传入各自独有的参数,及animBool,以判断是否调用此动画(与animatoin配合完成)
- protected override void Start()
- {
- base.Start();
- stateMachine.Initialize(idleState);
- skill = SkillManager.instance;
-
- }
-
- protected override void Update()//在mano中update会自动刷新但其他没有mano的不会故,需要在这个updata中调用其他脚本中的函数stateMachine.currentState.update以实现 //stateMachine中的update
-
- {
- base.Update();
- stateMachine.currentState.Update();//反复调用CurrentState的Update函数
- CheckForDashInput();
-
- }
- public void AssignNewSword(GameObject _newSword)//保持创造的sword实例的函数
- {
- sword = _newSword;
- }
-
- public void CatchTheSword()//通过player的CatchTheSword进入,及当剑消失的瞬间进入
- {
- stateMachine.ChangeState(catchSword);
- Destroy(sword);
- }
-
- public IEnumerator BusyFor(float _seconds)//https://www.zhihu.com/tardis/bd/art/504607545?source_id=1001
- {
- isBusy = true;
- yield return new WaitForSeconds(_seconds);
- isBusy = false;
-
- }//p39 4.防止在攻击间隔中进入move,通过设置busy值,在使用某些状态时,使其为busy为true,抑制其进入其他state
- //IEnumertor本质就是将一个函数分块执行,只有满足某些条件才能执行下一段代码,此函数有StartCoroutine调用
- public void AnimationTrigger() => stateMachine.currentState.AnimationFinishTrigger();
- //从当前状态拿到AnimationTrigger进行调用的函数
-
- public void CheckForDashInput()
- {
-
-
- if (IsWallDetected())
- {
- return;
- }//修复在wallslide可以dash的BUG
- if (Input.GetKeyDown(KeyCode.LeftShift) && skill.dash.CanUseSkill())//将DashTimer<0 的判断 改成DashSkill里的判断
- {
-
-
- dashDir = Input.GetAxisRaw("Horizontal");//设置一个值,可以将dash的方向改为你想要的方向而不是你的朝向
- if (dashDir == 0)
- {
- dashDir = facingDir;//只有当玩家没有控制方向时才使用默认朝向
- }
- stateMachine.ChangeState(dashState);
- }
-
- }//将Dash切换设置成一个函数,使其在所以情况下都能使用
-
-
-
- }
- using System.Collections;
- using System.Collections.Generic;
- using Unity.VisualScripting;
- using UnityEngine;
-
- public class PlayerBlackholeState : PlayerState
- {
- private float flyTime = .4f;//飞行时间
- private bool skillUsed;//技能是否在被使用
- private float defaultGravity;
-
- public PlayerBlackholeState(Player _player, PlayerStateMachine _stateMachine, string _animBoolName) : base(_player, _stateMachine, _animBoolName)
- {
- }
-
- public override void AnimationFinishTrigger()
- {
- base.AnimationFinishTrigger();
- }
-
- public override void Enter()
- {
- base.Enter();
-
- skillUsed = false;
- stateTimer = flyTime;
- defaultGravity = rb.gravityScale;
- rb.gravityScale = 0;
- }
-
- public override void Exit()
- {
- base.Exit();
- rb.gravityScale = defaultGravity;
- player.MakeTransprent(false);
- }
-
- public override void Update()
- {
- base.Update();
-
- //使角色释放技能后能飞起来
- if (stateTimer > 0)
- {
- rb.velocity = new Vector2(0, 15);
- }
-
- if(stateTimer < 0)
- {
- rb.velocity = new Vector2(0, -.1f);
-
- if(!skillUsed)
- {
- if(player.skill.blackhole.CanUseSkill())//创建实体
- skillUsed = true;
- }
- }
-
- if(player.skill.blackhole.SkillCompleted())
- {
- stateMachine.ChangeState(player.airState);
- }
- }
-
-
- }