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) { } }