我正在使用 Minions Art 草系统,我希望能够从另一个脚本调用并重新生成第 301 行上的当前网格,我无法找到一种方法与另一个脚本上的任何内容进行交互,所以当我生成网格时,它会生成草
https://www.patreon.com/posts/grass-system-urp-83683483
我还使用塞巴斯蒂安·拉格斯程序生成教程,使用衰减贴图
https://www.youtube.com/watch?v=wbpMiKiSKm8&list=PLFt_AvWsXl0eBW2EiBtl_sxmDtSgZBxB3
using System.Collections.Generic;
using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEditorInternal;
using UnityEngine;
using UnityEngine.SceneManagement;
public class GrassPainterWindow : EditorWindow
{
public MapGenerator mapGenerator;
// main tabs
readonly string[] mainTabBarStrings = { "Paint/Edit", "Flood", "Generate", "General Settings" };
int mainTab_current;
Vector2 scrollPos;
bool paintModeActive;
readonly string[] toolbarStrings = { "Add", "Remove", "Edit", "Reproject" };
readonly string[] toolbarStringsEdit = { "Edit Colors", "Edit Length/Width", "Both" };
Vector3 hitPos;
Vector3 hitNormal;
[SerializeField]
SO_GrassToolSettings toolSettings;
// options
[HideInInspector]
public int toolbarInt = 0;
[HideInInspector]
public int toolbarIntEdit = 0;
public Material mat;
public List<GrassData> grassData = new();
[HideInInspector]
int grassAmount = 0;
Ray ray;
// raycast vars
[HideInInspector]
public Vector3 hitPosGizmo;
Vector3 mousePos;
RaycastHit[] terrainHit;
private int flowTimer;
private Vector3 lastPosition = Vector3.zero;
[SerializeField]
GameObject grassObject;
GrassComputeScript grassCompute;
NativeArray<float> sizes;
NativeArray<float> cumulativeSizes;
NativeArray<float> total;
Vector3 cachedPos;
bool showLayers;
[MenuItem("Tools/Grass Tool")]
static void Init()
{
Debug.Log("init");
// Get existing open window or if none, make a new one:
GrassPainterWindow window = (GrassPainterWindow)EditorWindow.GetWindow(typeof(GrassPainterWindow), false, "Grass Tool", true);
var icon = EditorGUIUtility.FindTexture("tree_icon");
SO_GrassToolSettings m_toolSettings = (SO_GrassToolSettings)AssetDatabase.LoadAssetAtPath("Assets/Settings/grassToolSettings.asset", typeof(SO_GrassToolSettings));
if (m_toolSettings == null)
{
Debug.Log("creating new one");
m_toolSettings = CreateInstance<SO_GrassToolSettings>();
AssetDatabase.CreateAsset(m_toolSettings, "Assets/Settings/grassToolSettings.asset");
m_toolSettings.CreateNewLayers();
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
window.titleContent = new GUIContent("Grass Tool", icon);
window.toolSettings = m_toolSettings;
window.Show();
MapGenerator mapGenerator = FindObjectOfType<MapGenerator>();
}
private void OnGUI()
{
scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
if (GUILayout.Button("Manual Update"))
{
grassCompute.Reset();
}
grassObject = (GameObject)EditorGUILayout.ObjectField("Grass Compute Object", grassObject, typeof(GameObject), true);
if (grassObject == null)
{
grassObject = FindObjectOfType<GrassComputeScript>()?.gameObject;
}
if (grassObject != null)
{
grassCompute = grassObject.GetComponent<GrassComputeScript>();
grassCompute.currentPresets = (SO_GrassSettings)EditorGUILayout.ObjectField("Grass Settings Object", grassCompute.currentPresets, typeof(SO_GrassSettings), false);
if (grassCompute.SetGrassPaintedDataList.Count > 0)
{
grassData = grassCompute.SetGrassPaintedDataList;
grassAmount = grassData.Count;
}
else
{
grassData.Clear();
}
if (grassCompute.currentPresets == null)
{
EditorGUILayout.LabelField("No Grass Settings Set, create or assign one first. \n Create > Utility> Grass Settings", GUILayout.Height(150));
EditorGUILayout.EndScrollView();
return;
}
}
else
{
if (GUILayout.Button("Create Grass Object"))
{
if (EditorUtility.DisplayDialog("Create a new Grass Object?",
"No Grass Object Found, create a new Object?", "Yes", "No"))
{
CreateNewGrassObject();
}
}
EditorGUILayout.LabelField("No Grass System Holder found, create a new one", EditorStyles.label);
EditorGUILayout.EndScrollView();
return;
}
EditorGUILayout.Separator();
EditorGUILayout.BeginHorizontal();
grassCompute.currentPresets.materialToUse = (Material)EditorGUILayout.ObjectField("Grass Material", grassCompute.currentPresets.materialToUse, typeof(Material), false);
EditorGUILayout.EndHorizontal();
EditorGUILayout.Separator();
EditorGUILayout.LabelField("Total Grass Amount: " + grassAmount.ToString(), EditorStyles.label);
EditorGUILayout.BeginHorizontal();
mainTab_current = GUILayout.Toolbar(mainTab_current, mainTabBarStrings, GUILayout.Height(30));
EditorGUILayout.EndHorizontal();
EditorGUILayout.Separator();
EditorGUILayout.Separator();
switch (mainTab_current)
{
case 0: //paint
ShowPaintPanel();
break;
case 1: // flood
ShowFloodPanel();
break;
case 2: // generate
ShowGeneratePanel();
break;
case 3: //settings
ShowMainSettingsPanel();
break;
}
if (GUILayout.Button("Clear Grass"))
{
if (EditorUtility.DisplayDialog("Clear All Grass?",
"Are you sure you want to clear the grass?", "Clear", "Don't Clear"))
{
ClearMesh();
}
}
EditorGUILayout.EndScrollView();
EditorUtility.SetDirty(toolSettings);
EditorUtility.SetDirty(grassCompute.currentPresets);
}
void ShowFloodPanel()
{
EditorGUILayout.LabelField("Flood Options", EditorStyles.boldLabel);
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("Flood Length/Width"))
{
FloodLengthAndWidth();
}
if (GUILayout.Button("Flood Colors"))
{
FloodColor();
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.Separator();
EditorGUILayout.LabelField("Width and Length ", EditorStyles.boldLabel);
toolSettings.sizeWidth = EditorGUILayout.Slider("Grass Width", toolSettings.sizeWidth, 0.01f, 2f);
toolSettings.sizeLength = EditorGUILayout.Slider("Grass Length", toolSettings.sizeLength, 0.01f, 2f);
EditorGUILayout.Separator();
EditorGUILayout.LabelField("Color", EditorStyles.boldLabel);
toolSettings.AdjustedColor = EditorGUILayout.ColorField("Brush Color", toolSettings.AdjustedColor);
EditorGUILayout.LabelField("Random Color Variation", EditorStyles.boldLabel);
toolSettings.rangeR = EditorGUILayout.Slider("Red", toolSettings.rangeR, 0f, 1f);
toolSettings.rangeG = EditorGUILayout.Slider("Green", toolSettings.rangeG, 0f, 1f);
toolSettings.rangeB = EditorGUILayout.Slider("Blue", toolSettings.rangeB, 0f, 1f);
}
void ShowGeneratePanel()
{
toolSettings.grassAmountToGenerate = EditorGUILayout.IntField("Grass Place Max Amount", toolSettings.grassAmountToGenerate);
toolSettings.generationDensity = EditorGUILayout.Slider("Grass Place Density", toolSettings.generationDensity, 0.01f, 1f);
EditorGUILayout.Separator();
LayerMask tempMask0 = EditorGUILayout.MaskField("Blocking Mask", InternalEditorUtility.LayerMaskToConcatenatedLayersMask(toolSettings.paintBlockMask), InternalEditorUtility.layers);
toolSettings.paintBlockMask = InternalEditorUtility.ConcatenatedLayersMaskToLayerMask(tempMask0);
toolSettings.VertexColorSettings = (SO_GrassToolSettings.VertexColorSetting)EditorGUILayout.EnumPopup("Block On vertex Colors", toolSettings.VertexColorSettings);
toolSettings.VertexFade = (SO_GrassToolSettings.VertexColorSetting)EditorGUILayout.EnumPopup("Fade on Vertex Colors", toolSettings.VertexFade);
EditorGUILayout.Separator();
EditorGUILayout.LabelField("Width and Length ", EditorStyles.boldLabel);
toolSettings.sizeWidth = EditorGUILayout.Slider("Grass Width", toolSettings.sizeWidth, 0.01f, 2f);
toolSettings.sizeLength = EditorGUILayout.Slider("Grass Length", toolSettings.sizeLength, 0.01f, 2f);
EditorGUILayout.Separator();
EditorGUILayout.LabelField("Color", EditorStyles.boldLabel);
toolSettings.AdjustedColor = EditorGUILayout.ColorField("Brush Color", toolSettings.AdjustedColor);
EditorGUILayout.LabelField("Random Color Variation", EditorStyles.boldLabel);
toolSettings.rangeR = EditorGUILayout.Slider("Red", toolSettings.rangeR, 0f, 1f);
toolSettings.rangeG = EditorGUILayout.Slider("Green", toolSettings.rangeG, 0f, 1f);
toolSettings.rangeB = EditorGUILayout.Slider("Blue", toolSettings.rangeB, 0f, 1f);
EditorGUILayout.Separator();
EditorGUILayout.LabelField("Normal Limit", EditorStyles.boldLabel);
toolSettings.normalLimit = EditorGUILayout.Slider("Normal Limit", toolSettings.normalLimit, 0f, 1f);
EditorGUILayout.Separator();
showLayers = EditorGUILayout.Foldout(showLayers, "Layer Settings(Cutoff Value, Fade Height Toggle");
if (showLayers)
{
for (int i = 0; i < toolSettings.layerBlocking.Length; i++)
{
EditorGUILayout.BeginHorizontal();
toolSettings.layerBlocking[i] = EditorGUILayout.Slider(i.ToString(), toolSettings.layerBlocking[i], 0f, 1f);
toolSettings.layerFading[i] = EditorGUILayout.Toggle(toolSettings.layerFading[i]);
EditorGUILayout.EndHorizontal();
}
}
GameObject[] selection = Selection.gameObjects;
selection = GameObject.FindGameObjectsWithTag("TerrainMesh");
if (GUILayout.Button("Add Positions From Mesh"))
{
if (selection == null)
{
// no objects selected
}
else
{
Undo.RegisterCompleteObjectUndo(this, "Add new Positions from Mesh(es)");
for (int i = 0; i < selection.Length; i++)
{
GeneratePositions(selection[i]);
}
}
}
if (GUILayout.Button("Regenerate on current Mesh (Clears Current)"))
{
if (selection == null)
{
// no object selected
return;
}
else
{
ClearMesh();
Undo.RegisterCompleteObjectUndo(this, "Regenerated Positions on Mesh(es)");
for (int i = 0; i < selection.Length; i++)
{
GeneratePositions(selection[i]);
}
}
}
EditorGUILayout.Separator();
}
void ShowPaintPanel()
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Paint Mode:", EditorStyles.boldLabel);
paintModeActive = EditorGUILayout.Toggle(paintModeActive);
EditorGUILayout.EndHorizontal();
EditorGUILayout.Separator();
EditorGUILayout.LabelField("Hit Settings", EditorStyles.boldLabel);
LayerMask tempMask = EditorGUILayout.MaskField("Hit Mask", InternalEditorUtility.LayerMaskToConcatenatedLayersMask(toolSettings.hitMask), InternalEditorUtility.layers);
toolSettings.hitMask = InternalEditorUtility.ConcatenatedLayersMaskToLayerMask(tempMask);
LayerMask tempMask2 = EditorGUILayout.MaskField("Painting Mask", InternalEditorUtility.LayerMaskToConcatenatedLayersMask(toolSettings.paintMask), InternalEditorUtility.layers);
toolSettings.paintMask = InternalEditorUtility.ConcatenatedLayersMaskToLayerMask(tempMask2);
EditorGUILayout.Separator();
EditorGUILayout.LabelField("Paint Status (Right-Mouse Button to paint)", EditorStyles.boldLabel);
toolbarInt = GUILayout.Toolbar(toolbarInt, toolbarStrings);
EditorGUILayout.Separator();
EditorGUILayout.LabelField("Brush Settings", EditorStyles.boldLabel);
toolSettings.brushSize = EditorGUILayout.Slider("Brush Size", toolSettings.brushSize, 0.1f, 50f);
if (toolbarInt == 0)
{
toolSettings.normalLimit = EditorGUILayout.Slider("Normal Limit", toolSettings.normalLimit, 0f, 1f);
toolSettings.density = EditorGUILayout.Slider("Density", toolSettings.density, 0.1f, 10f);
}
if (toolbarInt == 2)
{
toolbarIntEdit = GUILayout.Toolbar(toolbarIntEdit, toolbarStringsEdit);
EditorGUILayout.Separator();
EditorGUILayout.LabelField("Soft Falloff Settings", EditorStyles.boldLabel);
toolSettings.brushFalloffSize = EditorGUILayout.Slider("Brush Falloff Size", toolSettings.brushFalloffSize, 0.01f, 1f);
toolSettings.Flow = EditorGUILayout.Slider("Brush Flow", toolSettings.Flow, 0.1f, 10f);
EditorGUILayout.Separator();
EditorGUILayout.LabelField("Adjust Width and Length Gradually", EditorStyles.boldLabel);
toolSettings.adjustWidth = EditorGUILayout.Slider("Grass Width Adjustment", toolSettings.adjustWidth, -1f, 1f);
toolSettings.adjustLength = EditorGUILayout.Slider("Grass Length Adjustment", toolSettings.adjustLength, -1f, 1f);
toolSettings.adjustWidthMax = EditorGUILayout.Slider("Grass Width Adjustment Max Clamp", toolSettings.adjustWidthMax, 0.01f, 3f);
toolSettings.adjustHeightMax = EditorGUILayout.Slider("Grass Length Adjustment Max Clamp", toolSettings.adjustHeightMax, 0.01f, 3f);
EditorGUILayout.Separator();
}
if (toolbarInt == 0 || toolbarInt == 2)
{
EditorGUILayout.Separator();
if (toolbarInt == 0)
{
EditorGUILayout.LabelField("Width and Length ", EditorStyles.boldLabel);
toolSettings.sizeWidth = EditorGUILayout.Slider("Grass Width", toolSettings.sizeWidth, 0.01f, 2f);
toolSettings.sizeLength = EditorGUILayout.Slider("Grass Length", toolSettings.sizeLength, 0.01f, 2f);
}
EditorGUILayout.Separator();
EditorGUILayout.LabelField("Color", EditorStyles.boldLabel);
toolSettings.AdjustedColor = EditorGUILayout.ColorField("Brush Color", toolSettings.AdjustedColor);
EditorGUILayout.LabelField("Random Color Variation", EditorStyles.boldLabel);
toolSettings.rangeR = EditorGUILayout.Slider("Red", toolSettings.rangeR, 0f, 1f);
toolSettings.rangeG = EditorGUILayout.Slider("Green", toolSettings.rangeG, 0f, 1f);
toolSettings.rangeB = EditorGUILayout.Slider("Blue", toolSettings.rangeB, 0f, 1f);
}
if (toolbarInt == 3)
{
EditorGUILayout.Separator();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Reprojection Y Offset", EditorStyles.boldLabel);
toolSettings.reprojectOffset = EditorGUILayout.FloatField(toolSettings.reprojectOffset);
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.Separator();
}
void ShowMainSettingsPanel()
{
EditorGUILayout.LabelField("Blade Mix/Max Settings", EditorStyles.boldLabel);
EditorGUILayout.BeginHorizontal();
grassCompute.currentPresets.MinWidth = EditorGUILayout.FloatField(grassCompute.currentPresets.MinWidth);
grassCompute.currentPresets.MaxWidth = EditorGUILayout.FloatField(grassCompute.currentPresets.MaxWidth);
EditorGUILayout.EndHorizontal();
EditorGUILayout.MinMaxSlider("Blade Width Min/Max", ref grassCompute.currentPresets.MinWidth, ref grassCompute.currentPresets.MaxWidth, 0.01f, 1f);
EditorGUILayout.BeginHorizontal();
grassCompute.currentPresets.MinHeight = EditorGUILayout.FloatField(grassCompute.currentPresets.MinHeight);
grassCompute.currentPresets.MaxHeight = EditorGUILayout.FloatField(grassCompute.currentPresets.MaxHeight);
EditorGUILayout.EndHorizontal();
EditorGUILayout.MinMaxSlider("Blade Height Min/Max", ref grassCompute.currentPresets.MinHeight, ref grassCompute.currentPresets.MaxHeight, 0.01f, 1f);
EditorGUILayout.Separator();
EditorGUILayout.LabelField("Random Height", EditorStyles.boldLabel);
grassCompute.currentPresets.grassRandomHeightMin = EditorGUILayout.FloatField("Min Random:", grassCompute.currentPresets.grassRandomHeightMin);
grassCompute.currentPresets.grassRandomHeightMax = EditorGUILayout.FloatField("Max Random:", grassCompute.currentPresets.grassRandomHeightMax);
EditorGUILayout.MinMaxSlider("Random Grass Height", ref grassCompute.currentPresets.grassRandomHeightMin, ref grassCompute.currentPresets.grassRandomHeightMax, -5f, 5f);
EditorGUILayout.Separator();
EditorGUILayout.LabelField("Blade Shape Settings", EditorStyles.boldLabel);
grassCompute.currentPresets.bladeRadius = EditorGUILayout.Slider("Blade Radius", grassCompute.currentPresets.bladeRadius, 0f, 2f);
grassCompute.currentPresets.bladeForwardAmount = EditorGUILayout.Slider("Blade Forward", grassCompute.currentPresets.bladeForwardAmount, 0f, 2f);
grassCompute.currentPresets.bladeCurveAmount = EditorGUILayout.Slider("Blade Curve", grassCompute.currentPresets.bladeCurveAmount, 0f, 2f);
grassCompute.currentPresets.bottomWidth = EditorGUILayout.Slider("Bottom Width", grassCompute.currentPresets.bottomWidth, 0f, 2f);
EditorGUILayout.Separator();
EditorGUILayout.LabelField("Blade Amount Settings", EditorStyles.boldLabel);
grassCompute.currentPresets.allowedBladesPerVertex = EditorGUILayout.IntSlider("Allowed Blades Per Vertex", grassCompute.currentPresets.allowedBladesPerVertex, 1, 10);
grassCompute.currentPresets.allowedSegmentsPerBlade = EditorGUILayout.IntSlider("Allowed Segments Per Blade", grassCompute.currentPresets.allowedSegmentsPerBlade, 1, 4);
EditorGUILayout.Separator();
EditorGUILayout.LabelField("Wind Settings", EditorStyles.boldLabel);
grassCompute.currentPresets.windSpeed = EditorGUILayout.Slider("Wind Speed", grassCompute.currentPresets.windSpeed, -2f, 2f);
grassCompute.currentPresets.windStrength = EditorGUILayout.Slider("Wind Strength", grassCompute.currentPresets.windStrength, -2f, 2f);
EditorGUILayout.Separator();
EditorGUILayout.LabelField("Tinting Settings", EditorStyles.boldLabel);
grassCompute.currentPresets.topTint = EditorGUILayout.ColorField("Top Tint", grassCompute.currentPresets.topTint);
grassCompute.currentPresets.bottomTint = EditorGUILayout.ColorField("Bottom Tint", grassCompute.currentPresets.bottomTint);
EditorGUILayout.Separator();
EditorGUILayout.LabelField("LOD/Culling Settings", EditorStyles.boldLabel);
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Show Culling Bounds:", EditorStyles.boldLabel);
grassCompute.currentPresets.drawBounds = EditorGUILayout.Toggle(grassCompute.currentPresets.drawBounds);
EditorGUILayout.EndHorizontal();
grassCompute.currentPresets.minFadeDistance = EditorGUILayout.FloatField("Min Fade Distance", grassCompute.currentPresets.minFadeDistance);
grassCompute.currentPresets.maxDrawDistance = EditorGUILayout.FloatField("Max Draw Distance", grassCompute.currentPresets.maxDrawDistance);
grassCompute.currentPresets.cullingTreeDepth = EditorGUILayout.IntField("Culling Tree Depth", grassCompute.currentPresets.cullingTreeDepth);
EditorGUILayout.Separator();
EditorGUILayout.LabelField("Other Settings", EditorStyles.boldLabel);
grassCompute.currentPresets.affectStrength = EditorGUILayout.FloatField("Interactor Bend Strength", grassCompute.currentPresets.affectStrength);
grassCompute.currentPresets.castShadow = (UnityEngine.Rendering.ShadowCastingMode)EditorGUILayout.EnumPopup("Shadow Settings", grassCompute.currentPresets.castShadow);
}
void CreateNewGrassObject()
{
grassObject = new GameObject();
grassObject.name = "Grass System - Holder";
grassCompute = grassObject.AddComponent<GrassComputeScript>();
// setup object
grassData = new List<GrassData>();
grassCompute.SetGrassPaintedDataList = grassData;
}
void OnSceneGUI(SceneView sceneView)
{
if (this.hasFocus && paintModeActive)
{
DrawHandles();
}
}
从你的问题和巨大的代码片段中很难看出。
一般来说:通过创建方法
public static
,以便可以从任何地方调用它(当然假设包装类型是可见的)...可能需要进行一些重构,以不依赖于任何实例字段,而是采用参数(使用ref
/out
(如需要)
我没有数行数,但我只是假设你指的是
CreateNewGrassObject
所以我会将其转换为
public static GrassComputeScript CreateNewGrassObject()
{
var grassObject = new GameObject();
grassObject.name = "Grass System - Holder";
var grassCompute = grassObject.AddComponent<GrassComputeScript>();
// setup object
var grassData = new List<GrassData>();
grassCompute.SetGrassPaintedDataList = grassData;
return grassCompute;
}
所有其他本地值也可以通过例如
var newGrass = GrassPainterWindow.CreateNewGrassObject();
var gameObject = newGrass.gameObject;
var grassData = newGrass.SetGrassPaintedDataList;
由于它不包含特定于编辑器的代码,您甚至可以考虑将其移至类似的帮助器类中
public static class GrassTools
{
public static GrassComputeScript CreateNewGrassObject()
{
...
}
}
因此即使在构建中也可以使用。