using NAudio.Wave;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
using DG.Tweening;
using static RobotManager;
public enum RobotCommand
{
///
///设置位置
///
init_position,
///
/// 设置名称
///
set_name,
///
/// 设置颜色
///
set_color,
///
/// 控制舵机值
///
servo_motor_control,
///
/// 获取动作
///
get_action_lab,
///
/// 执行动作
///
play_action,
///
/// 获取语音识别结果
///
get_speech_text,
///
/// 获取识别结果
///
get_image_action,
///
/// 打开动作编辑面板
///
define_action,
///
/// 文本转语音
///
speak,
///
/// 打开颜色识别面板
///
openColorDetect,
///
/// 关闭颜色识别
///
stopColorDetect,
///
/// 左转
///
trun_left,
///
/// 右转
///
trun_right
}
public class RobotManager : MonoBehaviour
{
public GameObject robotTempCamera;
public RobotUIManager robotUIManager;
public Collider Collider;
public static RobotManager instance;
public static GameObject robot;
public GameObject customPanel;
public GameObject robotActionTemple;
private GameObject templete;
///
/// 机器人模板
///
public GameObject Templete { get { if (templete == null) templete = Resources.Load("Prefabs/JQR_YJ") as GameObject; return templete; } }
///
/// 机器人生成父物体
///
public Transform robotParent;
public static List robotgames = new List();
public static List robots = new List();
///
/// 使用全局坐标
///
public bool useGlobalPosition;
public static int[] idsValue = new int[18];
public static bool ControlRobot;
public Robot Robot;
public List Motions = new List();
//默认动作站立
public static List standMon = new List();
public static int time;
///
/// 动作组
///
public List all_motions = new List();
///
/// 场景元素物体
///
private List sceneObject = new List();
private void Awake()
{
Collider = GameObject.Find("Object005").GetComponent();
instance = this;
robotParent = GameObject.Find("GameScenter").transform;
GameObject game = GameObject.Find("MyTemp");
CustomPanel.robot = game.transform.Find("My_JQR_YJ_Temp").gameObject;
GetMotionLab();
}
private void Start()
{
Debug.Log("start");
MyServer.instance.SetHandler_jqr(PythonDataHandler);
MyServer.instance.SetHandler_other((data) =>
{
{
var command = (PublicCommond)Enum.Parse(typeof(PublicCommond), data["commond"].ToString());
var eventid = data["event_id"].ToObject();
switch (command)
{
case PublicCommond.init_scene:
{
//关闭语音面板
RobotUIManager.instance.CloseTextToSpeakPanel();
//停止颜色识别
UnityCallPython.instance.StopColorRead();
//关闭媒体音乐
MediaPlayer.Instance.AudioStop();
//删除UI界面
if (RobotUI.Instance.panelDic != null && RobotUI.Instance.panelDic.Count > 0)
{
foreach (var item in RobotUI.Instance.panelDic.Values)
{
//item.SetActive(false);
Destroy(item.gameObject);
}
RobotUI.Instance.panelDic.Clear();
}
//初始化场景
RobotUI.Instance.Init();
RobotUIManager.instance.CloseWebCam();
if (robotgames.Count > 0)
{
robotgames.ForEach(a =>
{
Destroy(a.gameObject);
});
robotgames.Clear();
}
robots.Clear();
//删除自定义动作面板
if (customPanel != null)
{
//customPanel.SetActive(false);
Destroy(customPanel);
//RobotUI.Instance.OpenPanel(RobotePanelEnum.CustomPanel.ToString());
}
if (robotActionTemple != null)
{
robotActionTemple.SetActive(false);
}
//清理场景元素
sceneObject.ForEach(a =>
{
Destroy(a);
});
sceneObject.Clear();
//重置分数
ScoreManager.Instance.ResetScore();
//隐藏ide面板
MainCanvasManager.Instance.transform.Find("ide设置面板").gameObject.SetActive(false);
MyServer.instance.SendMsgToSDK(eventid, ResultStatus.SUCCESS);
}
break;
case PublicCommond.audio_load:
var __file_name = data["filepath"].ToObject();
MediaPlayer.Instance.NewAudioLoad(__file_name, (result, msg) =>
{
ConsolePanel.ConsoleOutput("语音加载"+ (result==true?"完成:":"失败:"+ msg), "log");
DoReturn(result, eventid, msg);
});
break;
case PublicCommond.audio_play:
MediaPlayer.Instance.AudioPlay();
break;
case PublicCommond.audio_pause:
MediaPlayer.Instance.AudioPause();
break;
case PublicCommond.audio_stop:
MediaPlayer.Instance.AudioStop();
break;
case PublicCommond.audio_set_volume:
var __volume = data["volume"].ToObject();
MediaPlayer.Instance.AudioSetVolume(__volume);
break;
case PublicCommond.screen_shot:
bool isStep = data["isStep"].ToObject();
string stepName = data["stepName"].ToObject();
if (!isStep)
{
MainCanvasManager.Instance.ScreemShot(CallForTest.instance.pathTaskFile + "/任务.png");
}
else
{
MainCanvasManager.Instance.ScreemShot(CallForTest.instance.pathTaskFile + "/步骤_" + stepName + ".png");
}
break;
case PublicCommond.get_control_image:
List tmpNames = new List();
List list = GameObject.FindObjectsByType(FindObjectsInactive.Exclude, FindObjectsSortMode.None).ToList();
list.ForEach(a =>
{
if (!string.IsNullOrEmpty(a.Nameid))
{
tmpNames.Add(a.Nameid);
}
});
DoReturn(true, eventid, JsonConvert.SerializeObject(tmpNames));
break;
case PublicCommond.set_control_image:
{
string name = data["name"].ToString();
string filePath = data["filePath"].ToString();
MyCardItem item = GameObject.FindObjectsByType(FindObjectsInactive.Exclude, FindObjectsSortMode.None).ToList().Find(a => a.Nameid == name);
if (item != null)
{
item.ChangeTexture(filePath, (isok,str) =>
{
DoReturn(isok, eventid, str);
});
}
}
break;
case PublicCommond.get_scene_objet:
{
List names=new List();
var tmps=Resources.LoadAll("sceneObject").ToList();
tmps.ForEach(a =>
{
names.Add(a.name);
});
DoReturn(true, eventid, JsonConvert.SerializeObject(names));
}
break;
case PublicCommond.set_scene_objet:
{
string name = data["name"].ToString();
float[] point = data["point"].ToObject();
float[] rotate = data["rotate"].ToObject();
GameObject obj=Resources.Load("sceneObject/" + name);
if (obj != null)
{
GameObject sceneObj = GameObject.Instantiate(obj, robotParent,true);
sceneObject.Add(sceneObj);
sceneObj.transform.localPosition = new Vector3(point[0], point[1], point[2]);
sceneObj.transform.localEulerAngles = new Vector3(rotate[0], rotate[1], rotate[2]);
DoReturn(true, eventid, "设置成功");
}
else
{
DoReturn(false, eventid, "不存在此场景元素");
}
}
break;
case PublicCommond.set_camera_mode:
{
//设置相机模式
var mode = data["mode"].ToObject();
if (mode == "自由模式")
{
Camera.main.transform.GetComponent().enabled = true;
transform.GetComponent().EndRoate();
}
else if (mode == "环绕模式")
{
var center = data["center"].ToObject();
var radius = data["radius"].ToObject();
var tmpspeed = data["speed"].ToObject();
var high = data["high"].ToObject();
Camera.main.transform.GetComponent().enabled = false;
Vector3 tmpc = new Vector3(center[0], center[1], center[2]);
transform.GetComponent().StartRoate(Camera.main, robotParent.position + tmpc, radius, tmpspeed, high);
}
}
break;
default:
break;
}
}
});
}
///
/// 获取所有动作文件
///
public void GetMotionLab()
{
var path = Path.Combine(Application.streamingAssetsPath, "RobotFiles/Motions");
DirectoryInfo directory = new DirectoryInfo(path);
FileInfo[] files = directory.GetFiles("*.txt");
for (int i = 0; i < files.Length; i++)
{
using (StreamReader reader = new StreamReader(files[i].FullName))
{
var txt = reader.ReadToEnd();
var newGroup = new MotionGroup() { motionName = files[i].Name.Split('.')[0], motionList = new List() };
var motor_values = JsonConvert.DeserializeObject>(txt);
for (int j = 0; j < motor_values.Count; j++)
{
newGroup.motionList.Add(new Motion(motor_values[j]));
}
all_motions.Add(newGroup);
if (newGroup.motionName == "stand")
{
standMon.Add(newGroup);
}
}
}
}
public void ShowMotions()
{
}
public class MonsData
{
public string action;
public float duration;
public int loop_times;
public int number;
}
public void PythonDataHandler(JObject _jobject)
{
var command = (RobotCommand)Enum.Parse(typeof(RobotCommand), _jobject["commond"].ToString());
var eventid = _jobject["event_id"].ToObject();
var number = _jobject["number"].ToObject();
ScoreManager.Instance.UpdateScore(command.ToString());
switch (command)
{
case RobotCommand.init_position:
var pos = _jobject["point"].ToObject();
var rotate = _jobject["rotate"].ToObject();
//Console(string.Format("设置[0]号机器人位置:[{1},{2}]", number, pos[0], pos[1]));
if (CreateNewRobot(new Vector3(pos[0], 0, pos[1]), rotate, false, number))
{
DoReturn(true, eventid, "初始化机器人"+ number + "成功!");
ConsolePanel.ConsoleOutput("初始化机器人"+ number + "成功!", "log");
}
else
{
DoReturn(false, eventid, "初始化机器人失败!");
ConsolePanel.ConsoleOutput("初始化机器人失败!", "log");
}
break;
case RobotCommand.set_name:
var name = _jobject["name"].ToObject();
//Console(string.Format("设置{0}号机器人名称:{1}", number, name));
if (robots!=null&&robots.Count>0)
{
if (UpdateRobotName(number, name))
{
DoReturn(true, eventid, "名称:" + name + "设置成功!");
}else
{
DoReturn(false, eventid, "名称:" + name + "设置失败!");
ConsolePanel.ConsoleOutput("名称:" + name + "设置失败!", "log");
}
}
else
{
DoReturn(false, eventid, "名称:" + name + "设置失败!"+ "请创建机器人!");
ConsolePanel.ConsoleOutput("名称:" + name + "设置失败!" + "请创建机器人!", "log");
}
break;
case RobotCommand.set_color:
var rob_colorstr = _jobject["color"].ToObject();
//var rob_color = UnityEngine.Color.red;
//UnityEngine.ColorUtility.TryParseHtmlString("#" + rob_colorstr, out rob_color);
//Console(string.Format("设置{0}号机器人颜色:{1}", number, rob_color));
if (robots != null && robots.Count > 0)
{
if (UpdateRobotColor(number, rob_colorstr))
{
DoReturn(true, eventid, rob_colorstr + "颜色设置成功!");
}
else
{
DoReturn(false, eventid, rob_colorstr + "颜色设置失败!");
ConsolePanel.ConsoleOutput(rob_colorstr + "颜色设置失败!", "log");
}
}
else
{
DoReturn(false, eventid, rob_colorstr + "颜色设置失败!" + "请创建机器人!");
ConsolePanel.ConsoleOutput( rob_colorstr + "颜色设置失败!" + "请创建机器人!", "log");
}
break;
case RobotCommand.get_action_lab:
//获取动作列表
Debug.Log("获取成功");
string actions = "";
actions += ("nodHead:2.5秒,");
actions += ("shakeHead:2.5秒,");
all_motions.ForEach(a =>
{
float time=0;
a.motionList.ForEach(b =>
{
time += b.duration_time;
});
actions += (a.motionName + ":" + time + "秒,");
});
DoReturn(true, eventid, actions.TrimEnd(','));
//string[] filesname = GetAction(false, number);
//if (filesname != null && filesname.Length > 0)
//{
// string str = "nodHead,shakeHead,";
// for (int i = 0; i < filesname.Length; i++)
// {
// var a = filesname[i].Split('\\')[filesname[i].Split('\\').Length - 1];
// var b = a.Split('.')[0];
// str += b + ",";
// }
// DoReturn(true, eventid, str.TrimEnd(','));
//}
//else
//{
// DoReturn(false, eventid, "获取失败");
//}
break;
case RobotCommand.play_action:
var action = _jobject["action"].ToObject();
var duration = _jobject["duration"].ToObject();
var loop_times = _jobject["loop_times"].ToObject();
MonsData monsData = new MonsData();
monsData.action = action;
monsData.duration = duration;
monsData.loop_times = loop_times;
monsData.number = number;
//robotgames[number - 1].GetComponent().isPlaying = true;
var tmpaction=RobotManager.instance.all_motions.Find(a => a.motionName == action);
if(tmpaction!=null)
{
robotgames[number - 1].GetComponent().actionque.Enqueue(monsData);
}
else
{
if (action == "nodHead")
{
robotgames[number - 1].GetComponent().NodHead(loop_times);
}
else if (action == "shakeHead")
{
robotgames[number - 1].GetComponent().ShakeHead(loop_times);
}
else
{
DoReturn(false, eventid, "无此动作:" + action);
ConsolePanel.ConsoleOutput("无此动作:" + action, "log");
}
}
break;
case RobotCommand.get_speech_text:
Openmicrophone(number,(isok,result)=>
{
DoReturn(isok, eventid, result);
});
break;
case RobotCommand.define_action:
DoReturn(DefineAction(true, number), eventid, DefineAction(true, number) ? "自定义动作成功!" : "自定义动作失败!");
break;
case RobotCommand.servo_motor_control:
var id = _jobject["servo_id"].ToObject();
var value = _jobject["value"].ToObject();
SetServoMotorContorl(number, id, value);
break;
case RobotCommand.speak:
string text = _jobject["txt"].ToObject();
string tone = _jobject["tone"].ToObject();
int speed = _jobject["speed"].ToObject();
RobotUIManager.instance.OpenTextToSpeekPanel(text, tone, speed, robotgames[number - 1].GetComponent());
break;
case RobotCommand.openColorDetect:
StartColorDetect(number);
ConsolePanel.ConsoleOutput("开始颜色识别");
break;
case RobotCommand.stopColorDetect:
StopColorDetect(number);
ConsolePanel.ConsoleOutput("停止颜色识别");
break;
case RobotCommand.trun_left:
{
float angle = _jobject["angle"].ToObject();
float time = _jobject["time"].ToObject();
var robot = robots.Find(x => x.robot_id == number);
if (robot != null)
{
Vector3 initR = robot.transform.eulerAngles;
robot.transform.Rotate(Vector3.down, angle, Space.World);
Vector3 R = robot.transform.eulerAngles;
robot.transform.eulerAngles = initR;
robot.transform.DORotate(R, time).OnComplete(() =>
{
DoReturn(true, eventid, "");
});
}
}
break;
case RobotCommand.trun_right:
{
float angle = _jobject["angle"].ToObject();
float time = _jobject["time"].ToObject();
var robot = robots.Find(x => x.robot_id == number);
if (robot != null)
{
Vector3 initR = robot.transform.eulerAngles;
robot.transform.Rotate(Vector3.up, angle, Space.World);
Vector3 R = robot.transform.eulerAngles;
robot.transform.eulerAngles = initR;
robot.transform.DORotate(R, time).OnComplete(() =>
{
DoReturn(true, eventid, "");
});
}
}
break;
default:
Debug.Log("机器人无此指令:" + command);
break;
}
}
///
/// 开始图像识别
///
///
void StartColorDetect(int number)
{
UnityCallPython.instance.StartColorRead(robotgames[number - 1].GetComponent());
}
///
/// 关闭颜色识别
///
///
void StopColorDetect(int number)
{
UnityCallPython.instance.StopColorRead();
}
private void SetServoMotorContorl(int _number, int id, int value)
{
robotgames[_number - 1].GetComponent().HVBUSSERVOs.Find(x => x.indexNo.Equals(id)).UpdateValue(value, 0);
}
///
/// 打开动作编辑面板
///
///
///
///
private bool DefineAction(bool v, int _number)
{
robotTempCamera.SetActive(true);
for (int i = 0; i < robotgames.Count; i++)
{
robotgames[i].SetActive(false);
}
ControlRobot = true;
customPanel = RobotUI.Instance.OpenPanel(RobotePanelEnum.CustomPanel.ToString());
if (customPanel != null)
{
return true;
}
else
{
return false;
}
}
///
/// 打开录音面板,并开始语音识别
///
///
///
///
private void Openmicrophone(int number,Action callback)
{
RobotUI.Instance.OpenPanel(RobotePanelEnum.RecordPanel.ToString()).GetComponent().Init(number, callback);
//if (MicrophoneInput.instance.CheckMicrophone())
//{
// RobotUI.Instance.OpenPanel(RobotePanelEnum.RecordPanel.ToString()).GetComponent().Init(number,callback);
//}
//else
//{
// callback(false,"错误:无麦克风");
//}
}
///
/// 获取动作
///
///
///
///
private string[] GetAction(bool _isarray, int _uav_number)
{
string[] filesName = Directory.GetFiles(Application.streamingAssetsPath + "/RobotFiles/Motions", "*.txt");
if (filesName.Length > 0)
{
return filesName;
}
return null;
}
///
/// 打开摄像机
///
public bool OpenCam(bool flag, int number)
{
if (robotgames[number - 1] != null)
{
bool isopencamera = robotgames[number - 1].GetComponent().OpenCamera();
return isopencamera;
}
return false;
}
///
/// 播放动画
///
///
///
///
///
/// 设置机器人颜色
///
///
///
///
private bool UpdateRobotColor(int number, string color)
{
UnityEngine.Color rob_color;
if(UnityEngine.ColorUtility.TryParseHtmlString(color, out rob_color))
{
var rob = robots.Find(x => x.robot_id == number);
if (rob == null)
{
return false;
}
else
{
rob.SetColor(rob_color);
return true;
}
}
else
{
return false;
}
}
///
/// 输出机器人信息
///
///
///
private void Console(string _message, string _type = "log")
{
ConsolePanel.ConsoleOutput(_message, _type);//输出机器人信息
}
///
/// 执行并返回结果
///
///
///
///
private void DoReturn(bool _success, int _eventid, string _result)
{
MyServer.instance.SendMsgToSDK(_eventid, _success ? ResultStatus.SUCCESS : ResultStatus.FAILED_WARNING, _result);
//if (_success)
// MyServer.instance.SendMsgToSDK(_eventid, ResultStatus.SUCCESS);
//else
// MyServer.instance.SendMsgToSDK(_eventid, ResultStatus.FAILED_WARNING, _result);
}
///
/// 从位置创建机器人
///
///
///
///
///
public bool CreateNewRobot(Vector3 _pos, float rotate, bool _isarray = false, int _number = 0)
{
////检测范围内是否有机器人
//if (Physics.CheckSphere(_pos, 0.75f, 1 << 6) && !_isarray)
// return false;
var newt = Instantiate(Templete, robotParent, true);
if (useGlobalPosition)
{
newt.transform.position = _pos;
newt.transform.eulerAngles = new Vector3(-90, rotate-90, 0);
}
else
{
newt.transform.localPosition = _pos;
newt.transform.localEulerAngles = new Vector3(-90, rotate-90, 0);
}
Collider[] collider = Physics.OverlapSphere(newt.transform.position, 0.1f);
if (collider.Contains(Collider))
{
}
else
{
ConsolePanel.ConsoleOutput(_number + "号机器人初始化位置超过限制,请重试", "warning");
Destroy(newt);
return false;
}
robotgames.Add(newt);
newt.GetComponent().id = _number;
newt.transform.SetAsLastSibling();
newt.SetActive(true);
var rob = newt.GetComponentInChildren();
robots.Add(rob);
rob.robot_id = _number == 0 ? robots.Count : _number;
return true;
}
public bool UpdateRobotName(int _number, string _name)
{
var robot = robots.Find(x => x.robot_id == _number);
if (robot == null)
{
return false;
}
else
{
robot.SetName(_name);
return true;
}
}
internal void GetTextString(string recordstr)
{
}
}