386 lines
12 KiB
C#
386 lines
12 KiB
C#
|
||
using BehaviorDesigner.Runtime;
|
||
using BehaviorDesigner.Runtime.Tasks;
|
||
using DragonLi.Core;
|
||
using UnityEngine;
|
||
|
||
public class Actions
|
||
{
|
||
public class SetEnemyState : Action
|
||
{
|
||
public SharedInt state;
|
||
|
||
public override TaskStatus OnUpdate()
|
||
{
|
||
Enemy enemy = transform.GetComponent<Enemy>();
|
||
if (enemy == null) return TaskStatus.Failure;
|
||
enemy.ChangeState((EnemyState)state.Value);
|
||
return TaskStatus.Success;
|
||
}
|
||
}
|
||
|
||
public class SetPlayerAiState : Action
|
||
{
|
||
public SharedInt state;
|
||
|
||
public override TaskStatus OnUpdate()
|
||
{
|
||
PlayerAI playerAi = transform.GetComponent<PlayerAI>();
|
||
if (playerAi == null) return TaskStatus.Failure;
|
||
playerAi.ChangeState((PlayerAIState)state.Value);
|
||
return TaskStatus.Success;
|
||
}
|
||
}
|
||
|
||
public class SetEnemyDestination : Action
|
||
{
|
||
public SharedVector3 targetPos;
|
||
|
||
public override TaskStatus OnUpdate()
|
||
{
|
||
Enemy enemy = transform.GetComponent<Enemy>();
|
||
if (enemy == null) return TaskStatus.Failure;
|
||
enemy.ai.isStopped = false;
|
||
enemy.ai.destination = targetPos.Value;
|
||
return TaskStatus.Success;
|
||
}
|
||
}
|
||
|
||
public class SetEnemyDestination2 : Action
|
||
{
|
||
public SharedGameObject target;
|
||
|
||
public override TaskStatus OnUpdate()
|
||
{
|
||
Enemy enemy = transform.GetComponent<Enemy>();
|
||
if (enemy == null) return TaskStatus.Failure;
|
||
enemy.ai.isStopped = false;
|
||
enemy.ai.destination = target.Value.transform.position;
|
||
return TaskStatus.Success;
|
||
}
|
||
}
|
||
|
||
public class PlayerAIMoveForward : Action
|
||
{
|
||
public SharedGameObject TargetObj;
|
||
public override TaskStatus OnUpdate()
|
||
{
|
||
PlayerAI playerAi = transform.GetComponent<PlayerAI>();
|
||
if (playerAi == null) return TaskStatus.Failure;
|
||
playerAi.ai.isStopped = false;
|
||
playerAi.ai.destination = TargetObj.Value.transform.position;
|
||
if (playerAi.ai.destination == TargetObj.Value.transform.position)
|
||
{
|
||
return TaskStatus.Success;
|
||
}
|
||
return TaskStatus.Running;
|
||
}
|
||
}
|
||
|
||
public class PlayerAIMoveTarget : Action
|
||
{
|
||
public SharedGameObject TargetObj;
|
||
public override void OnStart()
|
||
{
|
||
base.OnStart();
|
||
}
|
||
|
||
public override TaskStatus OnUpdate()
|
||
{
|
||
PlayerAI playerAi = transform.GetComponent<PlayerAI>();
|
||
if (playerAi == null) return TaskStatus.Failure;
|
||
//if(playerAi.target==null) return TaskStatus.Failure;
|
||
playerAi.ai.isStopped = false;
|
||
playerAi.target = TargetObj.Value;
|
||
GameObject target = playerAi.target;
|
||
playerAi.ai.destination = target==null? GameLocal.Ins.pkPos.position : target.transform.position;
|
||
if(target==null)
|
||
return TaskStatus.Failure;
|
||
// 计算目标距离
|
||
float distance = Vector3.Distance(transform.position, target.transform.position);
|
||
if (distance <= 4f)
|
||
{
|
||
playerAi.ai.isStopped = true;
|
||
return TaskStatus.Success;
|
||
}
|
||
return TaskStatus.Running;
|
||
}
|
||
}
|
||
|
||
public class EnemyMoveTarget : Action
|
||
{
|
||
public SharedGameObject TargetObj;
|
||
public SharedVector3 TargetPos;
|
||
public override TaskStatus OnUpdate()
|
||
{
|
||
Enemy playerAi = transform.GetComponent<Enemy>();
|
||
if (playerAi == null) return TaskStatus.Failure;
|
||
playerAi.ai.isStopped = false;
|
||
Vector3 targetPos=TargetObj.Value==null? TargetPos.Value:TargetObj.Value.transform.position;
|
||
if (TargetObj.Value == null)
|
||
{
|
||
GameObject target = GameManager.Ins.GetPlayerAi(transform);
|
||
if (target != null)
|
||
{
|
||
TargetObj.Value = target;
|
||
targetPos=target.transform.position;
|
||
}
|
||
}
|
||
playerAi.ai.destination=targetPos;
|
||
// 计算目标距离
|
||
float distance = Vector3.Distance(transform.position, targetPos);
|
||
if (distance <= 4f)
|
||
{
|
||
playerAi.ai.isStopped = true;
|
||
return TaskStatus.Success;
|
||
}
|
||
return TaskStatus.Running;
|
||
}
|
||
}
|
||
|
||
public class EnemyMoveToward : Action
|
||
{
|
||
public SharedVector3 targetPos;
|
||
|
||
public override TaskStatus OnUpdate()
|
||
{
|
||
Enemy enemy = transform.GetComponent<Enemy>();
|
||
if (enemy == null) return TaskStatus.Failure;
|
||
enemy.ai.isStopped = false;
|
||
enemy.ai.destination = targetPos.Value;
|
||
float dis=Vector3.Distance(enemy.transform.position.ReflectVectorXOZ(),targetPos.Value.ReflectVectorXOZ());
|
||
if (dis <= 1f)
|
||
{
|
||
return TaskStatus.Success;
|
||
}
|
||
return TaskStatus.Running;
|
||
}
|
||
}
|
||
|
||
public class EnemyStop : Action
|
||
{
|
||
public override TaskStatus OnUpdate()
|
||
{
|
||
Enemy enemy = transform.GetComponent<Enemy>();
|
||
if (enemy == null) return TaskStatus.Failure;
|
||
enemy.ai.isStopped = true;
|
||
//Debug.Log("敌人停止");
|
||
return TaskStatus.Success;
|
||
}
|
||
}
|
||
|
||
public class EnemyAttack : Action
|
||
{
|
||
public SharedVector3 targetPos;
|
||
public SharedGameObject target;
|
||
public override TaskStatus OnUpdate()
|
||
{
|
||
Enemy enemy = transform.GetComponent<Enemy>();
|
||
if (enemy == null) return TaskStatus.Failure;
|
||
Vector3 curTargetPos=targetPos.Value;
|
||
if (target.Value != null)
|
||
curTargetPos = target.Value.transform.position;
|
||
enemy.DoAttack(curTargetPos);
|
||
return TaskStatus.Success;
|
||
}
|
||
}
|
||
|
||
public class EnemyStopAttack : Action
|
||
{
|
||
public override TaskStatus OnUpdate()
|
||
{
|
||
Enemy enemy = transform.GetComponent<Enemy>();
|
||
if (enemy == null) return TaskStatus.Failure;
|
||
enemy.StopAttack();
|
||
return TaskStatus.Success;
|
||
}
|
||
}
|
||
|
||
public class PlayerAIAttack : Action
|
||
{
|
||
public SharedGameObject target;
|
||
public SharedVector3 targetPos;
|
||
public override TaskStatus OnUpdate()
|
||
{
|
||
PlayerAI playerAi = transform.GetComponent<PlayerAI>();
|
||
if (playerAi == null) return TaskStatus.Failure;
|
||
transform.LookAt(new Vector3(targetPos.Value.x, transform.position.y, targetPos.Value.z));
|
||
if (target.Value != null)
|
||
{
|
||
transform.LookAt(new Vector3(target.Value.transform.position.x, transform.position.y, target.Value.transform.position.z));
|
||
}
|
||
playerAi.DoAttack();
|
||
return TaskStatus.Success;
|
||
}
|
||
}
|
||
public class PlayerAIMeleeAttack : Action
|
||
{
|
||
public SharedGameObject target;
|
||
public SharedVector3 targetPos;
|
||
public override TaskStatus OnUpdate()
|
||
{
|
||
PlayerAI playerAi = transform.GetComponent<PlayerAI>();
|
||
if (playerAi == null) return TaskStatus.Failure;
|
||
if(target.Value==null|| GameManager.Ins.gameState==GameState.Victory)
|
||
return TaskStatus.Success;
|
||
// transform.LookAt(new Vector3(targetPos.Value.x, transform.position.y, targetPos.Value.z));
|
||
// if (target.Value != null)
|
||
// {
|
||
// transform.LookAt(new Vector3(target.Value.transform.position.x, transform.position.y, target.Value.transform.position.z));
|
||
// }
|
||
playerAi.DoAttack();
|
||
|
||
return TaskStatus.Running;
|
||
}
|
||
}
|
||
|
||
public class EnemyMeleeAttack : Action
|
||
{
|
||
public SharedGameObject target;
|
||
public SharedVector3 targetPos;
|
||
public override TaskStatus OnUpdate()
|
||
{
|
||
Enemy playerAi = transform.GetComponent<Enemy>();
|
||
if (playerAi == null) return TaskStatus.Failure;
|
||
if (target.Value != null)
|
||
targetPos = target.Value.transform.position;
|
||
playerAi.DoAttack(targetPos.Value);
|
||
return TaskStatus.Running;
|
||
}
|
||
}
|
||
|
||
|
||
public class PlayerAIStopAttack: Action
|
||
{
|
||
public SharedGameObject target;
|
||
public SharedVector3 targetPos;
|
||
public override TaskStatus OnUpdate()
|
||
{
|
||
PlayerAI playerAi = transform.GetComponent<PlayerAI>();
|
||
if (playerAi == null) return TaskStatus.Failure;
|
||
target.Value = null;
|
||
playerAi.StopAttack();
|
||
return TaskStatus.Success;
|
||
}
|
||
}
|
||
|
||
public class EnemyGetTarget : Action
|
||
{
|
||
public SharedVector3 targetPos;
|
||
|
||
// 未命中时的偏移距离(可调大,越大越容易飞出屏幕)
|
||
public float missOffset = 3f;
|
||
|
||
public override TaskStatus OnUpdate()
|
||
{
|
||
Vector3 target = transform.forward;
|
||
var tran = GameManager.Ins.GetPlayerPos();
|
||
|
||
if (tran == null)
|
||
{
|
||
targetPos.Value = target;
|
||
return TaskStatus.Success;
|
||
}
|
||
|
||
// 15%~25% 命中率
|
||
float hitRate = Random.Range(0.15f, 0.25f);
|
||
bool isHit = Random.value < hitRate;
|
||
|
||
if (isHit)
|
||
{
|
||
// 命中 -> 瞄准玩家/队友
|
||
targetPos.Value = tran.position;
|
||
}
|
||
else
|
||
{
|
||
// 未命中 -> 在目标点周围随机一个方向偏移
|
||
// 生成随机二维方向(平面上随机360°)
|
||
Vector2 randomCircle = Random.insideUnitCircle.normalized;
|
||
Vector3 offset = new Vector3(randomCircle.x, Random.Range(-0.5f, 0.5f), randomCircle.y) * missOffset;
|
||
|
||
targetPos.Value = tran.position + offset;
|
||
}
|
||
|
||
return TaskStatus.Success;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 正常射击寻找敌人
|
||
/// </summary>
|
||
public class TeammateFindTarget : Action
|
||
{
|
||
public SharedVector3 targetPos;
|
||
|
||
public float normalHitMin = 0.1f; // 10%
|
||
public float normalHitMax = 0.2f; // 20%
|
||
private float hitRate;
|
||
|
||
public override void OnStart()
|
||
{
|
||
// 每次开始时刷新命中率
|
||
hitRate = Random.Range(normalHitMin, normalHitMax);
|
||
}
|
||
|
||
public override TaskStatus OnUpdate()
|
||
{
|
||
var tran = GameManager.Ins.GetEnemy(transform);
|
||
if (tran == null) return TaskStatus.Failure;
|
||
|
||
bool isHit = Random.value < hitRate;
|
||
|
||
if (isHit)
|
||
{
|
||
targetPos.Value = tran.transform.position; // 命中敌人
|
||
}
|
||
else
|
||
{
|
||
// 偏移未命中
|
||
Vector2 randomCircle = Random.insideUnitCircle.normalized;
|
||
Vector3 offset = new Vector3(randomCircle.x, Random.Range(-0.5f, 0.5f), randomCircle.y) * 3f;
|
||
targetPos.Value = tran.transform.position + offset;
|
||
}
|
||
|
||
return TaskStatus.Success;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 百分百杀死敌人
|
||
/// </summary>
|
||
public class TeammateSupportKill : Action
|
||
{
|
||
public SharedGameObject Target;
|
||
public override TaskStatus OnUpdate()
|
||
{
|
||
if (GameManager.Ins == null) return TaskStatus.Failure;
|
||
var enemy = GameManager.Ins.GetEnemy(transform);
|
||
if (enemy != null)
|
||
{
|
||
var enemyComponent = enemy.GetComponent<Enemy>();
|
||
Target.Value = enemyComponent.gameObject;
|
||
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
||
{
|
||
if (enemyComponent != null && enemyComponent.state != EnemyState.Die)
|
||
{
|
||
enemyComponent.Die(transform.position,null);
|
||
Debug.LogError($"{gameObject.name} 倒计时结束,击杀一名敌人!");
|
||
}
|
||
}, 3f);
|
||
Target.Value = enemy;
|
||
}
|
||
return TaskStatus.Success;
|
||
}
|
||
}
|
||
|
||
public class CountdownTimeAction: Action
|
||
{
|
||
public SharedFloat CountdownTime; // 倒计时秒数
|
||
|
||
public override TaskStatus OnUpdate()
|
||
{
|
||
CountdownTime.Value-=Time.deltaTime;
|
||
return TaskStatus.Success;
|
||
}
|
||
}
|
||
} |