“英雄无敌”(一)

news2024/10/5 17:25:59

注意:在阅读本文前建议观看对应的视频教程,本文主要作为那些对视频教程仍有疑问的学习者的参考资料。且本文的部分内容有些过时(如仍使用旧版Unity的动画系统),故直接阅读本文对Unity的学习没有太大意义

视频教程:https://www.bilibili.com/video/BV12s411g7gU?p=136

目录

敌人模块

需求分析 

EnemyMotor 敌人马达类

EnemyStatusInfo 敌人状态信息类 

EnemyAnimation 敌人动画类 

敌人生成器

需求分析

EnemySpawn 敌人生成器类 

Path 路线类


敌人模块

1.敌人沿指定路线运动

2.受击后减血死亡

3.到达终点攻击玩家 

4.运动播放跑步动画,攻击播放攻击动画,攻击间隔播放闲置动画,死亡播放死亡动画

需求分析 

EnemyMotor 敌人马达类:提供移动、旋转、寻路功能 

EnemyStatusInfo 敌人状态信息类:定义血量,提供受伤、死亡的功能

EnemyAnimation 敌人动画类:定义各种动画名称,提供播放动画的功能

ps:由于没有相应的游戏素材,故本文使用print(“播放XX动画”)来代替场景中动画的部分,其次本文建议创建几个对应的空动画以满足运行条件 

关于动画的创建及在新版中使用旧版动画系统的注意事项,请阅读Unity脚本(三)中关于Animation的内容

EnemyAI 敌人AI类:通过判断状态,执行寻路或者攻击

ps:以上组件均应挂载至敌人的预制体上,但在实际开发中不建议直接将组件构造至模型上,应为其创建一个空物体作为其父级并将组件挂载至该父级上,如下图

   

​​​​​​​

EnemyMotor 敌人马达类

1.定义向前移动的方法 

2.定义朝向目标点旋转的方法

3.定义寻路的方法

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

//敌人马达,提供移动、旋转、寻路功能
public class EnemyMotor : MonoBehaviour
{
    public Path path;
    //当前路径点的索引
    private int currentPointIndex = 0;
    public float moveSpeed;

    private void Update()
    {
        PathFinding();
    }

    //向前移动
    public void MovementForward()
    {
        transform.Translate(0, 0, moveSpeed * Time.deltaTime);
    }

    //注视选转
    public void LookRotation(Vector3 target)
    {
        this.transform.LookAt(target);
    }

    //寻路,沿路线移动
    public bool PathFinding()
    {
        //return true;继续寻路
        //return false;到达终点,无需寻路

        //如果到达目标点
        //更新目标点(向下一个点移动)

        if (path == null || currentPointIndex >= path.wayPoints.Length) return false;
        //朝向目标点
        LookRotation(path.wayPoints[currentPointIndex]);
        //向前移动
        MovementForward();
        //如果达到目标(当前位置接近于目标点)
        if (Vector3.Distance(transform.position, path.wayPoints[currentPointIndex]) < 0.1f)
        {
            currentPointIndex++;
        }
        return true;
    }
}

EnemyStatusInfo 敌人状态信息类 

1.定义变量:当前生命值

2.定义方法:受伤,死亡

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

//敌人状态信息类,定义敌人信息,提供受伤死亡功能
public class EnemyStatusInfo : MonoBehaviour
{
    public float HP = 200;
    public float maxHP = 200;
    //死亡延迟销毁时间
    public float deathDelay = 5;
    public EnemySpawn spawn;

    //受伤
    public void Damage(float damage)
    {
        //扣血
        HP -= damage;
        //血量为0时,调用死亡方法
        if (HP <= 0)
            Death();
    }

    //死亡
    public void Death()
    {
        //播放死亡动画
        var anim = GetComponent<EnemyAnimation>();
        anim.action.Play(anim.deathAnimName);
        print("播放死亡动画");
        //销毁当前物体  
        Destroy(gameObject, deathDelay);
        //设置路线状态
        GetComponent<EnemyMotor>().path.isUsable = true;
        //产生下一个物体
        spawn.GenerateEnemy();
    }

    //测试方法,鼠标点击敌人,对其造成50点伤害
    private void OnMouseDown() {
        Damage(50);
    }
}

ps:请务必在敌人的预制体上挂载碰撞组件(Collider),否则OnMouseDown()无法生效

EnemyAnimation 敌人动画类 

1.定义各种动画名称的变量,如跑步、闲置、攻击

2.定义AnimationAction类,提供有关动画的行为 

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

public class EnemyAnimation : MonoBehaviour
{
    //跑步动画名称
    public string runAnimName;
    //攻击动画名称
    public string attackAnimName;
    //闲置动画名称
    public string idleAnimaName;
    //死亡动画名称
    public string deathAnimName;
    //行为类
    public AnimationAction action;

    private void Awake()
    {
        //action=new AnimationAction(?);
        action=new AnimationAction(GetComponent<Animation>());
    }
}

AnimationAction 动画行为类

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

//动画行为类,提供有关动画的行为
public class AnimationAction
{
    //附加在敌人模型上的动画组件引用
    private Animation anim;

    //创建动画行为类
    public AnimationAction(Animation anim)
    {
        this.anim=anim;
    }

    //播放动画
    public void Play(string animName)
    {
        anim.CrossFade(animName);
    }

    public bool IsPlaying(string animName)
    {
        return anim.IsPlaying(animName);
    }

}

敌人生成器

1.开始时生成指定数量的敌人

2.为每人随机选择一条可以使用的路线

3.敌人类型、产生的延迟时间随机

4.当敌人死亡后,再产生下一个敌人,直到生成数量到达上限为止

需求分析

1.创建根路线,并添加多条配有路点的路线

2.EnemySpawn 敌人生成器类:附加到根路线中,提供生成敌人的功能

3.Path 路线类:包括的属性有,路点坐标Vector3[] wayPoints,是否可用bool IsUseable

4.当生成器启用后,计算所有所有可以路线路线

5.当生成敌人时,随机选择一条可以使用的路线

EnemySpawn 敌人生成器类 

定义变量:

GameObject[] enemyTypes:用于记录敌人预制件

int startCount:用于记录开始时需要创建的敌人数量

int spawnedCount:用于记录已经产生的敌人数量

int maxCount:用于记录产生敌人数量的上限

int maxDelay:用于记录产生敌人的最大延迟时间

定义方法: 

CalculateWayLines():用于计算所有路线及坐标

GenerateEnemy():用于生成一个敌人。 

using System.Net.Mail;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemySpawn : MonoBehaviour
{
    //需要创建的敌人预制件
    public GameObject[] enmeyType;
    //需要创建敌人的最大数目
    public int maxCount = 5;
    //初始创建的敌人数目
    public int startCount = 2;
    //已经创建的敌人数目
    private int spawnCount;
    private Path[] paths;
    public int maxDelay = 10;

    //生成一个敌人
    public void GenerateEnemy()
    {
        spawnCount++;
        //如果生成数量已达到上限
        if(spawnCount>=maxCount) return;
        //延迟时间随机
        Invoke("GreateEnemy", Random.Range(0, maxDelay));
    }

    private void GreateEnemy()
    {
        //选择所有可以使用的路线
        Path[] usablePaths = SelectUsablePath();
        //随机选择一条可以使用的路线
        Path path = usablePaths[Random.Range(0, usablePaths.Length)];
        int randomIndex = Random.Range(0, enmeyType.Length);
        //Instantiate(敌人预制件,位置,旋转角度);
        GameObject go = Instantiate(enmeyType[randomIndex], path.wayPoints[0], Quaternion.identity) as GameObject;
        //配置信息
        EnemyMotor motor = go.GetComponent<EnemyMotor>();
        motor.path = path;
        path.isUsable = false;
        //传递生成器引用
        go.GetComponent<EnemyStatusInfo>().spawn=this;
    }

    private void Start()
    {
        CalculateWayLines();
        GenerateEnemy();
    }

    private void CalculateWayLines()
    {
        paths = new Path[this.transform.childCount];
        for (int i = 0; i < paths.Length; i++)
        {
            //每一条路线
            //路线变换组件的引用
            Transform path = this.transform.GetChild(i);
            //创建路线对象
            paths[i] = new Path(path.childCount);
            for (int pointIndex = 0; pointIndex < path.childCount; pointIndex++)
            {
                paths[i].wayPoints[pointIndex] = path.GetChild(pointIndex).position;
            }
        }
    }

    //闲置可以使用的路线
    private Path[] SelectUsablePath()
    {
        List<Path> res = new List<Path>(paths.Length);
        //遍历所有路线
        foreach (var path in paths)
        {
            //如果可以使用,添加到res中
            if (path.isUsable) res.Add(path);
        }
        return res.ToArray();
    }
}

Path 路线类

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

public class Path
{
    public Vector3[] wayPoints { get; set; }
    public bool isUsable{ get; set; }

    //构造函数
    public Path(int wayPointCount){
        wayPoints=new Vector3[wayPointCount];
        isUsable=true;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/134640.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

写小论文心得(计算机视觉领域)

简介 这篇博文打算讲一下我写小论文前后的过程&#xff0c;其中有许多地方我觉得对于新手来说还是有很多帮助的&#xff0c;包括我自己也是自己慢慢摸索出来的&#xff0c;希望能对正在准备自己第一篇论文的人有所帮助。 写论文的整个过程我想分为几个阶段&#xff1a; 1.获得…

【深度学习】生成对抗网络(GAN)生成海贼王图像 + PyTorch代码实现

文章目录一、数据集介绍1.1 lufei&#xff08;路飞&#xff09;1.2 luobin&#xff08;罗宾&#xff09;1.3 namei&#xff08;娜美&#xff09;1.4 qiaoba&#xff08;乔巴&#xff09;1.5 shanzhi&#xff08;山智&#xff09;1.6 suolong&#xff08;索隆&#xff09;1.7 wu…

【内核笔记】2022回顾-2023规划

文章目录一、2022博客总结二、2023博客规划三、改进沉淀、分享、成长&#xff0c;让自己和他人都能有所收获&#xff01;&#x1f604; 一、2022博客总结 2022年重点优化了&#x1f680;RK3399平台开发入门到精通系列专栏&#xff0c;订阅量突破2100个订阅2022年浏览量破190万2…

《梁启超家书》笔记三——交友取益,或读书取益,也要方面稍多,才有接谈交换,或开卷引进的机会

目录 1、学科选择建议 2、学习 3、所学不可太专向&#xff08;不知道学科外其他方向的了&#xff09; 4、建议欧游实地开开眼界 5、建议结婚前分开两地住 6、毕业后工作看法(分析利弊) 7、处事态度与人生观 1、学科选择建议 我很想你以生物学为主科&#xff0c;因为它是…

Vue(五)

1. 绑定class和style样式 dom里自己拿到节点&#xff0c;改它上面的class样式 shift()移除第一个class属性 push想加哪个class属性都行 59行div知道自己只能用两个样式&#xff0c;四种情况 上面这种不合法&#xff0c;就算把样式加进div也得 样式对象&#xff1a;里面的key绿…

【ElasticSearch7.X】学习笔记(一)

【ElasticSearch7.X】学习笔记一、介绍1.1、ElasticSearch1.2、RESTful1.3、数据格式二、下载安装&#xff08;单机部署&#xff09;2.1、解压文件2.2、修改配置配置2.3、创建用户并授权2.5、启动三、增删查改3.1、 索引操作3.1.1、增加索引3.1.2、查看索引3.1.2.1、查看所有索…

定时任务介绍及X-Job和E-Job简单对比

下面对elastic-Job和xxl-Job做个简单的描述和对比 一、区别 1、XJob环境依赖于mysql&#xff0c;不依赖ZooKeeper&#xff0c; 2、EJob依赖ZooKeeper1、X-Job 侧重的业务实现的简单和管理的方便&#xff0c;学习成本简单&#xff0c; 失败策略和路由策略丰富。推荐使用在“用户…

对elasticsearch的实际应用

有业务需求&#xff0c;要做一个搜索接口&#xff0c;从千万的数据中根据筛选项查到需要的数据 筛选项有 1.学段。高中&#xff0c;初中等 2.学科。数学&#xff0c;语文等 3.专区。同步专区&#xff0c;高考专区等 4.试卷类型。月考卷&#xff0c;期中考试卷等 5.年级。高一&a…

MyBatis-Plus常用注解

常用注解 TableName 在使用MyBatis-Plus实现基本的CRUD时&#xff0c;我们并没有指定要操作的表&#xff0c;只是在Mapper接口继承BaseMapper时&#xff0c;设置了泛型User&#xff0c;而操作的表为user表 由此得出结论&#xff0c;MyBatis-Plus在确定操作的表时&#xff0c;…

基于 Tensorflow 2.x 从零训练花卉图像识别模型

一、数据集准备 本篇文章使用数千张花卉照片作为数据集&#xff0c;共分为5个分类&#xff1a;雏菊&#xff08;daisy&#xff09;、蒲公英&#xff08;dandelion&#xff09;、玫瑰&#xff08;roses&#xff09;、向日葵&#xff08;sunflowers&#xff09;、郁金香&#xf…

ClickHouse中的数据类型

ClickHouse中的数据类型数据类型说明数值类型IntFloatDecimal字符串类型StringFixedStringUUID时间类型DateDateTimeDateTIme64复杂类型ArrayEnumTupleNested特殊类型IPV4GEOBoolean 和 Nullable[参考文章]&#xff1a; ClickHouse &#xff5c; 数据类型介绍 数据类型说明 …

Docker | docker安装portainer详细步骤

portainer是一款容器管理可视化界面&#xff0c;不想在虚拟中使用命令管理容器的小伙伴&#xff0c;可以选择安装portainer对容器进行管理&#xff0c;查看日志、启动、停止容器等非常方便。 1. 搜索portainer镜像 docker search portainer 2. 拉取portainer镜像 docker pull…

[torch]日志记录之SummaryWriter(持更)

参考博文&#xff1a; 《tensorboardX的简单使用》《详解PyTorch项目使用TensorboardX进行训练可视化》《使用TensorBoard检查监控深度学习模型》 一、使用方法 class SummaryWriter(builtins.object)| SummaryWriter(log_dirNone, comment, purge_stepNone, max_queue10, f…

Springboot扩展点之ApplicationContextInitializer

前言 一提到Spring、Springoboot&#xff0c;很多人马上就会想到依赖注入、控制反转、自动装配、约定大于配置、使开发变得简单等等。但是如果仅仅会使用Springboot、SpringMVC完成一些增删改查&#xff0c;解决一些bug&#xff0c;那么实际上你并没有真的懂Spring、Sp…

每天5分钟机器学习:线性判别分析LDA算法

本文重点 我们前面学习了PCA算法,本文我们将学习一种新的算法,这种算法和PCA非常相似,这个算法叫做线性判别分析,简称为LDA,也称为Fisher线性判别(Fisher Linear Discriminant,FLD),是模式识别的经典算法,在1996年由Belhumeur引入模式识别和人工智能领域。 LDA原理 …

毒鸡汤 | 云服务器部署项目

文章目录前言环境介绍安装PHP安装Apache安装MySQL上传项目访问网站前言 新年的第一篇文章&#xff0c;今年继续努力加油&#xff0c;继续产出高质量的文章。 前面用PHPstudy搭建了【毒鸡汤】项目&#xff0c;但是这样只能自己访问&#xff0c;别人是访问不了的&#xff0c;因此…

Redis 持久化机制

个人博客地址&#xff1a; 文章目录Redis 持久化机制1. 概述2. RDB2.1 手动快照2.2 自动快照3. AOF3.1 AOF机制3.2 AOF文件的重写4. 混合型持久化5. 总结Redis 持久化机制 1. 概述 Redis​为了保证性能&#xff0c;会将所有数据放在内存中&#xff0c;那么万一Redis宕机&…

AcWing 756. 蛇形矩阵

目录问题描述思路与代码1. 个人解法2. 官方题解问题描述 原题链接&#x1f517;&#xff1a;756. 蛇形矩阵 输入两个整数 nnn 和 mmm&#xff0c;输出一个 nnn 行 mmm 列的矩阵&#xff0c;将数字 111 到 nmnmnm 按照回字蛇形填充至矩阵中。 具体矩阵形式可参考样例。 输入格…

synchronized底层原理

synchronized是JVM内置锁&#xff0c;基于monitor机制实现&#xff0c;依赖底层操作系统的互斥源语Mutex&#xff08;互斥量&#xff09;&#xff0c;它是一个重量级锁&#xff0c;性能较低。 当然&#xff0c;JVM内置锁在1.5之后版本做了重大优化&#xff0c;如锁粗化&#xf…

[红明谷CTF 2021]JavaWeb

0x01 好久没打过ctf了&#xff0c;最近也在学Java 就看下java的题吧 WP 进入环境就提示访问 /login &#xff0c;访问之后 提示的 /json ,试着访问一下 给了 jessid&#xff0c;继续访问 /json 的话 又会跳转至 /login 应该是要传点username password 果然是了&#…