feat(assets): 更新蓝色怪物模型导入设置并优化动画配置 - 升级模型导入器版本从2200到22361 - 添加ACL动画压缩配置参数,提升动画性能 - 调整动画循环设置,将loopTime设为1启用循环播放 - 增加虚拟几何体相关配置选项 fix(enemy): 修复敌人AI行为逻辑错误 - 修正敌人在攻击状态下仍会移动的问题 - 改进敌人追踪和巡逻状态转换逻辑 - 修复敌人转向时Y轴旋转导致的异常朝向 - 优化巡逻路径计算,改为水平面内随机移动 - 解决敌人在目标点附近抖动的问题 chore(dependencies): 更新Codely桥接包版本 - 将cn.tuanjie.codely.bridge从1.0.74升级至1.0.75 - 调整依赖包在manifest中的顺序 style(scene): 为场景对象添加物理材质和渲染属性 - 为CharacterController组件分配新的物理材质 - 在多个MeshRenderer组件中添加虚拟几何体和遮挡剔除相关属性 - 配置渲染器遮罩交互参数 config(build): 启用SampleScene场景构建 - 将SampleScene.scene添加到构建设置中 - 设置场景为启用状态以便打包构建 ```
189 lines
4.7 KiB
C#
189 lines
4.7 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
public class NewBehaviourScript : MonoBehaviour
|
|
{
|
|
|
|
//移动速度
|
|
public float speed = 5f;
|
|
|
|
//活动范围
|
|
public float range = 500f;
|
|
|
|
//侦查范围
|
|
public float detectRange = 200f;
|
|
|
|
//攻击范围
|
|
public float attackRange = 5f;
|
|
|
|
//角色状态
|
|
private State state = State.Alert;
|
|
|
|
//攻击目标
|
|
public GameObject target;
|
|
|
|
//当前目标点
|
|
private Vector3 targetPos;
|
|
|
|
//初始位置坐标
|
|
private Vector3 startPos;
|
|
|
|
//动画控制器
|
|
private Animator animator;
|
|
|
|
// 角色控制器
|
|
private CharacterController controller;
|
|
|
|
//状态枚举
|
|
public enum State
|
|
{
|
|
//警戒巡逻
|
|
Alert,
|
|
|
|
//追踪状态
|
|
Track,
|
|
|
|
//攻击状态
|
|
Attack
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Start is called before the first frame update
|
|
void Start()
|
|
{
|
|
//初始化
|
|
animator = GetComponent<Animator>();
|
|
controller = GetComponent<CharacterController>();
|
|
//记录初始坐标
|
|
startPos = transform.position;
|
|
randomTargetPos();
|
|
}
|
|
|
|
|
|
|
|
// Update is called once per frame
|
|
void Update()
|
|
{
|
|
//攻击状态直接返回
|
|
if (state == State.Attack)
|
|
{
|
|
animator.SetInteger("speed", 0);
|
|
return;
|
|
}
|
|
|
|
//获取侦查范围内除自己以外的Player层的单位
|
|
var players = Physics.OverlapSphere(transform.position, detectRange, LayerMask.GetMask("Player"));
|
|
//如果存在单位
|
|
if (players.Length > 0)
|
|
{
|
|
//找出标签是Friend的,并且不是自己
|
|
foreach (var player in players)
|
|
{
|
|
if (player.tag == "Friend" && player != gameObject)
|
|
{
|
|
//进入追逐状态
|
|
state = State.Track;
|
|
float dis = Vector3.Distance(transform.position, player.transform.position);
|
|
//和目标的距离在攻击范围外则朝目标移动
|
|
if (dis > attackRange)
|
|
{
|
|
move(player.transform.position - transform.position);
|
|
//打印动画speed的值
|
|
Debug.Log(animator.GetInteger("speed"));
|
|
}
|
|
else
|
|
{
|
|
attack(player);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (state == State.Track)
|
|
{
|
|
state = State.Alert;
|
|
}
|
|
|
|
//没有侦查到敌人则回到巡逻
|
|
state = State.Alert;
|
|
//角色在攻击状态则返回
|
|
if (state == State.Alert)
|
|
{
|
|
//移动
|
|
move(targetPos - transform.position);
|
|
//到达目标点时候随机目标点,只判断水平距离
|
|
Vector3 patrolOffset = transform.position - targetPos;
|
|
patrolOffset.y = 0;
|
|
if (patrolOffset.sqrMagnitude < 0.01f)
|
|
{
|
|
randomTargetPos();
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
//攻击
|
|
private void attack(Collider player)
|
|
{
|
|
//转向攻击目标
|
|
var direction = player.transform.position - transform.position;
|
|
direction.y = 0;
|
|
if (direction != Vector3.zero)
|
|
{
|
|
transform.rotation = Quaternion.LookRotation(direction, Vector3.up);
|
|
}
|
|
//攻击动画动作
|
|
animator.SetInteger("speed", 0);
|
|
animator.SetTrigger("attack");
|
|
state = State.Attack;
|
|
}
|
|
|
|
|
|
// 在 Animator 的 Attack 动画结束时调用此方法
|
|
public void OnAttackAnimationEnd()
|
|
{
|
|
//打印
|
|
Debug.Log("攻击结束");
|
|
state = State.Alert;
|
|
randomTargetPos();
|
|
}
|
|
|
|
|
|
|
|
//角色移动,持续到目标点
|
|
void move(Vector3 movement)
|
|
{
|
|
movement.y = 0;
|
|
if (movement == Vector3.zero)
|
|
{
|
|
animator.SetInteger("speed", 0);
|
|
return;
|
|
}
|
|
|
|
//改变动画控制器的参数
|
|
animator.SetInteger("speed", 1);
|
|
//向目标点移动
|
|
controller.Move(movement.normalized * Time.deltaTime * speed);
|
|
//改变角色朝向目标点,只改变y轴
|
|
transform.rotation = Quaternion.LookRotation(movement, Vector3.up);
|
|
transform.rotation = Quaternion.Euler(0, transform.rotation.eulerAngles.y, 0);
|
|
}
|
|
|
|
|
|
//随机目标点
|
|
private void randomTargetPos()
|
|
{
|
|
//以startPos为中心,在水平圆形范围内随机一个点
|
|
Vector2 randomOffset = Random.insideUnitCircle * range;
|
|
targetPos = startPos + new Vector3(randomOffset.x, 0, randomOffset.y);
|
|
}
|
|
}
|
|
|