UnityAI——个体AI角色的操控行为脚本(一)

简介: UnityAI——个体AI角色的操控行为脚本

注:本文用到了前文所用的基类UnityAI——操控行为编程的主要基类-CSDN博客

在一些游戏中,可能会遇到想让AI角色追逐或者避开玩家的情况。

如在飞机模拟游戏中,让导弹跟踪和进攻玩家或玩家的飞行器。这种情况下,可以运用本节介绍的技术。

一、靠近

操控行为中的靠近是指,指定一个目标位置,根据当前的运动速度向量,返回一个操控AI角色到达该目标位置的"操控力",使AI角色自动向该位置移动。

要想让AI角色靠近目标,首先要计算出AI角色在理想情况下到达目标位置的预期速度。该预期速度可看作是从AI角色的当前位置到目标位置的向量。操控向量是预期速度与AI角色当前速度的差,该向量大小随着当前位置的变化而变化,从而形成角色的寻找路径。

由于操控行为是基于力和速度的,速度不会突变,因此,如果角色一直采取靠近行为,那么最终它将会从目标穿过,然后再重新接近目标,如此往复。

当然,如果目标物体包含一个碰撞体,那么,接下来的行为就要由Character Controller决定了。如果不希望出现这种情况,可以采用后面介绍的Arrive行为,也可以另外添加一些处理步骤。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SteeringForSeek : Steering
{
    public GameObject target;
    private Vector3 desiredVelocity;//预期速度
    private Vehicle m_vehicle;//获得被操控的AI角色
    private float maxSpeed;
    private bool isPlanar;
    void Start()
    {
        m_vehicle = GetComponent<Vehicle>();
        maxSpeed = m_vehicle.maxSpeed;
        isPlanar = m_vehicle.isPlanar;  
    }
    public override Vector3 Force()
    {
        desiredVelocity = (target.transform.position - transform.position).normalized * maxSpeed;
        if (isPlanar)
            desiredVelocity.y = 0;
        return (desiredVelocity - m_vehicle.velocity);
    }
}

二、离开

离开和靠近行为正好相反,它会产生一个操控AI角色离开目标的力,而不是靠近目标的力。它们之间唯一的区别是DeisredVelocity具有相反的方向。

接着,还可以进一步调整,只有当AI角色进入目标周围一定范围内时,才产生离开的力,这样可以模拟出AI角色的有限感知范围

这里采用了Vector3.Distance函数来计算当前位置与目标位置之间的距离。事实上,如果采用Vector3.sqrMagnitude函数,将会得到更快的计算速度,因为省去了计算平方根的时间,这时可以预先计算fearDistance的平方并存储到一个变量中。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SteeringForFlee : Steering
{
    public GameObject target;
    public float fearDistance = 20;
    private Vector3 desiredVelocity;//预期速度
    private Vehicle m_vehicle;//获得被操控的AI角色
    private float maxSpeed;
    void Start()
    {
        m_vehicle = GetComponent<Vehicle>();
        maxSpeed = m_vehicle.maxSpeed;
    }
    public override Vector3 Force()
    {
        Vector3 temPos = new Vector3(transform.position.x, 0, transform.position.z);
        Vector3 temTargetPos = new Vector3(target.transform.position.x, 0, target.transform.position.z);
        if (Vector3.Distance(temPos, temTargetPos) > fearDistance)
            return new Vector3(0, 0, 0);
        desiredVelocity = (transform.position - target.transform.position).normalized * maxSpeed;
        return (desiredVelocity-m_vehicle.velocity);
    }
}

三、抵达

有时我们希望AI角色能够减速并停到目标位置,避免冲过目标,例如,车辆在接近十字路口时逐渐减速,然后停在路口处,这时就需要用到抵达行为。

在角色距离目标较远时,抵达与靠近行为的状态是一样的,但是接近目标时,不再是全速向目标移动,而代之以使AI角色减速,知道最终恰好停在目标位置。何时开始减速是通过参数进行设置的,这个参数可以看成是停止半径。当角色在停止半径之外时,以最大速度移动;当角色在停止半径之内时,逐渐减小预期速度,直到减小为0.这个参数的设置很关键,它决定了抵达行为的最终效果。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SteeringForArrive : Steering
{
    public bool isPlanar = true;
    public float arrivalDistance = 0.3f;
    public float characterRadius = 1.2f;
    public float slowDownDistance;
    public GameObject target;
    private Vector3 desiredVelocity;//预期速度
    private Vehicle m_vehicle;//获得被操控的AI角色
    private float maxSpeed;
    void Start()
    {
        m_vehicle = GetComponent<Vehicle>();
        maxSpeed = m_vehicle.maxSpeed;
        isPlanar = m_vehicle.isPlanar;
    }
    public override Vector3 Force()
    {
        Vector3 toTarget = target.transform.position - transform.position;
        Vector3 desiredVelocity;
        Vector3 returnForce;
        if (isPlanar)
            toTarget.y = 0;
        float distance = toTarget.magnitude;
        if (distance > slowDownDistance)
        {
            desiredVelocity = toTarget.normalized * maxSpeed;
            returnForce = desiredVelocity - m_vehicle.velocity;
        }
        else
        {
            desiredVelocity = toTarget - m_vehicle.velocity;
            returnForce = desiredVelocity - m_vehicle.velocity;
        }
        return returnForce;
    }
    void OnDrawGizmos()
    {
        Gizmos.DrawWireSphere(target.transform.position, slowDownDistance);
    }
}

四、追逐

追逐行为与靠近行为很相似,只不过目标不再是静止不动,而是另一个可移动的角色。最简单的追逃方式是直接向目标的当前位置靠近,不过这样看上去很不真实。举例来说,众所周知,当动物追猎物时,不是直接向猎物当前的位置奔跑,而是要预判,朝着其未来位置的方向追去,这样才能在最短时间内追上猎物。在AI中,把这种操控行为称为"追逐"。

如何实现这种智能的追逐行为呢?我们可以使用一个简单的预测器,在每一帧重新计算它的值。

假设采用一个线性预测器,有假设在预测时间间隔T时间内角色不会转向,角色经过时间T后的未来位置可以用当前速度乘以T来确定,然后把得到的值加到角色当前位置上,就得到未来位置了。最后,再以预测位置作为目标,应用靠近行为就可以了。

实现追逐行为的一个关键是如何确定T。可以把它设置为一个常数,也可以当追逐者距离目标较远时设为较大的值,而接近目标时设为较小的值。

这里,设定预测时间和追逐者与逃避者之间的距离成正比,与二者的速度成正比。

一些情况下,追逐可能会提前结束。例如:逃避者在前面,几乎面对追逐者,那么追逐者应该直接向逃避者的当前位置移动。二者之间的关系可以通过计算逃避者朝向向量与AI角色朝向向量的点积得到,在下面的代码中,逃避者朝向的反向和AI角色的朝向必须大约在20度范围之内,才可以被认为是面对着的。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SteeringForPersuit : Steering
{
    public GameObject target;
    private Vector3 desiredVelocity;//预期速度
    private Vehicle m_vehicle;//获得被操控的AI角色
    private float maxSpeed;
    void Start()
    {
        m_vehicle = GetComponent<Vehicle>();
        maxSpeed = m_vehicle.maxSpeed;
    }
    public override Vector3 Force()
    {
        Vector3 toTarget = target.transform.position - transform.position;
        float relativeDirection = Vector3.Dot(transform.forward, target.transform.forward);//计算追逐者的前方与逃避者前方之间的夹角
        if (Vector3.Dot(toTarget, transform.forward) > 0 && relativeDirection < -0.95f)//夹角大于0且追逐者基本面对着逃避者
        {
            desiredVelocity=(target.transform.position - transform.position).normalized*maxSpeed;
            return (desiredVelocity - m_vehicle.velocity);     
        }
        float lookaheadTime = toTarget.magnitude / (maxSpeed + target.GetComponent<Vehicle>().velocity.magnitude);//计算预测时间,正比于距离,反比于速度和
        desiredVelocity = (target.transform.position + target.GetComponent<Vehicle>().velocity * lookaheadTime - transform.position).normalized * maxSpeed;
        return(desiredVelocity - m_vehicle.velocity);
    }
}


相关文章
|
2月前
|
机器学习/深度学习 人工智能 监控
面向智慧牧场的牛行为识别数据集(5000张图片已划分、已标注) | AI训练适用于目标检测任务
本数据集包含5000张已标注牛行为图片,涵盖卧、站立、行走三类,适用于YOLO等目标检测模型训练。数据划分清晰,标注规范,场景多样,助力智慧牧场、健康监测与AI科研。
面向智慧牧场的牛行为识别数据集(5000张图片已划分、已标注) | AI训练适用于目标检测任务
|
8月前
|
人工智能 搜索推荐
「社会实验室」成真!SocioVerse:复旦联合小红书开源社会模拟世界模型,用AI预演群体行为
SocioVerse是由复旦大学联合小红书等机构开源的社会模拟框架,基于大语言模型和千万级真实用户数据构建,能精准模拟群体行为并预测社会事件演化趋势。
553 2
「社会实验室」成真!SocioVerse:复旦联合小红书开源社会模拟世界模型,用AI预演群体行为
|
3月前
|
Web App开发 人工智能 自然语言处理
快速掌握Dify+Chrome MCP:打造网页操控AI助手
本文教你如何快速搭建一个能操作浏览器的AI助手:通过Dify和Chrome MCP结合,只需三步配置,即可实现自动填表、数据抓取和网页操控,无需编写代码,用自然语言就能指挥AI完成各类网页任务。
|
5月前
|
机器学习/深度学习 人工智能 算法
深度强化学习在异构环境中AI Agent行为泛化能力研究
随着人工智能技术的迅猛发展,AI Agent 在游戏、智能制造、自动驾驶等场景中已逐步展现出强大的自适应能力。特别是深度强化学习(Deep Reinforcement Learning, DRL)的引入,使得智能体能够通过与环境的交互,自动学习最优的行为策略。本文将系统性地探讨基于深度强化学习的AI Agent行为决策机制,并结合代码实战加以说明。
深度强化学习在异构环境中AI Agent行为泛化能力研究
|
5月前
|
消息中间件 人工智能 机器人
vx自动回复机器人,ai自动回复机器人,微信自动回复脚本插件
这个微信自动回复机器人包含主程序、配置管理、工具函数和单元测试模块。主程序使用itchat库实现微信登录和消息处理
|
7月前
|
人工智能 算法 自动驾驶
AI和大数据:是工具,还是操控人心的“隐形之手”?
AI和大数据:是工具,还是操控人心的“隐形之手”?
175 1
|
10月前
|
人工智能 自然语言处理 API
Cline:29.7K Star!一文详解VSCode最强开源AI编程搭子:一键生成代码+自动跑终端+操控浏览器...
Cline 是一款集成于 VSCode 的 AI 编程助手,支持多语言模型,实时检查语法错误,帮助开发者提高编程效率。通过智能化手段,Cline 可以生成代码、执行终端命令、调试 Web 应用,并扩展更多功能。
3396 73
|
8月前
|
机器学习/深度学习 人工智能 自然语言处理
这个模型让AI角色会说话还会演!MoCha:Meta联手滑铁卢大学打造对话角色视频生成黑科技
MoCha是由Meta与滑铁卢大学联合开发的端到端对话角色视频生成模型,通过创新的语音-视频窗口注意力机制实现精准的唇语同步和全身动作生成。
425 12
这个模型让AI角色会说话还会演!MoCha:Meta联手滑铁卢大学打造对话角色视频生成黑科技
|
8月前
|
人工智能 JSON 自然语言处理
让AI听懂你的建模需求!BlenderMCP:自然语言指令直接操控 Blender,一句话生成复杂3D场景
BlenderMCP通过MCP协议实现Blender与Claude AI的无缝集成,支持通过自然语言指令完成3D建模、材质调整等复杂操作,显著提升创作效率。
919 1
让AI听懂你的建模需求!BlenderMCP:自然语言指令直接操控 Blender,一句话生成复杂3D场景
|
9月前
|
机器学习/深度学习 人工智能 自然语言处理
AI赋能教育评价改革:生成式人工智能(GAI)认证的角色与影响
本文探讨了人工智能(AI)技术在教育评价改革中的作用及生成式人工智能(GAI)认证的影响。随着数字化时代的到来,AI为教育评价提供了新工具与手段,能够优化评价过程、提升质量并促进个性化发展。GAI认证不仅提升了教育工作者的技能与竞争力,还推动了教育评价的标准化与规范化。文章强调需加强AI技术应用研究、推广GAI认证,并注重评价的个性化与差异化,以助力学生全面发展。AI赋能教育评价改革是未来趋势,将为教育事业注入更多智慧与力量。

热门文章

最新文章