387 lines
13 KiB
C#
387 lines
13 KiB
C#
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
using static UnityEditor.Experimental.GraphView.GraphView;
|
||
using static UnityEngine.GraphicsBuffer;
|
||
|
||
public class UseObjects : MonoBehaviour
|
||
{
|
||
private Transform parentObject; // 父物体(包含所有子物体)
|
||
private GameObject player;//玩家
|
||
public JSONReader js;
|
||
//警戒物品使用
|
||
public GameObject warningPrefab; // 警戒锥道具模型
|
||
public GameObject polePrefab; // 警戒杆道具模型
|
||
public GameObject tapePrefab; // 隔离警示带模型
|
||
public float maxDistance = 10f; // 最大直接距离10米
|
||
public bool hasTape = false; // 是否携带隔离警示带
|
||
private List<GameObject> warningObjects = new List<GameObject>(); // 存储所有警戒类道具
|
||
//物品交付
|
||
public List<GameObject> potentialTargets; // 所有可能成为交付对象的目标列表
|
||
public Button deliverButton; // 交付按钮
|
||
public float deliveryRange = 1f; // 交付范围半径
|
||
private GameObject currentTarget; // 当前最近的交付目标
|
||
private bool islogistics;//角色是否为后勤保障组;
|
||
private bool isdelivery;//是否开启交付
|
||
[System.Serializable]
|
||
public class EmergencyItem
|
||
{
|
||
public string itemName; // 道具名称
|
||
public bool isConsumable; // 是否消耗品 (1=是,0=否)
|
||
public int validTime; // 有效时间:-1(无限),0 或正数(有限时间)
|
||
}
|
||
|
||
// 模拟物品的字段配置
|
||
public Dictionary<string, EmergencyItem> itemConfigs = new Dictionary<string, EmergencyItem>();
|
||
|
||
void Start()
|
||
{
|
||
parentObject = GameObject.Find("fireEquip").transform;
|
||
player=GameObject.FindGameObjectWithTag("Player");
|
||
// 初始化模拟物品数据
|
||
InitializeItemConfigs(3001);
|
||
// 隐藏交付按钮
|
||
deliverButton.gameObject.SetActive(false);
|
||
deliverButton.onClick.AddListener(HandleDelivery);
|
||
|
||
// 为每个子物体添加点击事件
|
||
foreach (Transform child in parentObject)
|
||
{
|
||
Button childButton = child.GetComponent<Button>();
|
||
if (childButton == null)
|
||
{
|
||
Debug.LogWarning($"子物体 {child.name} 缺少 Button 组件!");
|
||
continue;
|
||
}
|
||
// 初始化子物体状态
|
||
Transform buttonPanel = child.Find("informationImage");
|
||
Transform highlight = child.Find("Image");
|
||
if (buttonPanel != null) buttonPanel.gameObject.SetActive(false);
|
||
if (highlight != null) highlight.gameObject.SetActive(false);
|
||
|
||
// 绑定点击事件
|
||
childButton.onClick.AddListener(() => OnChildClicked(child.gameObject));
|
||
}
|
||
// 获取所有标签为 "People" 的物体
|
||
GameObject[] playNPC = GameObject.FindGameObjectsWithTag("People");
|
||
// 遍历每个人,将其存入一个链表
|
||
foreach (GameObject player in playNPC)
|
||
{
|
||
potentialTargets.Add(player.gameObject);
|
||
}
|
||
UseCautionaryitems(player.transform.position, polePrefab);
|
||
}
|
||
private void Update()
|
||
{
|
||
// 在范围内查找最近的交付目标
|
||
currentTarget = FindNearestTarget();
|
||
if (currentTarget != null)
|
||
{
|
||
// 显示交付按钮并高亮目标
|
||
HighlightTarget(currentTarget, true);
|
||
deliverButton.gameObject.SetActive(true);
|
||
}
|
||
else
|
||
{
|
||
// 隐藏交付按钮并取消高亮
|
||
if (currentTarget != null)
|
||
{
|
||
HighlightTarget(currentTarget, false);
|
||
}
|
||
deliverButton.gameObject.SetActive(false);
|
||
}
|
||
}
|
||
// 初始化模拟物品数据
|
||
void InitializeItemConfigs(int id)
|
||
{
|
||
itemConfigs.Add("1", new EmergencyItem { itemName = "1", isConsumable = true, validTime = -1 });
|
||
itemConfigs.Add("2", new EmergencyItem { itemName = "2", isConsumable = true, validTime = 30 });
|
||
itemConfigs.Add("3", new EmergencyItem { itemName = "3", isConsumable = false, validTime = 15 });
|
||
|
||
itemConfigs.Add("4", new EmergencyItem { itemName = "4", isConsumable = true, validTime = -1 });
|
||
itemConfigs.Add("5", new EmergencyItem { itemName = "5", isConsumable = true, validTime = 30 });
|
||
itemConfigs.Add("6", new EmergencyItem { itemName = "6", isConsumable = false, validTime = 15 });
|
||
// 添加更多物品配置...
|
||
foreach (var key in js.matialDictionary)
|
||
{
|
||
MatialData matialData = key.Value;
|
||
if (matialData.ID==id)
|
||
{
|
||
//获取物品数据
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
// 当子物体被点击时
|
||
void OnChildClicked(GameObject clickedChild)
|
||
{
|
||
// 隐藏其他子物体的按钮板和高光框
|
||
foreach (Transform child in parentObject)
|
||
{
|
||
Transform buttonPanel = child.Find("informationImage");
|
||
Transform highlight = child.Find("Image");
|
||
if (buttonPanel != null) buttonPanel.gameObject.SetActive(false);
|
||
if (highlight != null) highlight.gameObject.SetActive(false);
|
||
}
|
||
|
||
// 获取当前点击的子物体名称
|
||
string itemName = clickedChild.name;
|
||
Debug.Log(itemName);
|
||
if (!itemConfigs.ContainsKey(itemName))
|
||
{
|
||
Debug.LogWarning($"未找到物品 {itemName} 的配置!");
|
||
return;
|
||
}
|
||
|
||
// 根据配置判断显示按钮
|
||
EmergencyItem item = itemConfigs[itemName];
|
||
Transform clickedButtonPanel = clickedChild.transform.Find("informationImage");
|
||
Transform clickedHighlight = clickedChild.transform.Find("Image");
|
||
|
||
if (clickedButtonPanel != null)
|
||
{
|
||
//clickedButtonPanel.gameObject.SetActive(true);
|
||
// 显示对应的按钮
|
||
UpdateButtonPanel(clickedButtonPanel, item);
|
||
|
||
}
|
||
|
||
// 显示当前子物体的高光框
|
||
if (clickedHighlight != null)
|
||
{
|
||
clickedHighlight.gameObject.SetActive(true);
|
||
}
|
||
}
|
||
|
||
// 根据物品配置更新按钮面板
|
||
void UpdateButtonPanel(Transform buttonPanel, EmergencyItem item)
|
||
{
|
||
// 获取按钮
|
||
Button viewButton = buttonPanel.Find("LookButton").GetComponent<Button>();
|
||
Button useButton = buttonPanel.Find("UseButton").GetComponent<Button>();
|
||
Button discardButton = buttonPanel.Find("ThrowButton").GetComponent<Button>();
|
||
|
||
// 按规则显示或隐藏按钮
|
||
if (item.isConsumable && item.validTime == -1)
|
||
{
|
||
// 规则1:直接使用,不弹出按钮
|
||
buttonPanel.gameObject.SetActive(false);
|
||
UseItem(item);
|
||
}
|
||
else if (item.isConsumable && item.validTime >= 0)
|
||
{
|
||
buttonPanel.gameObject.SetActive(true);
|
||
// 规则2:弹出【查看】【使用】【丢弃】
|
||
viewButton.gameObject.SetActive(true);
|
||
useButton.gameObject.SetActive(true);
|
||
discardButton.gameObject.SetActive(true);
|
||
|
||
// 绑定事件
|
||
viewButton.onClick.AddListener(() => ViewItem(item));
|
||
useButton.onClick.AddListener(() => UseItem(item));
|
||
discardButton.onClick.AddListener(() => DiscardItem(item));
|
||
}
|
||
else if (!item.isConsumable && item.validTime >= 0)
|
||
{
|
||
buttonPanel.gameObject.SetActive(true);
|
||
// 规则3:弹出【查看】【丢弃】
|
||
viewButton.gameObject.SetActive(true);
|
||
useButton.gameObject.SetActive(false);
|
||
discardButton.gameObject.SetActive(true);
|
||
|
||
// 绑定事件
|
||
viewButton.onClick.AddListener(() => ViewItem(item));
|
||
discardButton.onClick.AddListener(() => DiscardItem(item));
|
||
}
|
||
}
|
||
|
||
// 查看物品逻辑
|
||
void ViewItem(EmergencyItem item)
|
||
{
|
||
Debug.Log($"查看物品:{item.itemName}");
|
||
}
|
||
|
||
// 使用物品逻辑
|
||
void UseItem(EmergencyItem item)
|
||
{
|
||
Debug.Log($"使用物品:{item.itemName}");
|
||
}
|
||
|
||
// 丢弃物品逻辑
|
||
void DiscardItem(EmergencyItem item)
|
||
{
|
||
Debug.Log($"丢弃物品:{item.itemName}");
|
||
}
|
||
//使用警戒物品
|
||
void UseCautionaryitems(Vector3 playerPosition,GameObject gameObject)
|
||
{
|
||
// 生成警戒类道具(警戒杆,警戒锥)
|
||
GameObject newWarning = Instantiate(gameObject, playerPosition, Quaternion.identity);
|
||
warningObjects.Add(newWarning);
|
||
|
||
// 判断当前位置是否距离其他警戒类道具10米以内
|
||
GameObject nearestWarning = FindNearestWarning(newWarning);
|
||
if (nearestWarning != null)
|
||
{
|
||
if (hasTape)
|
||
{
|
||
// 如果携带隔离警示带,连接到最近的警戒类道具
|
||
CreateTape(newWarning, nearestWarning);
|
||
}
|
||
else
|
||
{
|
||
// 不携带隔离警示带,无连接显示,但有效性记录
|
||
Debug.Log("未携带隔离警示带,未连接警戒道具!");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Debug.Log("当前位置周围10米范围内没有其他警戒类道具!");
|
||
}
|
||
}
|
||
// 找到距离最近的警戒类道具
|
||
private GameObject FindNearestWarning(GameObject currentWarning)
|
||
{
|
||
GameObject nearest = null;
|
||
float minDistance = maxDistance;
|
||
|
||
foreach (GameObject warning in warningObjects)
|
||
{
|
||
if (warning == currentWarning) continue; // 跳过当前道具
|
||
|
||
float distance = Vector3.Distance(currentWarning.transform.position, warning.transform.position);
|
||
if (distance < minDistance)
|
||
{
|
||
minDistance = distance;
|
||
nearest = warning;
|
||
}
|
||
}
|
||
return nearest;
|
||
}
|
||
|
||
// 生成隔离警示带
|
||
private void CreateTape(GameObject start, GameObject end)
|
||
{
|
||
// 生成隔离警示带
|
||
GameObject tape = Instantiate(tapePrefab);
|
||
|
||
// 设置隔离警示带的起点和终点
|
||
LineRenderer lineRenderer = tape.GetComponent<LineRenderer>();
|
||
if (lineRenderer != null)
|
||
{
|
||
lineRenderer.positionCount = 2;
|
||
lineRenderer.SetPosition(0, start.transform.position);
|
||
lineRenderer.SetPosition(1, end.transform.position);
|
||
}
|
||
|
||
Debug.Log($"已连接警戒类道具:{start.name} -> {end.name}");
|
||
}
|
||
// 交付逻辑中查找范围内最近的目标
|
||
GameObject FindNearestTarget()
|
||
{
|
||
GameObject nearestTarget = null;
|
||
float nearestDistance = deliveryRange;
|
||
|
||
foreach (var target in potentialTargets)
|
||
{
|
||
float distance = Vector3.Distance(player.transform.position, target.transform.position);
|
||
if (distance <= deliveryRange && IsInFront(target))
|
||
{
|
||
nearestTarget = target;
|
||
nearestDistance = distance;
|
||
}
|
||
}
|
||
return nearestTarget;
|
||
}
|
||
// 判断目标是否在角色正面 180 度内
|
||
bool IsInFront(GameObject target)
|
||
{
|
||
Vector3 directionToTarget = (target.transform.position - player.transform.position).normalized;
|
||
float dotProduct = Vector3.Dot(player.transform.forward, directionToTarget);
|
||
return dotProduct > 0; // 在正面 180 度内
|
||
}
|
||
// 高亮目标(例如显示边缘发光效果)
|
||
void HighlightTarget(GameObject target, bool highlight)
|
||
{
|
||
Renderer renderer = target.GetComponent<Renderer>();
|
||
if (renderer != null)
|
||
{
|
||
// 设置高亮效果,比如更改材质或颜色
|
||
renderer.material.SetColor("_EmissionColor", highlight ? Color.green : Color.black);
|
||
}
|
||
}
|
||
// 处理交付逻辑
|
||
void HandleDelivery()
|
||
{
|
||
if (currentTarget == null)
|
||
{
|
||
Debug.LogWarning("没有可交付的目标!");
|
||
return;
|
||
}
|
||
|
||
// 检查目标职业是否符合条件
|
||
TargetData targetData = currentTarget.GetComponent<TargetData>();
|
||
if (targetData == null || targetData.weightCapacity == -1)
|
||
{
|
||
Debug.LogWarning("目标不满足交付条件!");
|
||
return;
|
||
}
|
||
|
||
// 执行交付逻辑:减少玩家道具数量,增加目标道具数量
|
||
PlayerInventory playerInventory = player.GetComponent<PlayerInventory>();
|
||
if (playerInventory != null && playerInventory.UseItem("SelectedItem"))
|
||
{
|
||
targetData.ReceiveItem("SelectedItem");
|
||
Debug.Log($"成功交付道具给目标:{currentTarget.name}");
|
||
}
|
||
else
|
||
{
|
||
Debug.LogWarning("玩家道具不足,无法交付!");
|
||
}
|
||
}
|
||
}
|
||
// 目标数据类
|
||
public class TargetData : MonoBehaviour
|
||
{
|
||
public int weightCapacity = 10; // 负重能力值
|
||
private Dictionary<string, int> receivedItems = new Dictionary<string, int>();
|
||
|
||
public void ReceiveItem(string itemName)
|
||
{
|
||
if (receivedItems.ContainsKey(itemName))
|
||
{
|
||
receivedItems[itemName]++;
|
||
}
|
||
else
|
||
{
|
||
receivedItems[itemName] = 1;
|
||
}
|
||
Debug.Log($"{itemName} 接收成功,当前数量:{receivedItems[itemName]}");
|
||
}
|
||
}
|
||
|
||
// 玩家道具管理类
|
||
public class PlayerInventory : MonoBehaviour
|
||
{
|
||
private Dictionary<string, int> items = new Dictionary<string, int>
|
||
{
|
||
{ "SelectedItem", 5 } // 模拟玩家的道具库存
|
||
};
|
||
|
||
public bool UseItem(string itemName)
|
||
{
|
||
if (items.ContainsKey(itemName) && items[itemName] > 0)
|
||
{
|
||
items[itemName]--;
|
||
Debug.Log($"{itemName} 使用成功,剩余数量:{items[itemName]}");
|
||
return true;
|
||
}
|
||
Debug.LogWarning($"{itemName} 使用失败,库存不足!");
|
||
return false;
|
||
}
|
||
}
|
||
|