ict.xunfei/Assets/Scripts/ROBOT/Robot.cs

586 lines
16 KiB
C#

using DG.Tweening;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Newtonsoft.Json;
using System.IO;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using static RobotManager;
using static ResolutionTest;
using TMPro;
public enum ColorEnum
{
red,
blue,
green
}
/// <summary>
/// 机器人电机数据
/// </summary>
public class RobotMotorValues
{
public int index;
public int time;
public int[] values;
}
public class Robot : MonoBehaviour
{
public Queue<GameObject> gameque = new Queue<GameObject>();
public Scrollbar myScrollbar;
public float scrovalue;
int number = 0;
Tween tween;
bool camIsOpen;//相机是否打开
public bool Isflag;//是否改动滑动条
public int id;
/// <summary>
/// 原始动作消息队列
/// </summary>
public Queue<MonsData> actionque;
public int robot_id;
public string myname;
/// <summary>
/// 伺服电机转动速度
/// </summary>
public float HVBUSSERVO_Speed = 0.1f;
/// <summary>
/// 当前动作
/// </summary>
public List<Motion> _motions = null;
/// <summary>
/// 动作队列
/// </summary>
public Queue<List<Motion>> motion_queue = new Queue<List<Motion>>();
/// <summary>
/// 电机
/// </summary>
public List<HVBUSSERVO> HVBUSSERVOs;
/// <summary>
/// 刚体组件
/// </summary>
public Rigidbody Rigidbody;
/// <summary>
/// 测试数据
/// </summary>
public string hvbdata;
/// <summary>
/// 是否正在播放动作
/// </summary>
public bool isPlaying = false;
/// <summary>
/// 重心 示意
/// </summary>
public Transform CenterOfMass;
public AudioSource audioSource;
private TextMeshPro NameText;
private void Awake()
{
animatorfla = true;
actionque = new Queue<MonsData>();
HVBUSSERVOs = GetComponentsInChildren<HVBUSSERVO>().ToList();
audioSource = GetComponent<AudioSource>();
if (transform.Find("NameText") != null)
{
NameText = transform.Find("NameText").GetComponent<TextMeshPro>();
}
}
private void OnEnable()
{
Rigidbody = GetComponent<Rigidbody>();
}
void Start()
{
ReSort();
_motions = null;
}
Queue<string> _colors = new Queue<string>();
// Update is called once per frame
void Update()
{
if (gameObject.transform.position.y < -0.5f)
{
ConsolePanel.ConsoleOutput(number + "号机器人掉下舞台,已销毁", "warning");
RobotManager.robotgames.Remove(gameObject);
RobotManager.robots.Remove(this);
Destroy(gameObject);
}
//动作测试
//if (Input.GetKeyDown(KeyCode.Space))
//{
// DoMotions();
//}
if (motion_queue.Count > 0 && _motions == null)
{
_motions = motion_queue.Dequeue();
DoMotions();
}
if (MotionsQueue.Count > 0 && current_motion == null)
{
current_motion = MotionsQueue.Dequeue();
DoBusServo(current_motion, EnqueArray);
}
if (actionque.Count != 0)
{
if (animatorfla)
{
MonsData mon = actionque.Dequeue();
PlayMotion(mon, id);
animatorfla = false;
}
}
}
/// <summary>
/// 动作持续时间
/// </summary>
float action_duration;
/// <summary>
/// 更新动作
/// </summary>
/// <param name="_motions"></param>
/// <param name="_duration">动作结束后的持续时间</param>
/// <param name="_callback"></param>
public MonsData _currmon = null;
/// <summary>
/// 更新动作
/// </summary>
/// <param name="_motions"></param>
/// <param name="_mon"></param>
/// <param name="_callback"></param>
public void UpdateMotions(List<Motion> _motions, MonsData _mon = null, Action _callback = null)
{
isPlaying = true;
if (_mon != null)
{
for (int i = 0; i < _mon.loop_times; i++)
{
motion_queue.Enqueue(_motions);
}
}
else
{
motion_queue.Enqueue(_motions);
}
_callback?.Invoke();
}
public void ClearQueue()
{
_motions = null;
gameque.Clear();
// motion_queue.Clear();
tween.Kill();
}
MonsData mon;
/// <summary>
/// 解析原始数据
/// </summary>
/// <param name="monsData"></param>
/// <param name="number"></param>
private void PlayMotion(MonsData monsData, int number)
{
action_duration = monsData.duration;
mon = monsData;
var group=RobotManager.instance.all_motions.Find(a => a.motionName == mon.action);
if(group!=null)
{
UpdateMotions(group.motionList, mon);
}
}
/// <summary>
/// 拍照
/// </summary>
public bool OpenCamera()
{
RobotUIManager.instance.AssignmentCam();
return camIsOpen;
}
/// <summary>
/// 执行第一条动作元
/// </summary>
private void DoMotions()
{
i = 1;
current_motion = null;
MotionsQueue.Enqueue(_motions[0]);
}
int i = 1;//动作序号
/// <summary>
/// 动作元
/// </summary>
Queue<Motion> MotionsQueue = new Queue<Motion>();
/// <summary>
/// 当前动作元
/// </summary>
public Motion current_motion = null;
int num = 0;
private void EnqueArray()
{
Debug.Log("取出新动作:" + i);
if (i < _motions.Count)
{
MotionsQueue.Enqueue(_motions[i]);
current_motion = null;
i += 1;
}
else //此处表示当前动作结束
{
if (motion_queue.Count == 0)
{
Invoke("OnActionEnd", action_duration);
}
else
// UpdateMotions(RobotManager.standMon[0].motionList, null);
_motions = null;
//RobotManager.time = 0;
}
}
public bool animatorfla = true;
/// <summary>
/// 动作结束执行
/// </summary>
private void OnActionEnd()
{
isPlaying = false;
animatorfla = true;
_motions = null;
if (Isflag)
{
for (int i = 0; i < CustomPanel.instance.items.Count; i++)
{
CustomPanel.instance.items[i].IsActivation(true);
}
}
}
/// <summary>
/// 电机执行
/// </summary>
/// <param name="motion"></param>
/// <param name="callback"></param>
public void DoBusServo(Motion motion, Action callback)
{
Debug.Log("执行动作");
float t = 0;
tween = DOTween.To(() => t, (x) => t = x, motion.duration_time, motion.duration_time).OnComplete(() => { callback?.Invoke(); });
HVBUSSERVOs[0].UpdateValue(motion.id_1, motion.duration_time, Isflag);
HVBUSSERVOs[1].UpdateValue(motion.id_2, motion.duration_time, Isflag);
HVBUSSERVOs[2].UpdateValue(motion.id_3, motion.duration_time, Isflag);
HVBUSSERVOs[3].UpdateValue(motion.id_4, motion.duration_time, Isflag);
HVBUSSERVOs[4].UpdateValue(motion.id_5, motion.duration_time, Isflag);
HVBUSSERVOs[5].UpdateValue(motion.id_6, motion.duration_time, Isflag);
HVBUSSERVOs[6].UpdateValue(motion.id_7, motion.duration_time, Isflag);
HVBUSSERVOs[7].UpdateValue(motion.id_8, motion.duration_time, Isflag);
HVBUSSERVOs[8].UpdateValue(motion.id_9, motion.duration_time, Isflag);
HVBUSSERVOs[9].UpdateValue(motion.id_10, motion.duration_time, Isflag);
HVBUSSERVOs[10].UpdateValue(motion.id_11, motion.duration_time, Isflag);
HVBUSSERVOs[11].UpdateValue(motion.id_12, motion.duration_time, Isflag);
HVBUSSERVOs[12].UpdateValue(motion.id_13, motion.duration_time, Isflag);
HVBUSSERVOs[13].UpdateValue(motion.id_14, motion.duration_time, Isflag);
HVBUSSERVOs[14].UpdateValue(motion.id_15, motion.duration_time, Isflag);
HVBUSSERVOs[15].UpdateValue(motion.id_16, motion.duration_time, Isflag);
// HVBUSSERVOs[16].UpdateValue(motion.id_17, motion.duration_time, Isflag);
// HVBUSSERVOs[17].UpdateValue(motion.id_18, motion.duration_time, Isflag);
HVBUSSERVOs[16].UpdateValue(500, motion.duration_time, Isflag);
HVBUSSERVOs[17].UpdateValue(500, motion.duration_time, Isflag);
if (gameque.Count > 0)
{
CustomPanel.FreshCurrItem(gameque.Dequeue());
number++;
myScrollbar.value = 1 - number * scrovalue;
}
}
/// <summary>
/// 根据颜色播放对应的动作
/// </summary>
public void PlayColorAction(string color)
{
if (!isPlaying)
{
if (!_colors.Contains(color))
{
_colors.Enqueue(color);
}
//匹配对应动作
string actionName = "";
if (color == "red")
{
actionName = "back";
}
else if (color == "blue")
{
actionName = "wave";
}
else if (color == "green")
{
actionName = "put_down";
}
else
{
Debug.Log("无此颜色");
return;
}
MotionGroup group = RobotManager.instance.all_motions.Find(a => a.motionName == actionName);
if (group != null)
{
UpdateMotions(group.motionList);
}
else
{
Debug.Log("无此动作文件:" + actionName);
}
}
}
/// <summary>
/// 对电机按编号重新排序
/// </summary>
private void ReSort()
{
HVBUSSERVOs = GetComponentsInChildren<HVBUSSERVO>().ToList();
HVBUSSERVO temp;
bool swapped;
for (int i = 0; i < HVBUSSERVOs.Count; i++)
{
swapped = false;
for (int j = 0; j < HVBUSSERVOs.Count - 1 - i; j++)
{
if (HVBUSSERVOs[j].indexNo > HVBUSSERVOs[j + 1].indexNo)
{
temp = HVBUSSERVOs[j];
HVBUSSERVOs[j] = HVBUSSERVOs[j + 1];
HVBUSSERVOs[j + 1] = temp;
if (!swapped)
swapped = true;
}
if (!swapped)
continue;
}
}
}
/// <summary>
/// 设置颜色
/// </summary>
/// <param name="color"></param>
public void SetColor(Color color)
{
List<Material> materials = new List<Material>();
List<Transform> gamelist = GetComponentsInChildren<Transform>().ToList();
for (int i = 1; i < gamelist.Count; i++)
{
List<Material> list = gamelist[i].transform.GetComponent<Renderer>().materials.ToList();
materials.AddRange(list);
}
for (int i = 0; i < materials.Count; i++)
{
materials[i].color = color;
}
ConsolePanel.ConsoleOutput("机器人颜色设置成功!", "log");
}
internal void RefreshCur(List<GameObject> items, Scrollbar _scrollbar)
{
myScrollbar = _scrollbar;
myScrollbar.value = 1;
scrovalue = 1f / items.Count;
number = 0;
gameque.Clear();
for (int i = 0; i < items.Count; i++)
{
gameque.Enqueue(items[i].gameObject);
}
}
/// <summary>
/// 开始录音
/// </summary>
public void StartRedord()
{
GetComponent<MicroPhoneManager>().StartRecordAudio();
}
/// <summary>
/// 停止录音
/// </summary>
public bool StopRecord()
{
bool flag = GetComponent<MicroPhoneManager>().StopRecordAudio();
return flag;
}
/// <summary>
/// 试听
/// </summary>
public void Audition()
{
GetComponent<MicroPhoneManager>().PlayRecordAudio();
}
public void ENDAudition()
{
GetComponent<MicroPhoneManager>().StopRecordAudio();
}
/// <summary>
/// 开始识别录音
/// </summary>
public void Recognition()
{
byte[] audiodata = MicroPhoneManager.instance.GetClipData();
IFlytekManager.instance.AudioToText(audiodata, DebugAudioText);
}
//识别成功,显示识别文字
public void DebugAudioText(string audio_text)
{
RecordDebugPanel.instance.Init(audio_text);
for (int i = 0; i < RobotManager.instance.all_motions.Count; i++)
{
if (audio_text == RobotManager.instance.all_motions[i].motionName)
{
motion_queue.Clear();
_motions = null;
UpdateMotions(RobotManager.instance.all_motions[i].motionList);
}
}
}
/// <summary>
/// 重新录音
/// </summary>
public void Anew()
{
RobotUI.Instance.ClosePanel(RobotePanelEnum.RecordEndPanel.ToString());
GetComponent<MicroPhoneManager>().StartRecordAudio();
RobotUI.Instance.OpenPanel(RobotePanelEnum.RecordKingPanel.ToString());
}
/// <summary>
/// 关闭麦克风
/// </summary>
public void EndRecord()
{
GetComponent<MicroPhoneManager>().StopRecordAudio();
}
/// <summary>
/// 设置机器人名字
/// </summary>
/// <param name="name"></param>
public void SetName(string name)
{
myname = name;
if (name.Length>10)
NameText.text = name.Substring(0, 10);
else NameText.text = name;
string Log = "名称:" + name + "设置成功!";
ConsolePanel.ConsoleOutput(Log, "log");
}
/// <summary>
/// 点头
/// </summary>
[ContextMenu("点头")]
public void NodHead(int time)
{
if (time > 0)
{
if (!isPlaying)
{
isPlaying = true;
HVBUSSERVOs[16].UpdateValue(500, 0.5f, false);
DoNod(time);
}
}
}
private void DoNod(int time)
{
HVBUSSERVOs[17].UpdateValue(1000, 1, false, () =>
{
HVBUSSERVOs[17].UpdateValue(0, 1, false, () =>
{
time--;
if(time<=0)
{
//结束动作
HVBUSSERVOs[17].UpdateValue(500, 0.5f, false, () =>
{
isPlaying = false;
});
}
else
{
DoNod(time);
}
});
});
}
/// <summary>
/// 摇头
/// </summary>
[ContextMenu("摇头")]
public void ShakeHead(int time)
{
if(time > 0)
{
if (!isPlaying)
{
isPlaying = true;
HVBUSSERVOs[17].UpdateValue(500, 0.5f, false);
DoShake(time);
}
}
}
private void DoShake(int time)
{
HVBUSSERVOs[16].UpdateValue(1000, 1, false, () =>
{
HVBUSSERVOs[16].UpdateValue(0, 1, false, () =>
{
time --;
if(time <=0)
{
HVBUSSERVOs[16].UpdateValue(500, 0.5f, false, () =>
{
isPlaying = false;
});
}
else
{
DoShake(time);
}
});
});
}
}