首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >游戏AI-实现AI角色的自主移动——操控行为

游戏AI-实现AI角色的自主移动——操控行为

作者头像
祝你万事顺利
发布于 2019-05-28 15:13:27
发布于 2019-05-28 15:13:27
1.3K00
代码可运行
举报
文章被收录于专栏:Unity游戏开发Unity游戏开发
运行总次数:0
代码可运行

Unity操控行为编程的基类:Vehicle类、AILocomotion类和Steering类

1.将AI角色抽象成一个质点——Vehicle类

这个类直译为“交通工具”包括了很宽泛的能自主移动的AI角色。 操作对象抽象为一个质点,包含位置信息、质量、速度等,速度随着施加力的变化而变化。力与速度都有一个限制,因此还需要最大力、最大速度。还需要一个朝向。 位置计算方法 1.每一帧的力(最大不超过最大力) 2.交通工具的质量,来确定加速度 3.加速度与原速度相加,得到新的速度 4.新的速度与一帧的时间相乘,计算出位移 5.原位置加上位移得到新位置

此类通过获取AI角色的操控行为列表,对表中的行为进行带权重的求和,再求得加速度

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Vehicle : MonoBehaviour {

    //操控行为的列表
    private Steering[] steerings;
    //最大速度
    public float maxSpeed = 10f;
    //能施加的最大力
    public float maxForce = 100;
    //最大速度平方
    protected float sqrMaxSpeed;

    public float mass = 1;
    public Vector3 velocity;

    //转向速度
    public float damping = 0.9f;

    //操控力的计算间隔,操控力每隔一段时间进行计算,来提高帧率
    public float computeInterval = 0.2f;

    //是否在平面上
    public bool isPlanar = true;

    //计算得到的操控力
    private Vector3 steeringForce;

    //加速度
    protected Vector3 acceleration;

    private float timer;


    protected void Start () {
        steeringForce = new Vector3(0, 0, 0);
        sqrMaxSpeed = maxSpeed * maxSpeed;
        timer = 0;
        //获得AI角色上的全部操控行为
        steerings = GetComponents<Steering>();
    }


    
    // Update is called once per frame
    void Update () {
        timer += Time.deltaTime;
        steeringForce = new Vector3(0, 0, 0);
        //力量检测时间一定间隔后才重新计算
        if (timer > computeInterval)
        {
            //AI最终被施加的力,就是各个力的权值相乘后的和
            foreach (var item in steerings)
            {
                if (item.enabled)
                {
                    steeringForce += item.Force() * item.weight;
                }
            }
            //ClampMagnitude方法返回一个Vector(maxForce,maxForce,maxForce)与steeringForce中更小的一个
            steeringForce = Vector3.ClampMagnitude(steeringForce, maxForce);
            //F = ma
            acceleration = steeringForce / mass;
            timer = 0;
        }       
    }
}
2.控制AI角色移动——AILocomotion类

真正控制AI角色的移动,计算每次移动的距离播放动画等

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//控制角色移动的类
public class AILocomotion : Vehicle {

    private CharacterController characterController;
    private Rigidbody theRigidbody;
    //每次移动的距离
    private Vector3 moveDistance;

    // Use this for initialization
    void Start () {
        characterController = GetComponent<CharacterController>();
        theRigidbody = GetComponent<Rigidbody>();
        moveDistance = new Vector3(0, 0, 0);
        //调用基类的Start(),对所需进行初始化
        base.Start();
    }

    //物理相关操作在FixedUpdate中进行
    private void FixedUpdate()
    {
        //计算速度
        velocity += acceleration * Time.fixedDeltaTime;
        //限制速度 velocity.sqrMagnitude 即为向量三个值的平方和
        if (velocity.sqrMagnitude > sqrMaxSpeed)
        {
            velocity = velocity.normalized * maxSpeed;
        }
        //计算位移
        moveDistance = velocity * Time.fixedDeltaTime;

        //如果要让AI在平面上移动,将y设置为0;
        if (isPlanar)
        {
            velocity.y = 0;
            moveDistance.y = 0;
        }

        //有角色控制器,直接传速度
        if (characterController != null)
        {
            characterController.SimpleMove(velocity);
        }
        //没有角色控制器和刚体
        //或有刚体但要由动力学方式控制
        else if (theRigidbody == null || theRigidbody.isKinematic)
        {
            transform.position += moveDistance;
        }
        //通过刚体控制
        else
        {
            theRigidbody.MovePosition(theRigidbody.position + moveDistance);
        }
        //更新朝向,如果速度大于一个阈值(防止抖动)
        if(velocity.sqrMagnitude > 0.0001)
        {

            //通过当前朝向和速度方向插值,计算新的朝向
            Vector3 newForward = Vector3.Lerp
                (transform.forward, velocity, damping * Time.fixedDeltaTime);
            //将y值设置为0
            if (isPlanar)
            {
                newForward.y = 0;
            }
            transform.forward = newForward;
        }

        //播放动画
        //gameObject.GetComponent<Animation>().Play("walk");

    }
}
3.各种操控行为的基类——Steering类

Steering类操控行为的基类,包括操控行为共有的变量和方法,操控AI角色的寻找、逃跑、躲避等都可由此类派生 此类为抽象类,每个子类有定义自己的权重,重写操控力的计算方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public abstract class Steering : MonoBehaviour {
    //操控力的权重
    public float weight = 1;
    //操控力的计算方法
    public virtual Vector3 Force()
    {
        return new Vector3(0, 0, 0);
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019.04.14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
游戏AI-个体AI角色的操控行为(1)
创建一个类SteeringForSeek继承Steering,将目标物体拖入Target,我们的AI就会自动向Target靠近。
祝你万事顺利
2019/05/28
5890
游戏AI-个体AI角色的操控行为(2)
我们希望场景中有随机移动的单位,如巡逻的士兵 吃草的牛羊,往往我们在场景中设置几个点让单位在几个点中随机移动,这样会出现一种情况,单位突然掉头,Craig Reynolds突出的随机徘徊解决了这个问题
祝你万事顺利
2019/05/28
7630
【Unity3D】官方自带人物控制器研究
5.0.0f4版本的官方自带资源包http://pan.baidu.com/s/1o8Ujrxo
恬静的小魔龙
2020/03/10
4.8K0
Unity 定点投射固定高度抛物线
假设同一平面中有AB两点,A点向B点水平射击,很容易想象子弹会沿由A指向B的向量方向前进,经过时间t后到达B点,若此时A点不再水平射击,改为以抛物线的方式向B点投射,同样需要在时间t后击中B点,那么如何确定被修正后的初速度呢。(这时就不得不提那万恶的游戏平衡性了Orz)
汐夜koshio
2021/03/02
1.2K0
Unity基础(22)-Navigation导航系统
同时设置为不阻碍行走-Walkable ,即可以在障碍物上行走。
孙寅
2020/06/02
1.4K0
Unity基础(22)-Navigation导航系统
【Unity】第一人称视角开发
我的需求是在Unity构建一个第一人称视角,实现移动跳跃功能。 主要参考的是这篇博文提供的方案,不过该方案为了只允许一次跳跃,单独在人物底部构建了一个空对象,我无需此限制,因此对其进行了简化。
zstar
2022/11/16
1.1K0
【Unity】第一人称视角开发
游戏AI-A*寻路(1)
基于单元格的导航图将地图划分为多个正方形单元或者六边形组成的规则网络,这种导航图易于理解和使用,结构相对简单,易于动态增加建筑物或者障碍等,适用于即时战略游戏或者塔防游戏,寻路以网格为单位,精准的寻路需要大量的节点,对内存要求比较高。另外在环境中包含的不同地形,也许需要通过额外信息进行存储,这也需要一定开销。
祝你万事顺利
2019/05/28
1.1K0
U2D【Move and Jump】
在Unity中使用Transform组件实现角色的平滑移动,可以通过以下步骤进行:
用户11315985
2024/10/16
4220
U2D【Move and Jump】
Unity 子弹生成系统
子弹系统和粒子系统比较类似,为了创建出五花八门的子弹,例如追踪,连续继承,散弹等,需要一个拥有众多参数的子弹生成器,这里叫它Shooter好了。
汐夜koshio
2020/03/19
2K0
【Unity】2D角色跳跃控制器
人物素材选用的是童年游戏《死神VS火影》中黑崎一护卍解形态,动作分帧图如下,进行扣绿处理后,可以导入到unity中进行自动切图。
zstar
2023/11/06
6880
【Unity】2D角色跳跃控制器
Unity基础(6)--资源管理(3)小赛车竞技
引言:今天突发奇想,想搞一个车的项目,话不多说,直接下载,但是之前对它一无所知。好在通过简单的测试,已经解决。运行效果还不错。上图是运行效果
孙寅
2020/06/02
8270
Unity动画☀️9. 木头自转、扛起木头、OnTriggerEnter
1️⃣ 导入木头Log,找回丢失的贴图,通过Perfab的Model—Scale Factor调节导入比例—0.3
星河造梦坊官方
2024/08/14
1710
Unity动画☀️9. 木头自转、扛起木头、OnTriggerEnter
“AS3.0高级动画编程”学习:第二章转向行为(上)
因为这一章的内容基本上都是涉及向量的,先来一个2D向量类:Vector2D.as (再次强烈建议不熟悉向量运算的童鞋,先回去恶补一下高等数学-07章空间解释几何与向量代数.pdf) package { import flash.display.Graphics; public class Vector2D { private var _x:Number; private var _y:Number; //构造函数 public function Vector2D(x:Number
菩提树下的杨过
2018/01/23
1.5K0
“AS3.0高级动画编程”学习:第二章转向行为(上)
面向小白!在Unity中实现最简单的人物移动脚本
网上关于角色移动的文章太多太多了,就我自己整理的时候都发现写了好多篇(因为有不同的方案),今天就将目前已知的移动角色的方案总结出来,毕竟是一个资源整合的时代,谁也不想找个角色移动的脚本都要找好几篇文章对吧
恬静的小魔龙
2022/08/07
2.7K0
面向小白!在Unity中实现最简单的人物移动脚本
VR开发--虚拟与现实游戏(VR-狩猎)
1、PC平台 2、资源(UI素材,粒子特效,动画等) 3、导入SteamVR 4、那个运行HTC Vive设备最少970显卡
孙寅
2020/06/02
7690
【Unity】万有引力和轨道计算(1)
首先要让星体之间能相互吸引,互相施加一个万有引力。这个我实现起来就很粗暴了,直接用过刚体施加一个力:
HkingAuditore
2023/10/26
3930
【Unity】万有引力和轨道计算(1)
Unity动画☀️8. 添加角色控制器、Curves、添加滑动
添加角色控制器Character Controller后,人物不会因动画问题而导致Y轴变化,人物会始终位于水平地面上
星河造梦坊官方
2024/08/14
2230
Unity动画☀️8. 添加角色控制器、Curves、添加滑动
MMORPG游戏开发实战(一)
新建目录工程 关于工程的文件夹创建 代码注释修改 可以百度,这种代码不需要记忆。一大堆,直接用就可以 using System; using System.Collections; using System.IO; using UnityEngine; using UnityEditor; public class ScriptsCreat : UnityEditor.AssetModificationProcessor { public static void OnWillCreateAss
孙寅
2020/06/02
1K0
MMORPG游戏开发实战(一)
Unity-BattleStar丨8. 物理引擎Rigidbody组件、Collider组件、Raycast
游戏中物理引擎用于模拟真实世界物理环境效果,要实现游戏对象的物理行为,Rigidbody(刚体)组件是必不可少的,当挂载该组件之后,物体立刻受到重力等物理效果影响。如果对象身上还挂载着Collider(碰撞)组件,那么该对象还受到碰撞物理效果影响,例如游戏中的被车撞飞
星河造梦坊官方
2024/08/14
3700
Unity-BattleStar丨8. 物理引擎Rigidbody组件、Collider组件、Raycast
Unity3D--项目:CS局域网之战(二)
我们除了扔进头部中,还可以扔进骨骼头部,保持相对位置,然后通过弯腰等骨骼动画来达到相机跟随
孙寅
2020/06/02
1.1K0
相关推荐
游戏AI-个体AI角色的操控行为(1)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档