Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释,可供学习Alex教程的人参考
此代码仅为较上一P有所改变的代码
【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili
Clone_Skill.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Clone_Skill : Skill
{
[Header("Clone Info")]
[SerializeField] private GameObject clonePrefab;//克隆原型
[SerializeField] private float cloneDuration;//克隆持续时间
[SerializeField] private bool canAttack;// 判断是否可以攻击
public void CreateClone(Transform _clonePosition)//传入克隆位置
{
GameObject newClone = Instantiate(clonePrefab);//创建新的克隆//克隆 original 对象并返回克隆对象。
//https://docs.unity3d.com/cn/current/ScriptReference/Object.Instantiate.html
newClone.GetComponent<Clone_Skill_Controller>().SetupClone(_clonePosition,cloneDuration,canAttack);//调试clone的位置,同时调试克隆持续时间
//Controller绑在克隆原型上的,所以用GetComponents,
}
}
Clone_Skill_Controller.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//Clone_Skill_Controller是绑在Clone体上的也就是Prefah上的
public class Clone_Skill_Controller : MonoBehaviour
{
private Animator anim;//声明animator
private SpriteRenderer sr;//定义Sr
[SerializeField] private float colorLoosingSpeed;//加速消失时间
private float cloneTimer;//定时器
[SerializeField]private Transform attackCheck;
[SerializeField] private float attackCheckRadius = .8f;
private Transform closestEnemy;
private void Awake()
{
sr = GetComponent<SpriteRenderer>();//拿到Sr
anim = GetComponent<Animator>();//拿到anim
}
private void Update()
{
cloneTimer -= Time.deltaTime;
if(cloneTimer < 0)
{
sr.color = new Color(1, 1, 1,sr.color.a-(Time.deltaTime * colorLoosingSpeed));//设置sr消失
}
if(sr.color.a<0)
{
Destroy(gameObject);
}
}
public void SetupClone(Transform _newTransform,float _cloneDuration,bool _canAttack)
{
if(_canAttack)
{
anim.SetInteger("AttackNumber", Random.Range(1, 3));//返回[minInclusive..maxInclusive](范围包括在内)内的随机浮点值。如果minInclusive大于maxInclusive,则数字会自动交换。
} //Random.Range()//https://docs.unity3d.com/cn/current/ScriptReference/Random.Range.html
transform.position = _newTransform.position;//这个函数实现了将克隆出来的对象的位置与Dash之前的位置重合的效果
cloneTimer = _cloneDuration;
FaceCloseTarget();
}
private void AnimationTrigger()
{
cloneTimer = -.1f;
}
private void AttackTrigger()
{
Collider2D[] colliders = Physics2D.OverlapCircleAll(attackCheck.position, attackCheckRadius);//创建一个碰撞器组,保存所有圈所碰到的碰撞器
//https://docs.unity3d.com/2022.3/Documentation/ScriptReference/Physics2D.OverlapCircleAll.html
foreach (var hit in colliders)//https://blog.csdn.net/m0_52358030/article/details/121722077
{
if (hit.GetComponent<Enemy>() != null)
{
hit.GetComponent<Enemy>().Damage();
}
}
}
private void FaceCloseTarget()
{
Collider2D[] colliders = Physics2D.OverlapCircleAll(transform.position, 25);//找到环绕自己的所有碰撞器
float closestDistance = Mathf.Infinity;//正无穷大的表示形式(只读)
//https://docs.unity3d.com/cn/current/ScriptReference/Mathf.Infinity.html
foreach(var hit in colliders)
{
if(hit.GetComponent<Enemy>()!=null)
{
float distanceToEnemy = Vector2.Distance(transform.position, hit.transform.position);//拿到与敌人之间的距离
if(distanceToEnemy < closestDistance)//比较距离,如果离得更近,保存这个敌人的位置,更改最近距离
{
closestDistance = distanceToEnemy;
closestEnemy = hit.transform;
}
}
}
if(closestEnemy != null)
{
if(transform.position.x>closestEnemy.position.x)//敌人在左面,转一圈
{
transform.Rotate(0,180,0);
}
}
}
}