void CompareAndUpdate(int realAmount, PartData partData) { while (partData.instances.Count < realAmount) { GameObject newPart = Instantiate(partData.prefab, body); PartOffset offset = offsets[Mathf.Min(offsets.Count - 1, partData.instances.Count)]; newPart.transform.localPosition = offset.posOffset * 3; newPart.transform.localRotation = Quaternion.identity; SpriteRenderer newPartSR = newPart.GetComponentInChildren <SpriteRenderer>(); newPartSR.sortingOrder = newPartSR.sortingOrder + offset.layerOffset; partData.instances.Add(newPart); } }
private void CreatePreview(PartOffset offsetPart) { if (Application.isPlaying) { return; } if (PreviewPart == null) { PreviewPart = Instantiate(offsetPart.Part.gameObject, Target.transform); PreviewPart.transform.position = Target.transform.TransformPoint(offsetPart.Position); PreviewPart.transform.rotation = Target.transform.rotation * Quaternion.Euler(offsetPart.Rotation); if (offsetPart.UseCustomScale) { PreviewPart.transform.localScale = offsetPart.Scale; } PreviewPart.name = offsetPart.Part.Id.ToString(); //PreviewPart.hideFlags = HideFlags.HideAndDontSave; DestroyImmediate(PreviewPart.GetComponent <PartBehaviour>()); foreach (SocketBehaviour Socket in PreviewPart.GetComponentsInChildren <SocketBehaviour>()) { DestroyImmediate(Socket); } Material PreviewMaterial = new Material(Shader.Find(Constants.DIFFUSE_SHADER_NAME)); PreviewMaterial.color = Color.cyan; PreviewPart.ChangeAllMaterialsInChildren(PreviewPart.GetComponentsInChildren <MeshRenderer>(), PreviewMaterial); } }
public override void OnInspectorGUI() { serializedObject.Update(); GUILayout.Space(10); #region Inspector GUILayout.BeginVertical("Easy Build System - Socket Behaviour", "window", GUILayout.MaxHeight(10)); GUILayout.BeginVertical("box"); GUI.color = MainEditor.GetEditorColor; GUILayout.BeginHorizontal(); GUILayout.Label("Socket Behaviour Settings", EditorStyles.largeLabel); #region Socket Behaviour Settings GUILayout.FlexibleSpace(); if (GUILayout.Button(DefaultInspector ? "Advanced Inspector" : "Default Inspector", GUILayout.Width(130))) { DefaultInspector = !DefaultInspector; } if (GUILayout.Button(AllIsOpen ? "Fold In" : "Fold Out", GUILayout.Width(80))) { BaseFoldout = !BaseFoldout; OffsetsFoldout = !OffsetsFoldout; AddonsFoldout = !AddonsFoldout; AllIsOpen = !AllIsOpen; } if (GUILayout.Button(Help ? "Hide Help" : "Show Help", GUILayout.Width(100))) { Help = !Help; } GUI.color = Color.white; GUILayout.EndHorizontal(); if (Help) { EditorGUILayout.HelpBox("This component allows to snap with the Builder Behaviour the Parts Behaviour according the offset settings during the runtime.\n" + "Sockets can cause problems if they are misconfigured, If it disable off unnaturally, please change their offset or radius.", MessageType.Info); GUI.color = MainEditor.GetEditorColor; if (GUILayout.Button("Open Documentation Link")) { Application.OpenURL(Constants.DOCS_LINK); } GUI.color = Color.white; } if (DefaultInspector) { DrawDefaultInspector(); GUILayout.EndVertical(); GUILayout.EndVertical(); serializedObject.ApplyModifiedProperties(); GUILayout.Space(10); return; } GUI.enabled = false; EditorGUILayout.ObjectField("Script", target, typeof(SocketBehaviour), true); GUI.enabled = true; GUI.color = Color.white; GUILayout.BeginHorizontal(); GUILayout.Space(13); BaseFoldout = EditorGUILayout.Foldout(BaseFoldout, "Base Section Settings"); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Space(13); GUILayout.BeginVertical(); if (BaseFoldout) { EditorGUILayout.PropertyField(serializedObject.FindProperty("Type"), new GUIContent("Socket Type :", "This allows to define the socket type.")); if ((SocketType)serializedObject.FindProperty("Type").enumValueIndex == SocketType.Socket) { EditorGUILayout.PropertyField(serializedObject.FindProperty("Radius"), new GUIContent("Socket Radius :", "This allows to define the socket radius point.\nYou can decrease the socket radius to improve the precision during the detection.")); } else { EditorGUILayout.PropertyField(serializedObject.FindProperty("AttachmentBounds"), new GUIContent("Socket Attachment Bounds :", "This allows to define the attachment bounds.")); } EditorGUILayout.PropertyField(serializedObject.FindProperty("DisableOnGroundContact"), new GUIContent("Disable On Terrain/Surface Contact :", "This allows to define if the socket will be disable if she's entering in collision with the terrain or the surface.")); } GUILayout.EndVertical(); GUILayout.EndHorizontal(); #endregion Socket Behaviour Settings GUI.color = MainEditor.GetEditorColor; GUILayout.Label("Socket Offset(s) Settings", EditorStyles.largeLabel); #region Socket Offsets Settings GUI.color = Color.white; GUILayout.BeginHorizontal(); GUILayout.Space(13); OffsetsFoldout = EditorGUILayout.Foldout(OffsetsFoldout, "Offsets Section Settings"); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Space(13); GUILayout.BeginVertical(); if (OffsetsFoldout) { GUILayout.BeginHorizontal(); GUILayout.Space(13); GUILayout.BeginVertical(); if (Target.PartOffsets.Count == 0) { GUILayout.BeginHorizontal("box"); GUI.color = new Color(1.5f, 1.5f, 0f); GUILayout.Label("The list does not contains of offset part(s), No part(s) will may be snap on it."); GUI.color = Color.white; GUILayout.EndHorizontal(); } else { int Index = 0; foreach (PartOffset Offset in Target.PartOffsets) { if (Offset == null || Offset.Part == null) { Target.PartOffsets.Remove(Offset); EditorUtility.SetDirty(target); return; } GUILayout.BeginHorizontal("box"); GUILayout.BeginVertical(); GUILayout.BeginHorizontal(); GUILayout.Label("(ID:" + Offset.Part.Id + ") " + Offset.Part.Name, EditorStyles.largeLabel); if (PreviewPart != null && int.Parse(PreviewPart.name) == Offset.Part.Id) { GUI.color = new Color(1.5f, 1.5f, 0f); if (GUILayout.Button("Cancel Preview", GUILayout.Width(100))) { ClearPreview(); } } else { GUI.color = MainEditor.GetEditorColor; if (GUILayout.Button("Preview Part", GUILayout.Width(100))) { ClearPreview(); CurrentOffset = Offset; CreatePreview(Offset); } } GUI.color = Color.white; GUI.color = new Color(1.5f, 0, 0); if (GUILayout.Button("Remove", GUILayout.Width(80))) { Target.PartOffsets.Remove(Offset); ClearPreview(); return; } GUI.color = Color.white; GUILayout.EndHorizontal(); GUILayout.Space(5); EditorGUI.BeginChangeCheck(); Offset.Position = EditorGUILayout.Vector3Field(new GUIContent("Offset Position : ", "This allows to set the position of part that will snapped on this socket."), Offset.Position); Offset.Rotation = EditorGUILayout.Vector3Field(new GUIContent("Offset Rotation : ", "This allows to set the rotation of part that will snapped on this socket."), Offset.Rotation); Offset.UseCustomScale = EditorGUILayout.Toggle(new GUIContent("Offset Use Custom Scale : ", "This allows to define whether the part to be snap to this socket will have a specific scale, otherwise it will be the scale only of the part."), Offset.UseCustomScale); if (Offset.UseCustomScale) { Offset.Scale = EditorGUILayout.Vector3Field(new GUIContent("Offset Scale : ", "This allows to define the specific scale of the part that will be snapped on this socket."), Offset.Scale); } if (EditorGUI.EndChangeCheck()) { if (PreviewPart != null) { if (PreviewPart.name == Offset.Part.Id.ToString()) { PreviewPart.transform.position = Target.transform.TransformPoint(Offset.Position); PreviewPart.transform.rotation = Quaternion.Euler(Offset.Rotation); PreviewPart.transform.localScale = Offset.UseCustomScale ? Offset.Scale : (Target.transform.parent != null ? Target.transform.parent.localScale : Target.transform.localScale); } EditorUtility.SetDirty(target); } } GUI.color = MainEditor.GetEditorColor; if (!ShowPartOffsetEditor || CurrentOffset != Offset) { if (GUILayout.Button("Edit Offset Part")) { SceneHelper.Focus(target, DrawCameraMode.Textured); if (PreviewPart != null) { DestroyImmediate(PreviewPart); } CurrentOffsetIndex = Index; CurrentOffset = Offset; ShowPartOffsetEditor = true; } } else if (CurrentOffset == Offset) { GUI.color = Color.white; EditorGUILayout.HelpBox("The position, rotation as well as the scale of the current part displayed, will be exactly the same in runtime.", MessageType.Info); GUI.color = new Color(0f, 1.5f, 1.5f); if (GUILayout.Button("Close")) { SceneHelper.UnFocus(); ShowPartOffsetEditor = false; Target.PartOffsets[CurrentOffsetIndex] = CurrentOffset; EditorUtility.SetDirty(target); Debug.Log("<b><color=cyan>[Easy Build System]</color></b> : The offsets changes were saved."); } } GUI.color = Color.white; GUILayout.Space(2); GUILayout.EndVertical(); GUILayout.EndHorizontal(); Index++; } } try { GUILayout.BeginVertical("box"); GUILayout.BeginHorizontal(); PrefabField = (PartBehaviour)EditorGUILayout.ObjectField(new GUIContent("Base Part :", "Part at add to the list for the snap according to the offset on this socket in runtime."), PrefabField, typeof(PartBehaviour), false); GUILayout.EndHorizontal(); GUILayout.BeginVertical(); GUI.enabled = PrefabField != null; GUI.color = MainEditor.GetEditorColor; if (GUILayout.Button("Add New Offset Part")) { if (PrefabField == null) { Debug.LogError("<b><color=cyan>[Easy Build System]</color></b> : Empty field."); return; } if (Target.PartOffsets.Find(entry => entry.Part.Name == PrefabField.Name) == null) { ClearPreview(); PartOffset Offset = new PartOffset(PrefabField); Target.PartOffsets.Add(Offset); CurrentOffset = Offset; CreatePreview(Offset); PrefabField = null; Repaint(); } else { Debug.LogError("<b><color=cyan>[Easy Build System]</color></b> : This part already exists in the collection."); } } GUI.color = Color.white; GUI.enabled = true; GUI.color = new Color(1.5f, 1.5f, 0f); if (GUILayout.Button("Clear All Offset Part(s) List")) { if (EditorUtility.DisplayDialog("Easy Build System - Information", "Do you want remove all the offset part(s) from the collection ?", "Ok", "Cancel")) { Target.PartOffsets.Clear(); Debug.Log("<b><color=cyan>[Easy Build System]</color></b> : The collection has been clear !."); } } GUI.color = Color.white; GUILayout.EndVertical(); GUILayout.Space(3); GUILayout.EndVertical(); } catch { } GUILayout.EndVertical(); GUILayout.EndHorizontal(); } GUILayout.EndVertical(); GUILayout.EndHorizontal(); #endregion Socket Offsets Settings GUI.color = MainEditor.GetEditorColor; GUILayout.Label("Socket Utilities Settings", EditorStyles.largeLabel); #region Socket Utilities Settings GUI.color = Color.white; GUILayout.BeginHorizontal(); GUILayout.Space(13); UtilitiesFoldout = EditorGUILayout.Foldout(UtilitiesFoldout, "Utilities Section Settings"); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Space(13); GUILayout.BeginVertical(); if (UtilitiesFoldout) { GUI.color = MainEditor.GetEditorColor; if (GUILayout.Button("Duplicate Socket (Inverse)")) { GameObject Duplicate = Instantiate(Target.gameObject, Target.transform.parent); Duplicate.name = Target.transform.name; Vector3 Inverse = new Vector3(-Target.transform.localPosition.x, Target.transform.localPosition.y, -Target.transform.localPosition.z); Duplicate.transform.localPosition = Inverse; Selection.activeGameObject = Duplicate; } GUI.color = Color.white; } GUILayout.EndVertical(); GUILayout.EndHorizontal(); #endregion Socket Utilities Settings GUI.color = MainEditor.GetEditorColor; GUILayout.Label("Socket Add-Ons Settings", EditorStyles.largeLabel); #region Socket Add-Ons Settings GUI.color = Color.white; GUILayout.BeginHorizontal(); GUILayout.Space(13); AddonsFoldout = EditorGUILayout.Foldout(AddonsFoldout, "Add-Ons Section Settings"); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Space(13); GUILayout.BeginVertical(); if (AddonsFoldout) { MainEditor.DrawAddons(Target, AddOnTarget.SocketBehaviour); } GUILayout.EndVertical(); GUILayout.EndHorizontal(); #endregion Socket Add-Ons Settings GUILayout.EndVertical(); GUILayout.EndVertical(); #endregion Inspector GUILayout.Space(10); serializedObject.ApplyModifiedProperties(); if (CurrentOffset != null) { if (PreviewPart != null) { PreviewPart.transform.position = Target.transform.TransformPoint(CurrentOffset.Position); PreviewPart.transform.rotation = Target.transform.rotation * Quaternion.Euler(CurrentOffset.Rotation); } } if (GUI.changed) { Target.PartOffsets = Target.PartOffsets.ToList().OrderBy(item => item.Part.Id).ToList(); } }
/// <summary> /// This method allows to move the preview only on available socket(s). /// </summary> public void UpdateSnapsMovement(SocketBehaviour[] sockets) { if (CurrentPreview == null) { return; } float ClosestAngle = Mathf.Infinity; CurrentSocket = null; for (int i = 0; i < sockets.Length; i++) { PartBehaviour Part = sockets[i].AttachedPart; if (Part == null || Part.Sockets.Length == 0) { continue; } for (int x = 0; x < Part.Sockets.Length; x++) { SocketBehaviour Socket = RayDetection == DetectionType.Overlap ? Part.Sockets[x] : sockets[i]; if (Socket != null) { if (Socket.gameObject.activeSelf && !Socket.IsDisabled) { if (Socket.AllowPart(SelectedPrefab) && !Part.AvoidAnchoredOnSocket) { if (RayDetection == DetectionType.Overlap) { if ((Socket.transform.position - (CameraType != RayType.TopDown ? GetTransform.position : TopDownHit.point)).sqrMagnitude < Mathf.Pow(CameraType != RayType.TopDown ? ActionDistance : SnapThreshold, 2)) { float Angle = Vector3.Angle(GetRay().direction, Socket.transform.position - GetRay().origin); if (Angle < ClosestAngle && Angle < OverlapAngles) { ClosestAngle = Angle; if (CameraType != RayType.TopDown && CurrentSocket == null) { CurrentSocket = Socket; } else { CurrentSocket = Socket; } } } } else { CurrentSocket = Socket; } } } } } } if (CurrentSocket != null) { PartOffset Offset = CurrentSocket.GetOffsetPart(SelectedPrefab.Id); if (CurrentSocket.CheckOccupancy(SelectedPrefab)) { return; } if (Offset != null) { CurrentPreview.transform.position = CurrentSocket.transform.position + CurrentSocket.transform.TransformVector(Offset.Position); CurrentPreview.transform.rotation = CurrentSocket.transform.rotation * (CurrentPreview.RotateOnSockets ? Quaternion.Euler(Offset.Rotation + CurrentRotationOffset) : Quaternion.Euler(Offset.Rotation)); if (Offset.UseCustomScale) { CurrentPreview.transform.localScale = Offset.Scale; } LastSocket = CurrentSocket; HasSocket = true; return; } } UpdateFreeMovement(); }