Alex教程每一P的教程原代碼加上我自己的理解初步理解寫(xiě)的注釋,可供學(xué)習(xí)Alex教程的人參考 此代碼僅為較上一P有所改變的代碼、
【Unity教程】從0編程制作類銀河惡魔城游戲_嗶哩嗶哩_bilibili文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-840855.html
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-840855.html
Blackhole_Skill_Controller.cs
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
public class Blackhole_Skill_Controller : MonoBehaviour
{
[SerializeField] private GameObject hotKeyPrefab;
[SerializeField] private List<KeyCode> KeyCodeList;
private float maxSize;//最大尺寸
private float growSpeed;//變大速度
private float shrinkSpeed;//縮小速度
private float blackholeTimer;
private bool canGrow = true;//是否可以變大
private bool canShrink;//縮小
private bool canCreateHotKeys = true;專門控制后面進(jìn)入的沒(méi)法生成熱鍵
private bool cloneAttackReleased;
private int amountOfAttacks = 4;
private float cloneAttackCooldown = .3f;
private float cloneAttackTimer;
private List<Transform> targets = new List<Transform>();
private List<GameObject> createdHotKey = new List<GameObject>();
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;//防止重復(fù)檢測(cè)
if (targets.Count > 0)//只有有target才釋放攻擊
{
ReleaseCloneAttack();//釋放攻擊
}
else
FinishBlackholeAbility();//縮小黑洞
}
if (Input.GetKeyDown(KeyCode.R)&& targets.Count > 0)
{
ReleaseCloneAttack();
}
CloneAttackLogic();
if (canGrow && !canShrink)
{
//這是控制物體大小的參數(shù)
transform.localScale = Vector2.Lerp(transform.localScale, new Vector2(maxSize, maxSize), growSpeed * Time.deltaTime);
//類似MoveToward,不過(guò)是放大到多少大小 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);
//限制攻擊次數(shù)和設(shè)置攻擊偏移量
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<Enemy>()!=null)
{
collision.GetComponent<Enemy>().FreezeTime(true);
CreateHotKey(collision);
}
}
private void OnTriggerExit2D(Collider2D collision)
{
if (collision.GetComponent<Enemy>() != null)
{
collision.GetComponent<Enemy>().FreezeTime(false);
}
}
private void CreateHotKey(Collider2D collision)
{
if(KeyCodeList.Count == 0)//當(dāng)所有的KeyCode都被去除,就不在創(chuàng)建實(shí)例
{
return;
}
if(!canCreateHotKeys)//這是當(dāng)角色已經(jīng)開(kāi)大了,不在創(chuàng)建實(shí)例
{
return;
}
//創(chuàng)建實(shí)例
GameObject newHotKey = Instantiate(hotKeyPrefab, collision.transform.position + new Vector3(0, 2), Quaternion.identity);
//將實(shí)例添加進(jìn)列表
createdHotKey.Add(newHotKey);
//隨機(jī)KeyCode傳給HotKey,并且傳過(guò)去一個(gè)毀掉一個(gè)
KeyCode choosenKey = KeyCodeList[Random.Range(0, KeyCodeList.Count)];
KeyCodeList.Remove(choosenKey);
Blackhole_Hotkey_Controller newHotKeyScript = newHotKey.GetComponent<Blackhole_Hotkey_Controller>();
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]);
}
}
}
Blackhole_Skill.cs
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<Blackhole_Skill_Controller>();
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;
}
}
}
Player.cs
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
public class Player : Entity
{
[Header("Attack Details")]
public Vector2[] attackMovement;//每個(gè)攻擊時(shí)獲得的速度組
public float counterAttackDuration = .2f;
public bool isBusy{ get; private set; }//防止在攻擊間隔中進(jìn)入move
//
[Header("Move Info")]
public float moveSpeed;//定義速度,與xInput相乘控制速度的大小
public float jumpForce;
public float swordReturnImpact;//在player里設(shè)置swordReturnImpact作為擊退的參數(shù)
[Header("Dash Info")]
[SerializeField] private float dashCooldown;
private float dashUsageTimer;//為dash設(shè)置冷卻時(shí)間,在一定時(shí)間內(nèi)不能連續(xù)使用
public float dashSpeed;//沖刺速度
public float dashDuration;//持續(xù)時(shí)間
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();
//通過(guò)構(gòu)造函數(shù),在構(gòu)造時(shí)傳遞信息
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動(dòng)畫(huà)
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這個(gè)類本身
}//Awake初始化所以State,為所有State傳入各自獨(dú)有的參數(shù),及animBool,以判斷是否調(diào)用此動(dòng)畫(huà)(與animatoin配合完成)
protected override void Start()
{
base.Start();
stateMachine.Initialize(idleState);
skill = SkillManager.instance;
}
protected override void Update()//在mano中update會(huì)自動(dòng)刷新但其他沒(méi)有mano的不會(huì)故,需要在這個(gè)updata中調(diào)用其他腳本中的函數(shù)stateMachine.currentState.update以實(shí)現(xiàn) //stateMachine中的update
{
base.Update();
stateMachine.currentState.Update();//反復(fù)調(diào)用CurrentState的Update函數(shù)
CheckForDashInput();
}
public void AssignNewSword(GameObject _newSword)//保持創(chuàng)造的sword實(shí)例的函數(shù)
{
sword = _newSword;
}
public void CatchTheSword()//通過(guò)player的CatchTheSword進(jìn)入,及當(dāng)劍消失的瞬間進(jìn)入
{
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.防止在攻擊間隔中進(jìn)入move,通過(guò)設(shè)置busy值,在使用某些狀態(tài)時(shí),使其為busy為true,抑制其進(jìn)入其他state
//IEnumertor本質(zhì)就是將一個(gè)函數(shù)分塊執(zhí)行,只有滿足某些條件才能執(zhí)行下一段代碼,此函數(shù)有StartCoroutine調(diào)用
public void AnimationTrigger() => stateMachine.currentState.AnimationFinishTrigger();
//從當(dāng)前狀態(tài)拿到AnimationTrigger進(jìn)行調(diào)用的函數(shù)
public void CheckForDashInput()
{
if (IsWallDetected())
{
return;
}//修復(fù)在wallslide可以dash的BUG
if (Input.GetKeyDown(KeyCode.LeftShift) && skill.dash.CanUseSkill())//將DashTimer<0 的判斷 改成DashSkill里的判斷
{
dashDir = Input.GetAxisRaw("Horizontal");//設(shè)置一個(gè)值,可以將dash的方向改為你想要的方向而不是你的朝向
if (dashDir == 0)
{
dashDir = facingDir;//只有當(dāng)玩家沒(méi)有控制方向時(shí)才使用默認(rèn)朝向
}
stateMachine.ChangeState(dashState);
}
}//將Dash切換設(shè)置成一個(gè)函數(shù),使其在所以情況下都能使用
}
PlayerBlackholeState.cs
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
public class PlayerBlackholeState : PlayerState
{
private float flyTime = .4f;//飛行時(shí)間
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();
//使角色釋放技能后能飛起來(lái)
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())//創(chuàng)建實(shí)體
skillUsed = true;
}
}
if(player.skill.blackhole.SkillCompleted())
{
stateMachine.ChangeState(player.airState);
}
}
}
到了這里,關(guān)于Unity類銀河惡魔城學(xué)習(xí)記錄8-5 p81 Blackhole duration源代碼的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!