练手小游戏(代码篇之敌人AI
Posted Sooda
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了练手小游戏(代码篇之敌人AI相关的知识,希望对你有一定的参考价值。
诶呀~又没有更新微博,去拔牙了,疼死了,休息了几天过来接着写代码~
首先是Base。写了一个框架,照别人扒的。
Base分三部分,AILocomotion(AI移动),Steering(行为基类),Vehicle(角色模型基类)
首先是Steering
/// <summary> /// 角色行为基类 /// </summary> public class Steering : MonoBehaviour { /// <summary> /// 操控权重 /// </summary> public float weight = 1; void Start () { } void Update () { } /// <summary> /// 计算操控力。由子类去实现 /// </summary> /// <returns></returns> public virtual Vector3 Force() { return Vector3.zero; } }
其次是角色行为基类
/// <summary> /// 角色模型基类 /// </summary> public class Vehicle : MonoBehaviour { /// <summary> /// 行为列表 /// </summary> private Steering[] steerings; /// <summary> /// 操控力 /// </summary> private Vector3 steeringForce; /// <summary> /// 最大的力 /// </summary> public float maxForce; /// <summary> /// 角色质量 /// </summary> private float mass = 1; /// <summary> /// 加速度 /// </summary> protected Vector3 acceleration; /// <summary> ///控制力计算间隔时间 /// </summary> private float computeInterval = 0.2f; /// <summary> /// 计时器 /// </summary> private float timer; /// <summary> /// 位移速度 /// </summary> public Vector3 speed; /// <summary> /// 最大速度 /// </summary> public float maxSpeed = 10; /// <summary> /// 最大速度的平方 /// </summary> public float sqrtMaxSpeed; /// <summary> /// 转向速度 /// </summary> public float damping = 0.9f; /// <summary> /// 是否是平面 /// </summary> public bool isPanar = false; protected void Start () { steeringForce = Vector3.zero; timer = 0; steerings = GetComponents<Steering>(); sqrtMaxSpeed = maxSpeed * maxSpeed; } void Update () { //每过computeInterval的时间就处理一下当前所有行为力的合力 timer += Time.deltaTime; steeringForce = Vector3.zero; if (timer > computeInterval) { foreach (Steering s in steerings) { if (s.enabled) { steeringForce += s.Force() * s.weight; } } steeringForce = Vector3.ClampMagnitude(steeringForce, maxForce); acceleration = steeringForce / mass; //加速度 = 力 / 质量 timer = 0; } } }
最后是AI移动类
/// <summary> /// 角色移动类 /// </summary> public class AILcomotion : Vehicle { /// <summary> /// AI角色控制器 /// </summary> private CharacterController mController; private Rigidbody mRigidbody; /// <summary> /// 每次移动的距离 /// </summary> private Vector3 mMoveDistance; void Start () { mController = GetComponent<CharacterController>(); mRigidbody = GetComponent<Rigidbody>(); mMoveDistance = Vector3.zero; base.Start(); } void FixedUpdate () { speed = speed + acceleration * Time.fixedDeltaTime; if (speed.sqrMagnitude > sqrtMaxSpeed) { speed = speed.normalized * maxSpeed; //float 转 Vector3 } //计算角色移动距离 mMoveDistance = speed * Time.fixedDeltaTime; if (isPanar) { speed.y = 0; } if (mController) { mController.SimpleMove(speed); } else if (mRigidbody == null || mRigidbody.isKinematic) //如果Rigidbody为空或受物理影响修改位置 { transform.position += mMoveDistance; } else { mRigidbody.MovePosition(mRigidbody.position + mMoveDistance); } if (speed.sqrMagnitude > 0.0001f) { Vector3 newForward = Vector3.Slerp(transform.forward, speed, damping * Time.fixedDeltaTime); if (isPanar) { newForward.y = 0; } transform.forward = newForward; } } }
之后就是各个行为的实现比如一个抵达行为
/// <summary> /// 抵达 /// </summary> public class Arrive : Steering { /// <summary> /// 靠近的目标 /// </summary> public GameObject target; /// <summary> /// 减速半径 /// </summary> public float slowDownDistance; /// <summary> /// 预期速度 /// </summary> private Vector3 mDesiredVelocity; /// <summary> /// AI角色 /// </summary> private Vehicle mVehicle; void Start() { mVehicle = GetComponent<Vehicle>(); } public override Vector3 Force() { //与目标之间的距离 Vector3 toTarget = target.transform.position - transform.position; if (mVehicle.isPanar) { toTarget.y = 0; } if (toTarget.magnitude < slowDownDistance) { //计算预期速度 mDesiredVelocity = toTarget - mVehicle.speed; } else { //计算预期速度 mDesiredVelocity = toTarget.normalized * mVehicle.maxSpeed; } if (mVehicle.isPanar) { mDesiredVelocity.y = 0; } //返回操控向量 return (mDesiredVelocity - mVehicle.speed); } }
目前还没有学习行为树的写法,目前就是把各个行为都放到角色上运行,有点臃肿。
以上是关于练手小游戏(代码篇之敌人AI的主要内容,如果未能解决你的问题,请参考以下文章