1. 首先是人物的挂载文件
// 定义变量
private IBattleCharacterContainer AttackTargetInfo = null; // 攻击目标信息集合
public Transform AttackTargetTrans = null; // 攻击目标transform
private Vector2 MoveDistance = new Vector2 (4, 6); //攻击后向后的移动距离
private Vector2 MoveDirLeft = new Vector2 (-70, -30); // 攻击后相对目标的移动角度
private Vector2 MoveDirRigh = new Vector2 (30, 70); // 攻击后相对目标的移动角度
bool moveFlag = false; // 是否移动控制变量
float m_refcomSmoothTime = 0.8f; // 移动所需要的时间
Vector3 m_refFix = Vector3.zero;
Vector3 moveToPos = Vector3.zero; // 计算后的移动位置
// 对外接口1 攻击目标的设定
public void SetTargetInfo(IBattleCharacterContainer target)
{
this.AttackTargetInfo = target;
this.AttackTargetTrans = target.Controller.transform;
}
// 攻击后移动的位置设置
void setMosterMoveTo ()
{
float angle = UnityEngine.Random.Range(1, 3)== 1 ? UnityEngine.Random.Range (MoveDirLeft.x, MoveDirLeft.y) :
UnityEngine.Random.Range (MoveDirRigh.x, MoveDirRigh.y);
float distance = Math.Abs(angle) * MoveDistance.y / MoveDirRigh.y;
transform.LookAt (AttackTargetTrans);
Quaternion r0= Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y + angle, transform.rotation.eulerAngles.z);
Vector3 movePos = (transform.position + (r0 * Vector3.forward) * distance);
moveFlag = true;
moveToPos = movePos;
}
// 攻击后移动的位置移动
void setMovetoPos ()
{
transform.position = Vector3.SmoothDamp(transform.position, moveToPos, ref m_refFix, m_refcomSmoothTime);
transform.LookAt (AttackTargetTrans);
m_refcomSmoothTime -= Time.deltaTime;
if(m_refcomSmoothTime <= 0)
{
m_refcomSmoothTime = 0.8f;
transform.position = moveToPos;
moveFlag = false;
}
}
3. Update 中人物正常移动的AI
private bool isMoving;
public void Update()
{
float step = motionSpeed * Time.deltaTime;
var motionDir = LookTarget - transform.position;
if(motionDir.magnitude > Mathf.Epsilon)
{
var lookTowards = Quaternion.LookRotation(motionDir);
transform.rotation = Quaternion.Slerp(transform.rotation, lookTowards, step);
}
if (CanMove)
{
if(AttackTargetTrans != null)
{
if(AttackTargetInfo.CharacterVariableData.Hp <= 0)
{
moveFlag = false;
AttackTargetTrans = null;
return;
}
else if(moveFlag == false && Vector3.Distance(transform.position, AttackTargetTrans.position) <= 5)
{
setMosterMoveTo();
return;
}
else if(moveFlag == true)
{
setMovetoPos();
return;
}
}
var newPos = Vector3.MoveTowards(transform.position, Target, step);
transform.position = new Vector3(newPos.x, transform.position.y, newPos.z);
var d = Vector3.Distance(newPos, Target);
if (d <= 1.0f && isMoving)
{
isMoving = false;
OnReachedMoveTarget(EventArgs.Empty);
}
}
}
Event ·登录
public event EventHandler ReachedMoveTarget;
protected virtual void OnReachedMoveTarget(EventArgs e)
{
var handler = ReachedMoveTarget;
if (handler != null)
handler(this, e);
}
控制移动
Controller.ReachedMoveTarget += characterController_ReachedMoveTarget;
private bool isNavigationStopped;
private void characterController_ReachedMoveTarget(object sender, EventArgs e)
{
if (rail == null || isNavigationStopped)
{
Controller.Idle();
return;
}
MoveOn();
}
private const float minRandomRadius = 2.0f;
private const float maxRandomRadius = 5.0f;
private void MoveOn()
{
if (rail == null)
return;
if (currentRailNodeIndex >= rail.Length - 1)
return;
currentRailNodeIndex++;
var pos = rail[currentRailNodeIndex];
var randomAngle = UnityEngine.Random.Range(0.0f, Mathf.PI * 2.0f);
var randomRadius = UnityEngine.Random.Range(minRandomRadius, maxRandomRadius);
var offsetX = Mathf.Cos(randomAngle) * randomRadius;
var offsetZ = Mathf.Sin(randomAngle) * randomRadius;
Controller.SetTarget(new Vector3(pos.x + offsetX, groundPosition, pos.z + offsetZ));
}
public void SetTarget(Vector3 target)
{
Target = target;
LookTarget = target;
isMoving = true;
}