诶呀~又没有更新微博,去拔牙了,疼死了,休息了几天过来接着写代码~
首先是Base。写了一个框架,照别人扒的。
Base分三部分,AILocomotion(AI移动),Steering(行为基类),Vehicle(角色模型基类)
首先是Steering
////// 角色行为基类/// public class Steering : MonoBehaviour { ////// 操控权重 /// public float weight = 1; void Start () { } void Update () { } ////// 计算操控力。由子类去实现 /// ///public virtual Vector3 Force() { return Vector3.zero; }}
其次是角色行为基类
////// 角色模型基类/// public class Vehicle : MonoBehaviour { ////// 行为列表 /// private Steering[] steerings; ////// 操控力 /// private Vector3 steeringForce; ////// 最大的力 /// public float maxForce; ////// 角色质量 /// private float mass = 1; ////// 加速度 /// protected Vector3 acceleration; //////控制力计算间隔时间 /// private float computeInterval = 0.2f; ////// 计时器 /// private float timer; ////// 位移速度 /// public Vector3 speed; ////// 最大速度 /// public float maxSpeed = 10; ////// 最大速度的平方 /// public float sqrtMaxSpeed; ////// 转向速度 /// public float damping = 0.9f; ////// 是否是平面 /// public bool isPanar = false; protected void Start () { steeringForce = Vector3.zero; timer = 0; steerings = GetComponents(); 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移动类
////// 角色移动类/// public class AILcomotion : Vehicle { ////// AI角色控制器 /// private CharacterController mController; private Rigidbody mRigidbody; ////// 每次移动的距离 /// private Vector3 mMoveDistance; void Start () { mController = GetComponent(); mRigidbody = GetComponent (); 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; } }}
之后就是各个行为的实现比如一个抵达行为
////// 抵达/// public class Arrive : Steering { ////// 靠近的目标 /// public GameObject target; ////// 减速半径 /// public float slowDownDistance; ////// 预期速度 /// private Vector3 mDesiredVelocity; ////// AI角色 /// private Vehicle mVehicle; void Start() { mVehicle = GetComponent(); } 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); }}
目前还没有学习行为树的写法,目前就是把各个行为都放到角色上运行,有点臃肿。