/// <summary> /// Add a new prefab to the spline /// </summary> // TODO: rewrite, use different approach: Use fake splines around the current spline. That way the separation distance doesn't matter // and you could have small prefabs on the outer spline, and big prefabs on the inner spline and they would distribute better private GameObject AddPrefab(ref int prefabInstanceIndex, Vector3 position, Vector3 direction, List <SplinePoint> splinePoints, int currentSplinePointIndex) { GameObject instance = null; // offset for lanes: lanes are from left to right, center is the spline. // so a spline with 5 lanes has these offset lanes: -2, -1, 0, 1, 2 int offsetLane = -prefabPainter.splineSettings.lanes / 2; for (var lane = 1; lane <= prefabPainter.splineSettings.lanes; lane++) { // skip center lane if requestred if (prefabPainter.splineSettings.skipCenterLane && offsetLane == 0) { offsetLane++; continue; } // get settings for the prefab to instantiate PrefabSettings prefabSettings = prefabPainter.GetPrefabSettings(); // check if we have settings at all if (prefabSettings == null) { return(null); } // instance will be created or used => advance index prefabInstanceIndex++; // check if we have to create a new instance or use an existing one if (prefabPainter.splineSettings.reusePrefabs) { if (prefabInstanceIndex < prefabPainter.splineSettings.prefabInstances.Count) { instance = prefabPainter.splineSettings.prefabInstances[prefabInstanceIndex]; } } // create instance if we don't have one yet if (instance == null) { instance = GameObject.Instantiate(prefabSettings.prefab); prefabPainter.splineSettings.prefabInstances.Add(instance); } // reset position & rotation instance.transform.position = position; instance.transform.rotation = Quaternion.identity; ApplyPrefabSettings(offsetLane, prefabSettings, instance, position, direction, splinePoints, currentSplinePointIndex); // reparent the child to the container instance.transform.parent = prefabPainter.container.transform; offsetLane++; } return(instance); }
public PrefabSettings GetPrefabSettings() { PrefabSettings selectedItem = GetRandomWeightedPrefab(); if (selectedItem == null) { Debug.LogError("No prefab is active! At least 1 prefab must be active."); return(null); } return(selectedItem); }
private void AddPrefab(GameObject prefab, PrefabSettingsTemplate template) { // new settings PrefabSettings prefabSettings = new PrefabSettings(); prefabSettings.ApplyTemplate(template); // initialize with dropped prefab prefabSettings.prefab = prefab; editor.newDraggedPrefabs.Add(prefabSettings); }
/// <summary> /// Ensure the prefab has a VegetationItemID /// </summary> /// <param name="prefabSettings"></param> private void updateVSProSettings(PrefabSettings prefabSettings, bool forceVegetationItemIDUpdate) { #if VEGETATION_STUDIO_PRO GameObject prefab = prefabSettings.prefab; // check if we have a VegetationItemID, otherwise create it using the current prefab if (string.IsNullOrEmpty(prefabSettings.vspro_VegetationItemID) || forceVegetationItemIDUpdate) { // get the asset guid if (string.IsNullOrEmpty(prefabSettings.assetGUID)) { string assetPath = AssetDatabase.GetAssetPath(prefab); if (!string.IsNullOrEmpty(assetPath)) { string assetGUID = AssetDatabase.AssetPathToGUID(assetPath); prefabSettings.assetGUID = assetGUID; } } // if we have a guid, get the vs pro id if (!string.IsNullOrEmpty(prefabSettings.assetGUID)) { // get the VegetationItemID prefabSettings.vspro_VegetationItemID = VegetationStudioManager.GetVegetationItemID(prefabSettings.assetGUID); // if the vegetation item id doesn't exist, create a new vegetation item if (string.IsNullOrEmpty(prefabSettings.vspro_VegetationItemID)) { VegetationType vegetationType = VegetationType.Objects; bool enableRuntimeSpawn = false; // no runtime spawn, we want it spawned from persistent storage BiomeType biomeType = BiomeType.Default; prefabSettings.vspro_VegetationItemID = VegetationStudioManager.AddVegetationItem(prefab, vegetationType, enableRuntimeSpawn, biomeType); } } else { Debug.LogError("Can't get assetGUID for prefab " + prefab); } } if (string.IsNullOrEmpty(prefabSettings.vspro_VegetationItemID)) { Debug.LogError("Can't get VegetationItemId for prefab " + prefab); } #endif }
public void AddNewPrefab(PrefabSettings prefabSettings, Vector3 newPosition, Quaternion newRotation, Vector3 newLocalScale) { #if VEGETATION_STUDIO_PRO // ensure the prefab has a VegetationItemID updateVSProSettings(prefabSettings, true); if (!string.IsNullOrEmpty(prefabSettings.vspro_VegetationItemID)) { string vegetationItemID = prefabSettings.vspro_VegetationItemID; Vector3 worldPosition = newPosition; Vector3 scale = newLocalScale; // TODO local or world? Quaternion rotation = newRotation; bool applyMeshRotation = true; // TODO ??? float distanceFalloff = 1f; // TODO ??? bool clearCellCache = true; // TODO ??? byte vegetationSourceID = Constants.VegetationStudioPro_SourceId; VegetationStudioManager.AddVegetationItemInstance(vegetationItemID, worldPosition, scale, rotation, applyMeshRotation, vegetationSourceID, distanceFalloff, clearCellCache); } #endif }
public void OnInspectorGUI() { GUILayout.BeginVertical("box"); { EditorGUILayout.LabelField("Prefabs", GUIStyles.BoxTitleStyle); GUILayout.BeginHorizontal(); { GUILayout.BeginVertical(); { // change background color in case there are no prefabs yet if (gizmo.prefabSettingsList.Count == 0) { editor.SetErrorBackgroundColor(); } // drop area Rect prefabDropArea = GUILayoutUtility.GetRect(0.0f, 34.0f, GUIStyles.DropAreaStyle, GUILayout.ExpandWidth(true)); // drop area box with background color and info text GUI.color = GUIStyles.DropAreaBackgroundColor; GUI.Box(prefabDropArea, "Drop prefabs here in order to use them", GUIStyles.DropAreaStyle); GUI.color = GUIStyles.DefaultBackgroundColor; editor.SetDefaultBackgroundColor(); Event evt = Event.current; switch (evt.type) { case EventType.DragUpdated: case EventType.DragPerform: if (prefabDropArea.Contains(evt.mousePosition)) { DragAndDrop.visualMode = DragAndDropVisualMode.Copy; if (evt.type == EventType.DragPerform) { DragAndDrop.AcceptDrag(); // list of new prefabs that should be created via drag/drop // we can't do it in the drag/drop code itself, we'd get exceptions like // ArgumentException: Getting control 12's position in a group with only 12 controls when doing dragPerform. Aborting // followed by // Unexpected top level layout group! Missing GUILayout.EndScrollView/EndVertical/EndHorizontal? UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr) // they must be added when everything is done (currently at the end of this method) editor.newDraggedPrefabs = new List <PrefabSettings>(); foreach (Object droppedObject in DragAndDrop.objectReferences) { // allow only prefabs if (PrefabUtility.GetPrefabAssetType(droppedObject) == PrefabAssetType.NotAPrefab) { Debug.Log("Not a prefab: " + droppedObject); continue; } // new settings PrefabSettings prefabSettings = new PrefabSettings(); // initialize with dropped prefab prefabSettings.prefab = droppedObject as GameObject; editor.newDraggedPrefabs.Add(prefabSettings); } } } break; } } GUILayout.EndVertical(); } GUILayout.EndHorizontal(); for (int i = 0; i < gizmo.prefabSettingsList.Count; i++) { if (i > 0) { editor.addGUISeparator(); } PrefabSettings prefabSettings = this.gizmo.prefabSettingsList[i]; GUILayout.BeginHorizontal(); { // preview // try to get the asset preview Texture2D previewTexture = AssetPreview.GetAssetPreview(prefabSettings.prefab); // if no asset preview available, try to get the mini thumbnail if (!previewTexture) { previewTexture = AssetPreview.GetMiniThumbnail(prefabSettings.prefab); } // if a preview is available, paint it if (previewTexture) { //GUILayout.Label(previewTexture, EditorStyles.objectFieldThumb, GUILayout.Width(50), GUILayout.Height(50)); // without border, but with size GUILayout.Label(previewTexture, GUILayout.Width(50), GUILayout.Height(50)); // without border, but with size //GUILayout.Box(previewTexture); // with border //GUILayout.Label(previewTexture); // no border //GUILayout.Box(previewTexture, GUILayout.Width(50), GUILayout.Height(50)); // with border and size //EditorGUI.DrawPreviewTexture(new Rect(25, 60, 100, 100), previewTexture); // draws it in absolute coordinates } // right alin the buttons GUILayout.FlexibleSpace(); if (GUILayout.Button("Add", EditorStyles.miniButton)) { this.gizmo.prefabSettingsList.Insert(i + 1, new PrefabSettings()); } if (GUILayout.Button("Duplicate", EditorStyles.miniButton)) { PrefabSettings newPrefabSettings = prefabSettings.Clone(); this.gizmo.prefabSettingsList.Insert(i + 1, newPrefabSettings); } if (GUILayout.Button("Reset", EditorStyles.miniButton)) { // remove existing this.gizmo.prefabSettingsList.RemoveAt(i); // add new this.gizmo.prefabSettingsList.Insert(i, new PrefabSettings()); } if (GUILayout.Button("Remove", EditorStyles.miniButton)) { this.gizmo.prefabSettingsList.Remove(prefabSettings); } } GUILayout.EndHorizontal(); GUILayout.Space(4); prefabSettings.prefab = (GameObject)EditorGUILayout.ObjectField("Prefab", prefabSettings.prefab, typeof(GameObject), true); prefabSettings.active = EditorGUILayout.Toggle("Active", prefabSettings.active); prefabSettings.probability = EditorGUILayout.Slider("Probability", prefabSettings.probability, 0, 1); // scale prefabSettings.changeScale = EditorGUILayout.Toggle("Change Scale", prefabSettings.changeScale); if (prefabSettings.changeScale) { prefabSettings.scaleMin = EditorGUILayout.FloatField("Scale Min", prefabSettings.scaleMin); prefabSettings.scaleMax = EditorGUILayout.FloatField("Scale Max", prefabSettings.scaleMax); } // position prefabSettings.positionOffset = EditorGUILayout.Vector3Field("Position Offset", prefabSettings.positionOffset); // rotation prefabSettings.rotationOffset = EditorGUILayout.Vector3Field("Rotation Offset", prefabSettings.rotationOffset); prefabSettings.randomRotation = EditorGUILayout.Toggle("Random Rotation", prefabSettings.randomRotation); // rotation limits if (prefabSettings.randomRotation) { EditorGuiUtilities.MinMaxEditor(" Rotation Limit X", ref prefabSettings.rotationMinX, ref prefabSettings.rotationMaxX, 0, 360); EditorGuiUtilities.MinMaxEditor(" Rotation Limit Y", ref prefabSettings.rotationMinY, ref prefabSettings.rotationMaxY, 0, 360); EditorGuiUtilities.MinMaxEditor(" Rotation Limit Z", ref prefabSettings.rotationMinZ, ref prefabSettings.rotationMaxZ, 0, 360); } // VS Pro Id #if VEGETATION_STUDIO_PRO EditorGUI.BeginDisabledGroup(true); EditorGUILayout.TextField("Asset GUID", prefabSettings.assetGUID); EditorGUILayout.TextField("VSPro Id", prefabSettings.vspro_VegetationItemID); EditorGUI.EndDisabledGroup(); #endif } } GUILayout.EndVertical(); }
private void ApplyPrefabSettings(int offsetLane, PrefabSettings prefabSettings, GameObject prefab, Vector3 currentPosition, Vector3 direction, List <SplinePoint> splinePoints, int currentSplinePointIndex) { // add prefab's position offset prefab.transform.position += prefabSettings.positionOffset; // lanes Vector3 splinePosition = prefab.transform.position; Quaternion splineRotation = Quaternion.LookRotation(direction); Vector3 addDistanceToDirection = Vector3.zero; if (offsetLane == 0) { // check if the objects should be aligned next to each other // TODO this is only done for the center lane currently; we don't have the information about the others // ie this only works in center lane mode currently if (prefabPainter.splineSettings.separation == SplineSettings.Separation.PrefabBounds) { // move along in the spline rotation, considering the radius addDistanceToDirection = splineRotation * prefab.transform.forward * GetDistanceToMove(prefab) / 2; } } // lane mode, all lanes except center else { // calculate offset distance to spline float offsetDistance = offsetLane * prefabPainter.splineSettings.laneDistance; // calculate the distance considering the spline direction //Vector3 distance = prefabPainter.splineSettings.lanePositionOffset - go.transform.position; addDistanceToDirection = splineRotation * prefab.transform.right * offsetDistance; } prefab.transform.position += addDistanceToDirection; // size if (prefabSettings.changeScale) { prefab.transform.localScale = Vector3.one * Random.Range(prefabSettings.scaleMin, prefabSettings.scaleMax); } // initial rotation Quaternion rotation = Quaternion.identity; switch (prefabPainter.splineSettings.instanceRotation) { case SplineSettings.Rotation.Spline: // rotation along spline rotation = Quaternion.LookRotation(direction); break; case SplineSettings.Rotation.Prefab: // rotation of the prefab if (prefabSettings.randomRotation) { float rotationX = Random.Range(prefabSettings.rotationMinX, prefabSettings.rotationMaxX); float rotationY = Random.Range(prefabSettings.rotationMinY, prefabSettings.rotationMaxY); float rotationZ = Random.Range(prefabSettings.rotationMinZ, prefabSettings.rotationMaxZ); rotation = Quaternion.Euler(rotationX, rotationY, rotationZ); } break; } // lerp rotation between control points along the spline if (prefabPainter.splineSettings.controlPointRotation) { /* * Quaternion controlPointRotation = prefabPainter.splineSettings.controlPoints[currentSplinePointIndex].rotation; * rotation *= controlPointRotation; */ int currentControlPointIndex = splinePoints[currentSplinePointIndex].startControlPointIndex; int nextControlPointIndex = currentControlPointIndex + 1; // check loop if (prefabPainter.splineSettings.loop) { if (nextControlPointIndex > prefabPainter.splineSettings.controlPoints.Count - 1) { nextControlPointIndex = 0; } } Vector3 currentControlPointPosition = prefabPainter.splineSettings.controlPoints[currentControlPointIndex].position; Vector3 nextControlPointPosition = prefabPainter.splineSettings.controlPoints[nextControlPointIndex].position; // the percentage that a spline point is between control points. ranges from 0 to 1 float percentageOnSegment = MathUtils.InverseLerp(currentControlPointPosition, nextControlPointPosition, currentPosition); // calculate lerp roation Quaternion currentControlPointRotation = prefabPainter.splineSettings.controlPoints[currentControlPointIndex].rotation; Quaternion nextControlPointRotation = prefabPainter.splineSettings.controlPoints[nextControlPointIndex].rotation; Quaternion lerpRotation = Quaternion.Lerp(currentControlPointRotation, nextControlPointRotation, percentageOnSegment); // add rotation rotation *= lerpRotation; } prefab.transform.rotation = rotation; // add prefab rotation offset prefab.transform.Rotate(prefabSettings.rotationOffset); }
private void AddNewPrefab(Vector3 position, Vector3 normal) { GameObject container = gizmo.container as GameObject; PrefabSettings prefabSettings = this.gizmo.GetPrefabSettings(); GameObject prefab = prefabSettings.prefab; /// /// Calculate position / rotation / scale /// // get new position Vector3 newPosition = position; // add offset newPosition += prefabSettings.positionOffset; Vector3 newLocalScale = prefabSettings.prefab.transform.localScale; // size if (prefabSettings.changeScale) { newLocalScale = Vector3.one * Random.Range(prefabSettings.scaleMin, prefabSettings.scaleMax); } // rotation Quaternion newRotation; if (prefabSettings.randomRotation) { float rotationX = Random.Range(prefabSettings.rotationMinX, prefabSettings.rotationMaxX); float rotationY = Random.Range(prefabSettings.rotationMinY, prefabSettings.rotationMaxY); float rotationZ = Random.Range(prefabSettings.rotationMinZ, prefabSettings.rotationMaxZ); newRotation = Quaternion.Euler(rotationX, rotationY, rotationZ); } else if (this.gizmo.brushSettings.alignToTerrain) { newRotation = Quaternion.FromToRotation(Vector3.up, normal); } else { newRotation = Quaternion.Euler(prefabSettings.rotationOffset); //rotation = Quaternion.identity; } /// /// create instance and apply position / rotation / scale /// // spawn item to vs pro if (gizmo.brushSettings.spawnToVSPro) { #if VEGETATION_STUDIO_PRO // ensure the prefab has a VegetationItemID updateVSProSettings(prefabSettings, true); if (!string.IsNullOrEmpty(prefabSettings.vspro_VegetationItemID)) { string vegetationItemID = prefabSettings.vspro_VegetationItemID; Vector3 worldPosition = position; Vector3 scale = newLocalScale; // TODO local or world? Quaternion rotation = newRotation; bool applyMeshRotation = true; // TODO ??? byte vegetationSourceID = 5; // TODO see PersistentVegetationStorageTools for constants. 5 = "Vegetation Studio - Painted" float distanceFalloff = 1f; // TODO ??? bool clearCellCache = true; // TODO ??? VegetationStudioManager.AddVegetationItemInstance(vegetationItemID, worldPosition, scale, rotation, applyMeshRotation, vegetationSourceID, distanceFalloff, clearCellCache); } #endif } // spawn item to scene else { // new prefab GameObject instance = PrefabUtility.InstantiatePrefab(prefab) as GameObject; instance.transform.position = newPosition; instance.transform.rotation = newRotation; instance.transform.localScale = newLocalScale; // attach as child of container instance.transform.parent = container.transform; Undo.RegisterCreatedObjectUndo(instance, "Instantiate Prefab"); } }
private void AddNewPrefab(Vector3 position, Vector3 normal) { GameObject container = editorTarget.container as GameObject; PrefabSettings prefabSettings = this.editorTarget.GetPrefabSettings(); GameObject prefab = prefabSettings.prefab; /// /// Calculate position / rotation / scale /// // get new position Vector3 newPosition = position; // add offset newPosition += prefabSettings.positionOffset; // auto physics height offset newPosition = ApplyAutoPhysicsHeightOffset(newPosition); Vector3 newLocalScale = prefabSettings.prefab.transform.localScale; // size if (prefabSettings.changeScale) { newLocalScale = Vector3.one * Random.Range(prefabSettings.scaleMin, prefabSettings.scaleMax); } // rotation Quaternion newRotation; if (prefabSettings.randomRotation) { float rotationX = Random.Range(prefabSettings.rotationMinX, prefabSettings.rotationMaxX); float rotationY = Random.Range(prefabSettings.rotationMinY, prefabSettings.rotationMaxY); float rotationZ = Random.Range(prefabSettings.rotationMinZ, prefabSettings.rotationMaxZ); newRotation = Quaternion.Euler(rotationX, rotationY, rotationZ); } else if (this.editorTarget.brushSettings.alignToTerrain) { newRotation = Quaternion.FromToRotation(Vector3.up, normal); } else { newRotation = Quaternion.Euler(prefabSettings.rotationOffset); //rotation = Quaternion.identity; } /// /// create instance and apply position / rotation / scale /// // spawn item to vs pro if (editorTarget.brushSettings.spawnToVSPro) { vegetationStudioProIntegration.AddNewPrefab(prefabSettings, newPosition, newRotation, newLocalScale); } // spawn item to scene else { // new prefab GameObject instance = PrefabUtility.InstantiatePrefab(prefab) as GameObject; instance.transform.position = newPosition; instance.transform.rotation = newRotation; instance.transform.localScale = newLocalScale; // attach as child of container instance.transform.parent = container.transform; Undo.RegisterCreatedObjectUndo(instance, "Instantiate Prefab"); if (editorTarget.spawnSettings.autoSimulationType != SpawnSettings.AutoSimulationType.None) { autoPhysicsCollection.Add(instance); } } }