Unity—英雄无敌(前方高能)

2023-11-03

英雄无敌(VR Project)【前方高能】:敌人模块、武器模块、HTC VIVE、玩家模块

可以学习考参一下本文章的思想、思路甚至是细节呦!*需求分析是重点

目录

敌人模块:

·敌人沿指定路线运动

·受击后减血死亡

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

·到达终点,攻击玩家

敌人生成器模块

策划

需求分析:

代码实现:


敌人模块:

·敌人沿指定路线运动

需求分析:创建脚本—敌人马达EnemyMotor,提供移动、旋转,寻路功能

代码实现:

public class EnemyMotor:MonoBehaviour

{

public void MovementForward()//向前移动

public void LookRotation(Vector3 point)//point:注视的目标点

{//提示:当前物体注视目标点旋转}

public bool Pathfinding()

{ return true;//需要继续寻路

  Return false;//到达终点,无需寻路

//如果到达目标点(判断当前位置与目标点间距 Vector3.Distance)

//更新目标点(向下一路口移动)

//朝向目标点

//向前移动

}

}

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

/// <summary>

/// 敌人马达,提供移动、旋转、寻路功能

/// </summary>

public class EnemyMotor : MonoBehaviour

{

    public Transform[] points;//当有路线脚本时:public WayLine line;

    //当前路点索引

    private int currentPointIndex;

    private float moveSpeed = 2;

    public void MovementForward()

    {

        this.transform.Translate(0, 0, moveSpeed * Time.deltaTime);

    }

    public void LookRotation(Vector3 targetPoint)

    {

        //提示:当前物体注视目标点旋转

        this.transform.LookAt(targetPoint);

    }

    public bool Pathfinding()

    {

        if (points == null || currentPointIndex >= points.Length) return false;//没有下一个点了//if (line== null || currentPointIndex >= line.WayPoints.Length) return false;(有了路线脚本后,改变的位置//把坐标换成路线)

        //朝向目标点

        LookRotation(points[currentPointIndex].position);

//LookRotation(line.WayPoints[currentPointIndex]);

        //向前移动

        MovementForward();

        //如果到达目标(当前位置接近于目标点)

        if (Vector3.Distance(this.transform.position, points[currentPointIndex].position) <0.5f)//if(Vector3.Distance(this.transform.position,line.WayPoints[currentPointIndex]< 0.5f)



            currentPointIndex++;

        return true;//可以继续寻路

    }

    //private void Update()

    //{

    //    Pathfinding();

    //}

}

 

·受击后减血死亡

需求分析:创建脚本—敌人状态信息EnemystatusInfo,定义血量,提供受伤,死亡的功能

代码实现:

public class EnemystatusInfo:MonoBehaviour

{

public EnemySpawn spawn;//敌人生成器的引用

public float HP=0;//当前血量

public float maxHP=200;//血量最大值

public float deathDelay=3;//死亡延迟销毁时间

//受伤

public void Damage(float amount)//amount需要扣除的血量

{ //扣血

HP-=amount;

//血量为0时,调用死亡方法

if(HP<=0)

Death();

}

public void Death()

{ Debug.Log(“阵亡”);

//播放当前画面

var anim=GetComponent<EnemyAnimation>();

animaction.Play(anim.deathAnimName);

//销毁当前物体

Destroy(this.gameObject,deathDelay);

//设置路线状态

GetComponent<EnemyMotor>().line.IsUsable=true;

//产生一下个敌人

Spawn.GenerateEnemy();

}

}

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

需求分析:创建脚本—敌人动画EnemyAnimation,定义各种动画名称,提供动画播放的功能

public class EnemyAnimation:MonoBehaviour

{ //敌人动画,定义需要播放的动画片段名称

public string anim.idleAnimName;//攻击后的闲置动画

public string runAnimName;

public string attckAnimName;

public string deathAnimName

public AnimationAction action;//AnimationAction行为类

public void Awake()

{ action=new Animation GetComponentInChildren<Animation>();

}

}

//动画行为类,提供有关动画的行为

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)//animName动画片段名称

{return anim.IsPlaying(animName);}

}

·到达终点,攻击玩家

需求分析:创建脚本—敌人AI EnemyAI,通过判断状态,执行寻路或者攻击

代码实现:

敌人AI

[RequireComponent(typeof(EnemyAniamtion))]

[RequireComponent(typeof(EnemyMotor))]

[RequireComponent(typeof(EnemyStatusInfo))]

//把EnemyAI拖给脚本,上边三个脚本也直接带着

public class EnemyAI:MonoBehaviour

{

//定义敌人状态的枚举类型

public enmu State

{ Attack, //攻击状态

PathFinding //寻路状态

}private State currentState=State.PathFinding;

private EnrmyMotor motor;

private EnemyAnimation anim;

private float atkTimer;

public float atkInterval=3;//攻击间隔

public void Start()

{ anim=GetComponent<EnemyAnimation>();

motor=GetComponent<EnemyMotor>();//找马达

}

public void Update()

{ //判断

Switch(currentState)

case State.PathFinding;

//执行寻路,调用马达中寻路方法,播放跑步动画

anim.action.Play(anim.runAnimName);

if(motor.Pathfinding()=false)//执行寻路结束,把切换状态

currentState=State.Attack;

break;

case State.Attack;

Attack();

break;

}

private void Attack()

{  //如果攻击动画没有播放

if(anim.action.IsPlaying(anim.attackAnimName)==false)

anim.action.Play(anim.idleAnimName)//播放闲置动画

//发起攻击

if(atkTimer<=Time.time)

{ anim.action.Play(anim.attackAnimName);

atkTimer=Time.time+atkInterval;//下一帧再调用就不满足条件

}

}(//ctrl+R+m可以提个方法)

}

AI怎样调用的动画:先找到引用EnemyAnimation,调用action,通过action调用AnimationAction里的实例方法

敌人生成器模块

策划

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

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

要求:敌人类型,产生的延迟时间随机

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

需求分析:

·创建跟路线,并添加多条配有路点的路线

·创建脚本—敌人生成器EnemySpawn,附加到跟路线中,提供生成敌人的功能

·创建类—路线WayLine,包含属性:路点坐标Vector3[] Points,是否可用bool IsUseable

当生成器启用后,计算所有子物体[路线]的路点坐标

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

代码实现:

//路线类

public class WayLine

{ public Vector3[] WayPoints{get;set;}

public bool IsUseable{get;set;}

//成员变量声明完,WayPoints默认是null,IsUseable默认是false

}

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class WayLine

{

    public Vector3[] WayPoints { get; set; }//声明完之后装的是null,因此要new

    public bool IsUseable { get; set; }

    public WayLine(int wayPointCount)

    {

        WayPoints = new Vector3[wayPointCount];

        IsUseable = true;

    }

}

//敌人生成器(脚本给路线点)

//脚本在路点,怎么找敌人?

public GameObject[] enemyType;//创建的敌人预制件数组

public int maxCount=5;//创建敌人最大数目

public int StartCount=2;

private int enemyCount;//已经创建的敌人数量

//生成一个敌人

public void GenerateEnemy()

{ //选择一条可以使用的路线?

//延迟时间随机

//Object.Instantiate(敌人预制件,位置,旋转角度)=Random.Range(0,enemyType.Length);

//创建敌人

GameObject go=Instantiate(enemyType[randomIndex],路线的第一个路点,Quaternion.identity)as GameObject;

//配置信息

go.GetComponent<EnemyMotor>();

}

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class EnemySpawn : MonoBehaviour

{

    public GameObject[] enemyType;//创建敌人的预制件

    public int maxCount = 5;

    public int StartCount = 2;//开始同时创建敌人的数量

    private int spawnedCount;//已经创建敌人数量

    private int maxDelay = 10;//延迟调用的最大时间

    private void Start()

    {

        CalculateWayLines();//计算所有路点

        //创建敌人

        for (int i = 0; i < StartCount; i++)

            GenerateEnemy();

    }

    private WayLine[] lines;//路线的数组是空的

   private void CalculateWayLines()

    {

        lines = new WayLine[this.transform.childCount];

        //根据路线数量创建路线数组,路线的数组有了但具体是什么还是空的

        for(int i=0;i<lines.Length;i++)

        {

            //每一个路线

            //路线变换组件的引用

            Transform wayLineTF = this.transform.GetChild(i);//获取每条路线的路点数

            //创建路线对象

            lines[i] = new WayLine(wayLineTF.childCount);

            //lines[0] {F12WayLine(WayPoints:Vector3[4]}

            //找点的坐标:把点的坐标给到路线的路点里去

            for(int pointIndex=0; pointIndex<wayLineTF.childCount; pointIndex++)

            {   //给路线路点赋值

                lines[i].WayPoints[pointIndex] = wayLineTF.GetChild(pointIndex).position;

            }

        }

    }

    //选择所有可以使用的路线

    private WayLine[] SelectUsableWayLine()

    {

        List<WayLine> result = new List<WayLine>(lines.Length);

        //遍历所有路线

        foreach(var item in lines)

        {//如果可以使用,添加到result列表中

            if (item.IsUseable) result.Add(item);

        }

        return result.ToArray();//把集合变为数组返回

    }

    public void GenerateEnemy()

    {

        spawnedCount++;

        //如果生成数量,已达到上限

        if(spawnedCount >=maxCount)

            return;

        //延迟产生一个敌人

        Invoke("CreateEnemy", Random.Range(1, maxDelay));

    }

   

    private void CreateEnemy()

    {

        //选择一条可以使用的路线?

        //选择所有可以使用的路线

        WayLine[] usableWayLines = SelectUsableWayLine();

        //随机选择一条

        WayLine line = usableWayLines[Random.Range(0, usableWayLines.Length)];

        //延迟时间随机?

        int randomIndex = Random.Range(0, enemyType.Length);

        //创建敌人

        GameObject go = Instantiate(enemyType[randomIndex], line.WayPoints[0], Quaternion.identity) as GameObject;

        //配置信息

        EnemyMotor motor = go.GetComponent<EnemyMotor>();

        motor.line = line;//传递路线

        line.IsUseable = false;

        //传递生成器对象引用【建议使用委托代替】(“回掉”为了敌人能调生成方法,把自己的引用传递进去)

        go.GetComponent<EnemyStatusInfo>().spawn = this;

    }

}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unity—英雄无敌(前方高能) 的相关文章

  • go语言的常见函数

    1 make函数 创建数组切片 Go语言提供的内置函数make 可以用于灵活地创建数组切片 创建一个初始元素个数为5的数组切片 元素初始值为0 mySlice1 make int 5 创建一个初始元素个数为5的数组切片 元素初始值为0 并预

随机推荐

  • 组件化2---APT的实现(ARoute)--传统写法和JavaPoet写法

    APT技术就是得用注解来自动生成一些类式代码 比如下面这个注解 Target ElementType TYPE Retention RetentionPolicy CLASS public interface ARouter String
  • Matlab图像操作——colorbar的详细使用方法与细节操作

    Matlab图像操作 colorbar的详细使用方法与细节操作 在Matlab中 colorbar是一种常用的工具 用于显示图像的颜色条 它提供了对图像色彩的可视化表示 使得用户能够更直观地理解图像数据的分布和范围 本文将介绍colorba
  • 网络传输一丢丢记录【数据包大小限制】

    今早用udp传一个对象序列化字节数组 大小达到了7000 字节 然后udp的send就报异常 一个在数据报套接字上发送的消息大于内部消息缓冲区或其他一些网络限制 或该用户用于接收数据报的缓冲区比数据报小 网上查了一下 说是超过udp的单包容
  • vue获取当前位置的信息以及天气信息

    1 首先在https lbs qq com 这个网页中 先使用微信 注册一个 1 1然后创建应用 1 2创建你的key 效果如下 这里面必须填写 0 0 0 0 255 255 25 255 2 使用npm下载jsonp插件 命令 npm
  • Windows Phone 7 网络字节序列化(结构转字节)实现

    令人激动的Windows Phone 7 Mango WP7 版本开放了Socket接口 虽有些Socket功能无法实现令人遗憾 但还是进步了一些 有了Socket我们就可以用其为我们传递Byte 数据流 而我们的数据又经常保存在struc
  • windows系统c语言编译器安装

    windows系统c语言编译器安装 1 安装包下载及说明 MinGW 的全称是 Minimalist GNU on Windows 实际上是将gcc c c 编译器 移植到了 Windows 平台下 并且包含了 Win32API 因此可以将
  • Enterprise Architect使用说明

    Enterprise Architect简介 支撑系统开发的全过程 在需求分析阶段 系统分析与设计阶段 系统开发及部署等方面有着强大的支持 同时加上对10种编程语言的正反向工程 项目管理 文档生成 数据建模等方面 可以让系统开发中各个角色都
  • Apache DolphinScheduler 如何实现自动化打包+单机/集群部署?

    Apache DolphinScheduler 是一款开源的分布式任务调度系统 旨在帮助用户实现复杂任务的自动化调度和管理 DolphinScheduler 支持多种任务类型 可以在单机或集群环境下运行 下面将介绍如何实现 DolphinS
  • 电子印章有哪些特点和优势?

    君子签电子印章系统是面向电子政务 电子商务等领域推出的获得国密认证 符合 安全电子签章密码技术规范 的安全系列产品 电子印章特点及优势 1 随时随地 自主印章 只要有网络 只要有电脑 用户就可以在任何时间 任何地点通过我们的平台自助申请印章
  • 文件路径问题( ./ 和 ../ 和 @/ )

    作为前端小白 最近在使用vue脚手架的时候 经常会遇到各种文件的引用 由于以前没有特别注意过这类问题 这次就写个文档给自己参考 PS 本篇文章仅用于 js 与 vue 代码的文件路径 其他语言的路径写法请自行尝试 文章目录 1 2 3 假如
  • C++桥接模式

    桥接模式 1 桥接模式简介及应用场景 桥接模式在 大话设计模式 一书中的定义是 将抽象部分与它的实现部分分离 使它们都可以独立地变化 抽象部分是指接口 实现部分是指继承接口的实体类 桥接模式可作为替代多重继承的一种方案 其主要应用场景为 一
  • 部落冲突COC呆呆机器人源码(采集资源/打鱼)

    字库部分 SetRowsNumber 0 注意 每次制作完字库后 需要自行把制作的字库文件添加到脚本 附件 中 SetDictEx 0 Attachment mq soft txt SetDictEx 1 Attachment army m
  • MFC之字符集与拓展讲解MFC函数名规范07

    1 字符集 字符集分为ASNI多字节字符集和UNICODE宽字节字符集 1 多字节字符集 一个字母代表一个字节 一般用于纯字母数字 例如欧洲国家 2 UNICODE宽字节字符集 一个字母代表两个字节或者三个字节 例如中文一般代表三个字节 所
  • 大宗物料管理信息系统 服务器名,材料管理信息系统

    LIMS应用越来越普及了 本文完整地阐述了LIMS开发和应用过程中的几乎所有重点问题 分享给大家 基本概念和发展历史 1 1 基本概念 简单地讲 实验室信息管理系统 LIMS 就是指通过计算机网络技术对实验的各种信息进行管理的计算机软 硬件
  • Seata1.4.0---新版本安装配置整合nacos与mysql

    文章目录 前言 一 配置mysql 1 创建数据表 2 conf目录file conf中加入数据库相关信息 二 配置nacos 1 单独创建seata命名空间 前言 在最近的几个版本中seata在配置方面进行了一定的变化 官方减少了一部分配
  • MySQL的基础

    目录 一 MySQL的基础概述 1 1基本概述 1 2SQL语句 1 3MySQL的特性 二 MySQL的语句 2 1查询语句 2 2插入语句 2 3更新语句 2 4删除语句 2 5连接查询 三 MySQL的运用 3 1创建一个数据库 3
  • python爬虫第7天 穿越网页表单与登录窗口进行采集 采集JavaScript

    Python Requests库 1 单选按钮 复选框和其他输入 2 提交文件和图像 3 处理登录和cookie 4 Requests 库的 session 函数 会话 session 对象 调用 requests Session 获取 会
  • Vue(树表格分页)

    目录 1 准备工作 2 动态树 2 1 在配置请求路径 2 2 使用动态数据构建导航菜单 2 2 1 通过接口获取数据 2 2 3 通过后台获取的数据构建菜单导航 2 2 3 1 先构建一级导航菜单 2 2 3 2 构建二级导航菜单 2 3
  • 《因果学习周刊》第13期:ICLR 23因果推断高分论文

    No 13 智源社区 因果学习组 因 果 学 习 研究 观点 资源 活动 周刊订阅 告诉大家一个好消息 因果学习周刊 已经开启 订阅功能 以后我们会向您自动推送最新版的 因果学习周刊 订阅方法 方式1 扫描下面二维码 进入 因果学习周刊 主
  • Unity—英雄无敌(前方高能)

    英雄无敌 VR Project 前方高能 敌人模块 武器模块 HTC VIVE 玩家模块 可以学习考参一下本文章的思想 思路甚至是细节呦 需求分析是重点 目录 敌人模块 敌人沿指定路线运动 受击后减血死亡 运动播放跑步动画 攻击播放攻击动画