• Unity类银河恶魔城学习记录7-8 P74 Pierce sword源代码


     Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释,可供学习Alex教程的人参考
    此代码仅为较上一P有所改变的代码

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

     

     Sword_Skill.cs
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. public enum SwordType
    6. {
    7. Regular,
    8. Bounce,
    9. Pierce,
    10. Spin
    11. }
    12. public class Sword_Skill : Skill
    13. {
    14. public SwordType swordType = SwordType.Regular;//创建应一个enum列表,后面用来判断切换状态
    15. [Header("Bounce Info")]
    16. [SerializeField] private int bounceAmount;
    17. [SerializeField] private float bounceGravity;
    18. [Header("Pierce info")]
    19. [SerializeField] private int pierceAmount;
    20. [SerializeField] private float pierceGravity;
    21. [Header("Skill Info")]
    22. [SerializeField] private GameObject swordPrefab;//sword预制体
    23. [SerializeField] private Vector2 launchForce;//发射力度
    24. [SerializeField] private float swordGravity;//发射体的重力
    25. private Vector2 finalDir;//发射方向
    26. [Header("Aim dots")]
    27. [SerializeField] private int numberOfDots;//需要的点的数量
    28. [SerializeField] private float spaceBetweenDots;//相隔的距离
    29. [SerializeField] private GameObject dotPrefab;//dot预制体
    30. [SerializeField] private Transform dotsParent;//不是很懂
    31. private GameObject[] dots;//dot组
    32. protected override void Start()
    33. {
    34. base.Start();
    35. GenerateDots();//生成点函数
    36. SetupGravity();
    37. }
    38. private void SetupGravity()//每个剑的状态都对应了不同的剑重力
    39. {
    40. if(swordType == SwordType.Pierce)
    41. {
    42. swordGravity = pierceGravity;
    43. }
    44. if(swordType == SwordType.Bounce)
    45. {
    46. swordGravity = bounceGravity;
    47. }
    48. }
    49. protected override void Update()
    50. {
    51. base.Update();
    52. if (Input.GetKeyUp(KeyCode.Mouse1))
    53. {
    54. finalDir = new Vector2(AimDirection().normalized.x * launchForce.x, AimDirection().normalized.y * launchForce.y);
    55. //将位移量改为单位向量分别与力度的x,y相乘作为finalDir
    56. }
    57. if (Input.GetKey(KeyCode.Mouse1))
    58. {
    59. for (int i = 0; i < dots.Length; i++)
    60. {
    61. dots[i].transform.position = DotsPosition(i * spaceBetweenDots);//用循环为每个点以返回值赋值(传入值为每个点的顺序i*点间距
    62. }
    63. }
    64. }
    65. public void CreateSword()
    66. {
    67. GameObject newSword = Instantiate(swordPrefab, player.transform.position, transform.rotation);//创造实例,初始位置为此时player的位置
    68. Sword_Skill_Controller newSwordScript = newSword.GetComponent();//获得Controller
    69. if(swordType == SwordType.Bounce)
    70. {
    71. newSwordScript.SetupBounce(true, bounceAmount);
    72. }
    73. else if(swordType == SwordType.Pierce)
    74. {
    75. newSwordScript.SetupPierce(pierceAmount);
    76. }
    77. newSwordScript.SetupSword(finalDir, swordGravity, player);//调用Controller里的SetupSword函数,给予其速度和重力和player实例
    78. player.AssignNewSword(newSword);//调用在player中保存通过此方法创造出的sword实例
    79. DotsActive(false);//关闭点的显示
    80. }
    81. #region Aim region
    82. public Vector2 AimDirection()
    83. {
    84. Vector2 playerPosition = player.transform.position;//拿到玩家此时的位置
    85. Vector2 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);//https://docs.unity3d.com/cn/current/ScriptReference/Camera.ScreenToWorldPoint.html
    86. //大概就是返回屏幕上括号里的参数的位置,这里返回了鼠标的位置
    87. //拿到此时鼠标的位置
    88. Vector2 direction = mousePosition - playerPosition;//获得距离的绝对向量
    89. return direction;//返回距离向量
    90. }
    91. public void DotsActive(bool _isActive)
    92. {
    93. for (int i = 0; i < dots.Length; i++)
    94. {
    95. dots[i].SetActive(_isActive);//设置每个点是否显示函数
    96. }
    97. }
    98. private void GenerateDots()//生成点函数
    99. {
    100. dots = new GameObject[numberOfDots];//为dot赋予实例数量
    101. for (int i = 0; i < numberOfDots; i++)
    102. {
    103. dots[i] = Instantiate(dotPrefab, player.transform.position, Quaternion.identity, dotsParent);//对象与世界轴或父轴完全对齐
    104. //https://docs.unity3d.com/cn/current/ScriptReference/Quaternion-identity.html
    105. dots[i].SetActive(false);//关闭dot
    106. }
    107. }
    108. private Vector2 DotsPosition(float t)//传入顺序相关的点间距
    109. {
    110. Vector2 position = (Vector2)player.transform.position +
    111. new Vector2
    112. (AimDirection().normalized.x * launchForce.x,
    113. AimDirection().normalized.y * launchForce.y) * t //基本间距
    114. + .5f * (Physics2D.gravity * swordGravity) * (t * t)//重力影响
    115. ;
    116. //t是控制之间点间距的
    117. return position;//返回位置
    118. }//设置点间距函数
    119. #endregion
    120. }
    Sword_Skill_Controller.cs
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. public class Sword_Skill_Controller : MonoBehaviour
    5. {
    6. [SerializeField] private float returnSpeed = 12;
    7. private bool isReturning;
    8. private Animator anim;
    9. private Rigidbody2D rb;
    10. private CircleCollider2D cd;
    11. private Player player;
    12. private bool canRotate = true;
    13. [Header("Piece info")]
    14. [SerializeField] float pierceAmount;
    15. [Header("Bounce info")]
    16. [SerializeField]private float bounceSpeed;//设置弹跳速度
    17. private bool isBouncing;//判断是否可以弹跳
    18. private int bounceAmount;//弹跳的次数
    19. public List enemyTargets;//保存所有在剑范围内的敌人的列表
    20. private int targetIndex;//设置targetIndex作为敌人计数器
    21. private void Awake()
    22. {
    23. anim = GetComponentInChildren();
    24. rb = GetComponent();
    25. cd = GetComponent();
    26. }
    27. public void ReturnSword()
    28. {
    29. rb.constraints = RigidbodyConstraints2D.FreezeAll;//修复剑只要不触碰到物体就无法收回的bug
    30. //rb.isKinematic = false;
    31. transform.parent = null;
    32. isReturning = true;
    33. }
    34. public void SetupSword(Vector2 _dir,float _gravityScale,Player _player)
    35. {
    36. player = _player;
    37. rb.velocity = _dir;
    38. rb.gravityScale = _gravityScale;
    39. if(pierceAmount < 0)
    40. anim.SetBool("Rotation", true); //其次在pierceAmount > 0时不启动旋转动画
    41. }
    42. public void SetupBounce(bool _isBouncing,int _bounceAmount)
    43. {
    44. isBouncing = _isBouncing;
    45. bounceAmount = _bounceAmount;
    46. }
    47. public void SetupPierce(int _pierceAomunt)
    48. {
    49. pierceAmount = _pierceAomunt;
    50. }
    51. private void Update()
    52. {
    53. if (canRotate)
    54. transform.right = rb.velocity;//使武器随着速度而改变朝向
    55. if (isReturning)
    56. {
    57. transform.position = Vector2.MoveTowards(transform.position, player.transform.position, returnSpeed * Time.deltaTime);//从原来的位置返回到player的位置
    58. //并且随着时间增加而增加速度
    59. if (Vector2.Distance(transform.position, player.transform.position) < 1)//当剑与player的距离小于一定距离,清除剑
    60. {
    61. player.CatchTheSword();
    62. }
    63. }
    64. BounceLogic();
    65. }
    66. private void BounceLogic()
    67. {
    68. if (isBouncing && enemyTargets.Count > 0)
    69. {
    70. transform.position = Vector2.MoveTowards(transform.position, enemyTargets[targetIndex].position, bounceSpeed * Time.deltaTime);
    71. //3.当可以弹跳且列表内数量大于0,调用ToWords,这将使剑能够跳到敌人身上
    72. if (Vector2.Distance(transform.position, enemyTargets[targetIndex].position) < .1f)
    73. {
    74. targetIndex++;
    75. bounceAmount--;//设置弹跳次数
    76. if (bounceAmount <= 0)
    77. {
    78. isBouncing = false;
    79. isReturning = true;
    80. }//这样会使当弹跳次数为0时,返回到角色手中
    81. if (targetIndex >= enemyTargets.Count)
    82. {
    83. targetIndex = 0;
    84. }
    85. }//利用与目标距离的判断,使剑接近目标距离时切换到下一个目标。
    86. //且如果所有目标都跳完了,切回第一个
    87. }
    88. }
    89. private void OnTriggerEnter2D(Collider2D collision)//传入碰到的物体的碰撞器
    90. {
    91. if (isReturning)
    92. {
    93. return;
    94. }//修复在返回时扔出时没有碰到任何物体,但返回时碰到了物体导致剑的一些性质发生改变的问题,及回来的时候调用了OnTriggerEnter2D
    95. collision.GetComponent()?.Damage();//设置一下敌人受击动画
    96. if (collision.GetComponent() != null)//首先得碰到敌人,只有碰到敌人才会跳
    97. {
    98. if (isBouncing && enemyTargets.Count <= 0)
    99. {
    100. Collider2D[] colliders = Physics2D.OverlapCircleAll(transform.position, 10);
    101. foreach (var hit in colliders)
    102. {
    103. if (hit.GetComponent() != null)
    104. {
    105. enemyTargets.Add(hit.transform);
    106. }
    107. }
    108. }
    109. }
    110. StuckInto(collision);
    111. }//打开IsTrigger时才可使用该函数
    112. //https://docs.unity3d.com/cn/current/ScriptReference/Collider2D.OnTriggerEnter2D.html
    113. private void StuckInto(Collider2D collision)
    114. {
    115. if(pierceAmount > 0 && collision.GetComponent()!= null)//本质就是能穿过敌人,在amount>0时不执行能让剑卡在敌人里的语句就行
    116. {
    117. pierceAmount--;
    118. return;
    119. }
    120. canRotate = false;
    121. cd.enabled = false;//相当于关闭碰撞后触发函数。//https://docs.unity3d.com/cn/current/ScriptReference/Collision2D-enabled.html
    122. rb.isKinematic = true;//开启物理学反应 https://docs.unity3d.com/cn/current/ScriptReference/Rigidbody2D-isKinematic.html
    123. rb.constraints = RigidbodyConstraints2D.FreezeAll;//冻结所有移动
    124. if (isBouncing&&enemyTargets.Count>0)//修复剑卡不到墙上的bug
    125. return;
    126. //终止对动画的改变和终止附在敌人上
    127. transform.parent = collision.transform;//设置sword的父组件为碰撞到的物体
    128. anim.SetBool("Rotation", false);
    129. }
    130. }

  • 相关阅读:
    sql 5
    Fluent表达式应用案例
    2020最新Java常见面试题及答案
    maven assembly打包生成Java应用启动脚本bat和sh
    我理解的游戏数据模型
    Android——SQLiteOpenHelper
    【2023百度之星初赛】跑步,夏日漫步,糖果促销,第五维度,公园,新材料,星际航行,蛋糕划分
    享元模式
    谷粒商城 (十二) --------- 商品服务 API 三级分类 ③ 树形展示三级分类数据
    关于百度蜘蛛机器人爬取博客园次数异常的猜想.
  • 原文地址:https://blog.csdn.net/Homura_/article/details/136276769