using System.Collections; using System.Collections.Generic; using UnityEngine; using XRTool.Util; using SC.XR.Unity.Module_InputSystem; using System; using System.Linq; using ShadowStudio.Model; using UnityEngine.EventSystems; using TriLib.Extras; namespace ShadowStudio.Tool { /// /// 画笔功能 /// public class DrawPener : UnitySingleton { /// /// 笔的材质 /// public Material penMate; /// /// 笔颜色的名称 /// public string colorName; /// /// 最小间距 /// public float minDis = 0.01f; /// /// 默认笔头的粗细 /// public float radius = 0.005f; /// /// 笔的颜色 /// public Color penColor = Color.white; /// /// 线的预制体 /// public LineSegment linePrefab; /// /// 每根线段最多100点 /// public int maxPointOfLine = 100; /// /// 所有线段加起来最多500个点 /// public int maxPointOfSegment = 500; /// /// 有可能要撤销对应的组件 /// private Queue lines; private LineSegment currentLine; private Coroutine drawCoroutine; private InputDevicePartBase part; private Vector3 lastPosition = Vector3.zero; public string defaultShader = "Mixed Reality Toolkit/Standard"; private int currentPoint; /// /// 资源的id /// public static string artLineId = "ArtId_GameObject"; /// /// 线与对应的名字的集合 /// private Dictionary lineMap; /// /// 请他用户的线段id /// 仅房主使用此数据 /// private List otherUserList; private List userList; private DrawPlaneContainer drawPlane; public List OtherUserList { get { if (otherUserList == null) { otherUserList = new List(); } return otherUserList; } } public List UserList { get { if (userList == null) { userList = new List(); } return userList; } } public LineSegment GetLine(string lineName) { if (lineMap != null && lineMap.ContainsKey(lineName)) { return lineMap[lineName]; } return null; } protected override void Awake() { base.Awake(); DisActiveDrawPen(); } public void ActiveDrawPen() { gameObject.SetActive(true); } /// /// 添加老线 /// /// public void AddOldLine(LineSegment line) { if (line) { if (lineMap == null) { lineMap = new Dictionary(); } if (!lineMap.ContainsKey(line.name)) { lineMap.Add(line.name, line); } if (lines == null) { lines = new Queue(); } if (line.Line.positionCount > 0 && !lines.Contains(line)) { currentPoint += line.Line.positionCount; lines.Enqueue(line); } } } public void DisActiveDrawPen() { gameObject.SetActive(false); } public void OnEnable() { DispatcherBase.KeyDownDelegateRegister(OnKeyDownAction); DispatcherBase.KeyUpDelegateRegister(OnKeyUpAction); //caoting 2021/6/11 合并新的sdk if (SCInputModule.Instance) { SCInputModule.Instance.CanDrag = false; } } private void OnDisable() { DispatcherBase.KeyDownDelegateUnRegister(OnKeyDownAction); DispatcherBase.KeyUpDelegateUnRegister(OnKeyUpAction); //caoting 2021/6/11 合并新的sdk if (SCInputModule.Instance) { SCInputModule.Instance.CanDrag = true; } } /// /// 抬起按钮时 /// /// /// private void OnKeyUpAction(InputKeyCode keyCode, InputDevicePartBase part) { drawPlane = null; lastPosition = Vector3.zero; ClearPen(); isHandlerobj = false; distance = 0; isNoCheck = false; } public void ClearPen() { if (drawCoroutine != null) { StopCoroutine(drawCoroutine); } drawCoroutine = null; if (lines == null) { lines = new Queue(); } if (currentLine) { if (currentLine.Line.positionCount > 1) { if (!lines.Contains(currentLine)) { currentLine.StopSyn(); lines.Enqueue(currentLine); } } else { Destroy(currentLine.gameObject); } } currentLine = null; } private bool isHandlerobj; private bool isNoCheck; private float distance; /// /// 按下按钮时 /// /// /// private void OnKeyDownAction(InputKeyCode keyCode, InputDevicePartBase part) { if (lines == null) { lines = new Queue(); } ///当前的还存在上一个画笔 if (currentLine || drawCoroutine != null || this.part != part) { ClearPen(); } ///当大于线段时,清除掉相关的线段 while (currentPoint >= maxPointOfSegment - maxPointOfLine) { ClearOldLine(); } this.part = part; var tmp = part.inputDataBase.SCPointEventData.pointerCurrentRaycast.gameObject; if (tmp) { ///如果点击了某个UI按钮,触发对应的点击事件,不绘制图形 var tmpbutton = tmp.GetComponentInParent(); if (tmpbutton != null) { if (!isNoCheck) { isHandlerobj = true; if (isHandlerobj) { if (distance == 0) { distance = GetDis(); } } } //tmpbutto n.OnPointerClick(part.inputDataBase.SCPointEventData); //return; } var downHandler = tmp.GetComponentInParent(); if (downHandler != null) { if (!isNoCheck) { isHandlerobj = true; if (isHandlerobj) { if (distance == 0) { distance = GetDis(); } } } //downHandler.OnPointerDown(part.inputDataBase.SCPointEventData); //return; } ///在画板上绘制 else if (drawPlane = tmp.GetComponentInParent()) { } else { drawPlane = null; } } drawCoroutine = StartCoroutine(DrawLine(keyCode)); } private float helpAngle = 1f; /// /// 画线功能的实现 /// 如果画在画线板上时,不计入总点数 /// /// /// private IEnumerator DrawLine(InputKeyCode keyCode) { var obj = part.inputDataBase.SCPointEventData.pointerCurrentRaycast.gameObject; currentLine = CreateLine(); currentLine.IsSingleLine = !drawPlane; if (lineMap == null) { lineMap = new Dictionary(); } if (!lineMap.ContainsKey(currentLine.name)) { lineMap.Add(currentLine.name, currentLine); } yield return currentLine; Vector3 pointPos = part.detectorBase.pointerBase.cursorBase.transform.position; //Vector3 pointPos = part.pointerBase.cursorBase.transform.position; if (API_Module_InputSystem.InputDeviceStatus(InputDeviceType.KS)) { pointPos = API_Module_InputSystem_KS.KSPosition(API_Module_InputSystem_KS.GCType.Right); pointPos += API_Module_InputSystem_KS.KSTransform(API_Module_InputSystem_KS.GCType.Right).forward.normalized * SystemSettingMgr.Instance.settings.RayDis; } if (lastPosition != Vector3.zero) { GameNode.Instance.SetParent(ObjNode.World, currentLine.transform, GameNode.Instance.LocalPosition(ObjNode.World, lastPosition, 1), Vector3.zero, Vector3.one, true); currentLine.AddPosition(lastPosition); currentPoint++; } else { GameNode.Instance.SetParent(ObjNode.World, currentLine.transform, GameNode.Instance.LocalPosition(ObjNode.World, pointPos, 1), Vector3.zero, Vector3.one, true); } while (currentLine && part) { //if (obj != part.inputDataBase.SCPointEventData.pointerCurrentRaycast.gameObject) //{ // OnKeyUpAction(keyCode, part); // yield break; //} Vector3 posks = part.detectorBase.pointerBase.cursorBase.transform.position; if (API_Module_InputSystem.InputDeviceStatus(InputDeviceType.KS)) { posks = API_Module_InputSystem_KS.KSPosition(API_Module_InputSystem_KS.GCType.Right); posks += API_Module_InputSystem_KS.KSTransform(API_Module_InputSystem_KS.GCType.Right).forward.normalized * SystemSettingMgr.Instance.settings.RayDis; } if (currentLine.Line.positionCount < 1 || Vector3.Distance(posks, pointPos) >= (obj ? (minDis / 5f) : minDis)) { bool addPoint = true; if (currentLine.Line.positionCount > 1) { Vector3 lastDir = currentLine.transform.TransformPoint(currentLine.Line.GetPosition(currentLine.Line.positionCount - 1)) - currentLine.transform.TransformPoint(currentLine.Line.GetPosition(currentLine.Line.positionCount - 2)); Vector3 curDir = posks - currentLine.transform.TransformPoint(currentLine.Line.GetPosition(currentLine.Line.positionCount - 1)); if (Vector3.Angle(lastDir, curDir) < helpAngle) { UnityLog.Instance.Log(Vector3.Angle(lastDir, curDir), 4); addPoint = false; if (isHandlerobj) { pointPos = GameSession.Instance.GetHeadForwadPos(distance, false); currentLine.SetPosition(pointPos); } else { currentLine.SetPosition(posks); } } } if (addPoint) { if (isHandlerobj) { pointPos = GameSession.Instance.GetHeadForwadPos(distance, false); } else { pointPos = posks; } currentLine.AddPosition(pointPos); currentPoint++; } } if (currentLine.Line.positionCount >= maxPointOfLine) { lastPosition = pointPos; isNoCheck = true; OnKeyDownAction(keyCode, part); yield break; } yield return new WaitForFixedUpdate(); //part.inputDataBase.SCPointEventData.pointerCurrentRaycast.gameObject; //part.pointerBase.cursorBase.transform.position; } } /// /// 创建线段 /// /// public LineSegment CreateLine() { LineSegment line; var lineName = UnityEngine.Random.Range(100000000, 999999999).ToString(); // DateTime.Now.ToString("MMddHHmmssf"); if (linePrefab) { line = Instantiate(linePrefab); line.name = lineName; } else { GameObject obj = new GameObject(lineName, typeof(LineRenderer)); line = obj.AddComponent(); //if (!line.Line.sharedMaterial) //{ // line.Line.sharedMaterial = penMate; //} } if (line) { ///如果设置了默认的材质,则使用默认材质 if (penMate) { line.SetLine(penMate); } line.SetLine(penColor, radius, colorName); } line.Line.positionCount = 0; line.Line.useWorldSpace = false; ///如果存在物体,则改变对齐模式,使线段看起来平整圆滑 if (part != null && part.inputDataBase.SCPointEventData.pointerCurrentRaycast.gameObject) { line.Line.alignment = LineAlignment.TransformZ; } GameNode.Instance.SetParent(ObjNode.World, line.transform, Vector3.zero, Vector3.zero, Vector3.one, true); return line; } /// /// 清除本地自己的老线段 /// 为什么不在线发送确认清除?因为延时问题造成的不流畅问题 /// 主动删除并释放本地内存,然后发送同步信息删除线段 /// public void ClearOldLine() { ///如果此条线段尚未同步,则禁止本地删除 if (lines.Count > 0) { var line = lines.Dequeue(); if (line) { currentPoint -= line.Line.positionCount; lineMap.Remove(line.name); ///删除线段 line.DelLine(); Destroy(line.gameObject); } } } /// /// 清除指定的线,删除此线段 /// 如果此线段属于用户自己创建的,则清空对应的内存 /// /// public void ClearOldLine(LineSegment line) { if (line) { if (lineMap != null && lineMap.ContainsKey(line.name)) { currentPoint -= line.Line.positionCount; lineMap.Remove(line.name); } Destroy(line.gameObject); } } /// /// 清除所有线段 /// public void ClearAllLine(bool isClearAll = false) { if (UserList != null) { ArtInfoMgr.Instance.DelGoodsByIds(UserList); } if (isClearAll) { ClearOtherLine(); } } /// /// 删除 /// /// public void AddLineId(int id, bool isOther = true) { if (isOther) { OtherUserList.Add(id); } else { UserList.Add(id); } } /// /// 清空其他用户的线段 /// public void ClearOtherLine() { ArtInfoMgr.Instance.DelGoodsByIds(OtherUserList); } public float GetDis() { Vector3 posks = part.detectorBase.pointerBase.cursorBase.transform.position; if (API_Module_InputSystem.InputDeviceStatus(InputDeviceType.KS)) { posks = API_Module_InputSystem_KS.KSPosition(API_Module_InputSystem_KS.GCType.Right); posks += API_Module_InputSystem_KS.KSTransform(API_Module_InputSystem_KS.GCType.Right).forward.normalized * SystemSettingMgr.Instance.settings.RayDis; } float dis= Vector3.Distance(posks, GameSession.Instance.gameHead.position); return dis; } } }