当前位置: 首页 > article >正文

Unity类银河战士恶魔城学习总结(P178 Archer s arrow 弓箭手的箭)

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

教程源地址:https://www.udemy.com/course/2d-rpg-alexdev/

本章节制作了一个弓箭手的箭

Arrow_Controller.cs

1.OnTriggerEnter2D方法

  • 功能:检测箭矢与其他对象的碰撞。
  • 逻辑
    • 如果碰撞对象的层级与targetLayerName匹配
      • 获取碰撞对象的CharacterStats组件并调用TakeDamage(damage)方法,造成伤害。
      • 调用StuckInto(collision)方法,使箭矢嵌入碰撞对象。
    • 如果碰撞对象的层级为"Ground"
      • 直接调用StuckInto(collision)方法,使箭矢嵌入地面。

2.StuckInto方法

  • 功能:处理箭矢嵌入目标后的状态变化。
  • 步骤
    1. 停止粒子系统:停止箭矢子对象中的ParticleSystem,例如拖尾效果。
    2. 禁用碰撞体:禁用箭矢的Collider2D,防止进一步的碰撞检测。
    3. 停止移动:将canMove设为false,阻止在Update中继续移动。
    4. 设置刚体为运动学:将rb.isKinematic设为true,使箭矢不再受物理引擎影响。
    5. 冻结所有刚体约束:通过rb.constraints = RigidbodyConstraints2D.FreezeAll冻结箭矢的所有移动和旋转,确保其在嵌入后不再移动。
    6. 设置父对象:将箭矢的transform设置为碰撞对象的子对象,使其随碰撞对象一起移动。
    7. 销毁箭矢:在5到7秒后销毁箭矢对象,使用Random.Range(5,7)生成销毁延迟时间。

3.FlipArrow()方法

功能:翻转箭矢的方向,使其朝相反方向移动,并更改目标层级。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//2024.12.11
public class Arrow_Controller : MonoBehaviour
{
    [SerializeField] private int damage;//箭矢造成的伤害值
    [SerializeField] private string targetLayerName = "Player";//箭矢的目标层

    [SerializeField] private float xVelocity;
    [SerializeField] private Rigidbody2D rb;

    [SerializeField] private bool canMove;
    [SerializeField] private bool flipped;


    private void Update()
    {
        if(canMove)
            rb.velocity = new Vector2(xVelocity, rb.velocity.y);
    }



    private void OnTriggerEnter2D(Collider2D collision)
    {
        if(collision.gameObject.layer == LayerMask.NameToLayer(targetLayerName))
        {
            collision.GetComponent<CharacterStats>().TakeDamage(damage);
            StuckInto(collision);

        }
        else if (collision.gameObject.layer == LayerMask.NameToLayer("Ground"))
        {
            StuckInto(collision);
        }

    }


    private void StuckInto(Collider2D collision)//射中目标
    {
        GetComponentInChildren<ParticleSystem>().Stop();//停止粒子系统
        GetComponent<Collider2D>().enabled = false;
        canMove = false;
        rb.isKinematic = true;//刚体为运动
        rb.constraints = RigidbodyConstraints2D.FreezeAll;
        transform.parent = collision.transform;//箭矢的父物体为碰撞物体

        Destroy(gameObject, Random.Range(5,7));
    }


    public void FlipArrow()
    {
        if (flipped)
            return;


        xVelocity = xVelocity * -1;
        flipped = true;
        transform.Rotate(0,180,0);
        targetLayerName = "Enemy";

    }
}

PlayerCounterAttackState.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerCounterAttackState : PlayerState
{
    private bool canCreateClone;

    public PlayerCounterAttackState(Player _player, PlayerStateMachine _stateMachine, string _animBoolName) : base(_player, _stateMachine, _animBoolName)
    {
    }

    public override void Enter()
    {
        base.Enter();

        canCreateClone = true;
        stateTimer = player.counterAttackDuration;
        player.anim.SetBool("SuccessfulCounterAttack", false);

    }

    public override void Exit()
    {
        base.Exit();
    }

    public override void Update()
    {
        base.Update();

        player.SetZeroVelocity();

        Collider2D[] colliders = Physics2D.OverlapCircleAll(player.attackCheck.position, player.attackCheckRadius);


        foreach (var hit in colliders)
        {
            if(hit.GetComponent<Arrow_Controller>()!= null)
            {
                hit.GetComponent<Arrow_Controller>().FlipArrow();
                SuccesfulCounterAttack();
            }


            if (hit.GetComponent<Enemy>() != null)
            {
                if (hit.GetComponent<Enemy>().CanBeStunned())
                    {
                        SuccesfulCounterAttack();

                        player.skill.parry.UseSkill();


                        if (canCreateClone)
                        {
                            canCreateClone = false;
                            player.skill.parry.MakeMirageOnParry(hit.transform);
                        }
                    }
                }
        }

        if (stateTimer < 0 || triggerCalled)
            stateMachine.ChangeState(player.idleState);

    }

    private void SuccesfulCounterAttack()
    {
        stateTimer = 10;//大于1的数,保证不会进入idle状态
        player.anim.SetBool("SuccessfulCounterAttack", true);
    }
}

http://www.kler.cn/a/443192.html

相关文章:

  • FPGA的 基本结构(Xilinx 公司Virtex-II 系列FPGA )
  • SpringBoot之核心配置
  • python【数据结构】
  • 单元测试MockitoExtension和SpringExtension
  • uniapp获取安卓与ios的唯一标识
  • CDP集成Hudi实战-Hive
  • 从Windows到Linux:跨平台数据库备份与还原
  • 利用Java爬虫获得京东JD商品SKU信息
  • 论文学习—VAE
  • 皮肤伤口分割数据集labelme格式248张5类别
  • 修改uniapp下拉刷新圆圈颜色
  • Unity UI SafeArea适配
  • vue-element-admin npm install 安装失败,tui-editor更名导致
  • API接口性能优化:提升电商数据处理速度的关键
  • 错误处理中间件 VS 异常过滤器 net Core
  • 深入解析ENAS中的共享权重机制
  • pyparsing restOfLine
  • 基于xss-lab的绕过
  • 华纳云:如何实现tomcat自动化部署?
  • 【Yonghong 企业日常问题03】如何在Linux系统上部署Yonghong DM-Engine v2.3.1(一键安装指南版)
  • 随手记:小程序使用uni.createVideoContext视频无法触发播放
  • Excel+VBA+FFmpeg全能图片处理利器:批量选择、调整尺寸、压缩质量、图片合并,水平垂直合并一键搞定!
  • 【C++】sophus 计算机视觉和机器人技术中的二维和三维李群 (一)
  • WPF MVVM 数据表格DataGrid的表头Header无法进行数据绑定
  • Java全栈项目:校园共享单车管理平台
  • 红狮金业:央行利率决议对贵金属市场的影响