(client) feat:实现右键菜单
This commit is contained in:
@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using AI;
|
||||
using Base;
|
||||
@ -14,6 +15,7 @@ namespace Entity
|
||||
public AttributesDef attributes;
|
||||
public Vector3 direction;
|
||||
public GameObject body;
|
||||
public string affiliation;
|
||||
|
||||
public bool canSelect = true;
|
||||
public bool IsChase { set; get; } = true;
|
||||
@ -21,21 +23,34 @@ namespace Entity
|
||||
{
|
||||
set
|
||||
{
|
||||
if (!value)
|
||||
if (value)
|
||||
{
|
||||
IsChase = true;
|
||||
currentJob = null;
|
||||
}
|
||||
_isPlayerControlled = value;
|
||||
}
|
||||
get => _isPlayerControlled;
|
||||
}
|
||||
|
||||
|
||||
public bool IsDead => attributes.health <= 0;
|
||||
|
||||
private bool _isPlayerControlled = false;
|
||||
private bool _warning = false;
|
||||
|
||||
|
||||
|
||||
public virtual void Init(PawnDef pawnDef)
|
||||
{
|
||||
attributes = pawnDef.attributes.Clone();
|
||||
aiTree = ConvertToAIBase(pawnDef.behaviorTree);
|
||||
affiliation=pawnDef.affiliation;
|
||||
//定义的tag有限,不用这个了
|
||||
// if(!string.IsNullOrEmpty(affiliation))
|
||||
// gameObject.CompareTag(affiliation);
|
||||
}
|
||||
public void Tick()
|
||||
{
|
||||
if (PlayerControlled)
|
||||
if (_isPlayerControlled)
|
||||
{
|
||||
UpdatePlayerControls();
|
||||
}
|
||||
@ -72,9 +87,9 @@ namespace Entity
|
||||
direction = (pos - transform.position).normalized;
|
||||
}
|
||||
|
||||
public virtual void Kill(float delay = 0)
|
||||
public virtual void Kill()
|
||||
{
|
||||
Destroy(gameObject,delay);
|
||||
attributes.health = 0;
|
||||
}
|
||||
|
||||
private void AutoBehave()
|
||||
@ -99,42 +114,97 @@ namespace Entity
|
||||
|
||||
private void UpdatePlayerControls()
|
||||
{
|
||||
// 获取当前键盘输入状态
|
||||
var inputDirection = new Vector3();
|
||||
// 检测 Shift 键状态
|
||||
var isHoldingShift = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
|
||||
IsChase = !isHoldingShift; // 按住 Shift 时 IsChase = false,否则 true
|
||||
// 获取当前键盘输入状态(2D 移动,只使用 X 和 Y 轴)
|
||||
var inputDirection = Vector2.zero;
|
||||
|
||||
// 检测 WASD 输入
|
||||
// 检测 WASD 或方向键输入
|
||||
if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
|
||||
{
|
||||
inputDirection += Vector3.forward; // 向前移动
|
||||
inputDirection += Vector2.up; // 向上移动(Y 轴正方向)
|
||||
}
|
||||
if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
|
||||
{
|
||||
inputDirection += Vector3.back; // 向后移动
|
||||
inputDirection += Vector2.down; // 向下移动(Y 轴负方向)
|
||||
}
|
||||
if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
|
||||
{
|
||||
inputDirection += Vector3.left; // 向左移动
|
||||
inputDirection += Vector2.left; // 向左移动(X 轴负方向)
|
||||
}
|
||||
if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
|
||||
{
|
||||
inputDirection += Vector3.right; // 向右移动
|
||||
inputDirection += Vector2.right; // 向右移动(X 轴正方向)
|
||||
}
|
||||
|
||||
// 如果有输入方向,则设置目标位置并尝试移动
|
||||
if (inputDirection != Vector3.zero)
|
||||
if (inputDirection == Vector2.zero) return;
|
||||
// 归一化方向向量,确保对角线移动速度一致
|
||||
inputDirection = inputDirection.normalized;
|
||||
|
||||
// 设置目标位置(2D 移动,Z 轴保持不变)
|
||||
var targetPosition = transform.position + new Vector3(inputDirection.x, inputDirection.y, 0);
|
||||
|
||||
// 调用 SetTarget 方法设置目标位置
|
||||
SetTarget(targetPosition);
|
||||
|
||||
// 调用 TryMove 方法处理实际移动逻辑
|
||||
TryMove();
|
||||
}
|
||||
public static AIBase ConvertToAIBase(BehaviorTreeDef behaviorTreeDef)
|
||||
{
|
||||
if (behaviorTreeDef == null)
|
||||
return null;
|
||||
var aiBase = CreateAIBaseInstance(behaviorTreeDef.className);
|
||||
if (behaviorTreeDef.childTree != null)
|
||||
{
|
||||
// 归一化方向向量,确保对角线移动速度一致
|
||||
inputDirection = inputDirection.normalized;
|
||||
|
||||
// 设置目标位置(假设当前位置为 transform.position)
|
||||
Vector3 targetPosition = transform.position + inputDirection;
|
||||
|
||||
// 调用 SetTarget 方法设置目标位置
|
||||
SetTarget(targetPosition);
|
||||
|
||||
// 调用 TryMove 方法处理实际移动逻辑
|
||||
TryMove();
|
||||
foreach (var child in behaviorTreeDef.childTree)
|
||||
{
|
||||
if (child != null)
|
||||
{
|
||||
aiBase.children.Add(ConvertToAIBase(child));
|
||||
}
|
||||
}
|
||||
}
|
||||
return aiBase;
|
||||
}
|
||||
// 使用反射根据 className 创建具体的 AIBase 子类实例
|
||||
private static AIBase CreateAIBaseInstance(string className)
|
||||
{
|
||||
if (string.IsNullOrEmpty(className))
|
||||
throw new ArgumentException("className 不能为空");
|
||||
if (className.Equals("AIBase", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return (AIBase)Activator.CreateInstance(typeof(AIBase));
|
||||
}
|
||||
// 定义可能的命名空间列表
|
||||
var possibleNamespaces = new[] { "AI"};
|
||||
|
||||
foreach (var ns in possibleNamespaces)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 获取当前程序集
|
||||
var assembly = typeof(AIBase).Assembly;
|
||||
|
||||
// 尝试查找类型
|
||||
var type = assembly.GetType($"{ns}.{className}");
|
||||
|
||||
if (type != null && typeof(AIBase).IsAssignableFrom(type))
|
||||
{
|
||||
// 如果找到合适的类型,则创建实例并返回
|
||||
return (AIBase)Activator.CreateInstance(type);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 忽略单个命名空间的错误,继续尝试下一个命名空间
|
||||
}
|
||||
}
|
||||
|
||||
// 如果所有命名空间都未找到对应的类型,抛出异常
|
||||
throw new InvalidOperationException($"无法找到类型 {className} 或该类型不是 AIBase 的子类");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,13 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace Entity
|
||||
{
|
||||
public class Outline:MonoBehaviour
|
||||
public class Outline : MonoBehaviour
|
||||
{
|
||||
public GameObject body;
|
||||
public SpriteRenderer outlineRenderer;
|
||||
public CapsuleCollider2D outlineCollider;
|
||||
|
||||
public Entity entity;
|
||||
|
||||
private bool _select = false;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
var size = GetSize();
|
||||
@ -15,15 +22,17 @@ namespace Entity
|
||||
outlineCollider.direction = size.x > size.y ? CapsuleDirection2D.Horizontal : CapsuleDirection2D.Vertical;
|
||||
outlineCollider.size = size;
|
||||
}
|
||||
|
||||
public void Show()
|
||||
{
|
||||
outlineRenderer.gameObject.SetActive(true);
|
||||
outlineRenderer.enabled = true;
|
||||
}
|
||||
|
||||
public void Hide()
|
||||
{
|
||||
outlineRenderer.gameObject.SetActive(false);
|
||||
outlineRenderer.enabled = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定对象及其所有子对象组成的图像的大小。
|
||||
/// </summary>
|
||||
@ -37,15 +46,52 @@ namespace Entity
|
||||
|
||||
if (renderers.Length == 0)
|
||||
{
|
||||
return new(-1,-1);
|
||||
return new(-1, -1);
|
||||
}
|
||||
|
||||
var totalBounds = renderers[0].bounds;
|
||||
for (var i = 1; i < renderers.Length; i++)
|
||||
{
|
||||
totalBounds.Encapsulate(renderers[i].bounds);
|
||||
}
|
||||
|
||||
var size = totalBounds.size;
|
||||
return size;
|
||||
}
|
||||
|
||||
private void OnMouseEnter()
|
||||
{
|
||||
Show();
|
||||
_select = true;
|
||||
}
|
||||
|
||||
private void OnMouseExit()
|
||||
{
|
||||
Hide();
|
||||
_select = false;
|
||||
}
|
||||
|
||||
private void OnMouseOver()
|
||||
{
|
||||
// 检测是否按下的是鼠标右键
|
||||
if (Input.GetMouseButtonDown(1)) // 鼠标右键对应的是按钮索引 1
|
||||
{
|
||||
var rightMenu = Prefab.RightMenuPrefab.Instance;
|
||||
rightMenu.Init(GetMenu());
|
||||
rightMenu.transform.position=Input.mousePosition;
|
||||
rightMenu.Show();
|
||||
}
|
||||
}
|
||||
|
||||
private List<(string name, UnityAction callback)> GetMenu()
|
||||
{
|
||||
var result = new List<(string name, UnityAction callback)>();
|
||||
if(entity.PlayerControlled)
|
||||
result.Add(("结束操控",()=>entity.PlayerControlled=false));
|
||||
else
|
||||
result.Add(("手动操控",()=>entity.PlayerControlled=true));
|
||||
result.Add(("杀死",()=>entity.Kill()));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user