This commit is contained in:
CortexCore
2025-03-14 21:04:19 +08:00
parent ff8670c453
commit 757ffe79ee
1282 changed files with 104378 additions and 3 deletions

View File

@@ -0,0 +1,28 @@
#if GRIFFIN
using UnityEditor;
namespace Pinwheel.Griffin
{
[CustomEditor(typeof(GGrassPrototypeGroup))]
public class GGrassPrototypeGroupInspector : Editor
{
private GGrassPrototypeGroup instance;
private void OnEnable()
{
instance = target as GGrassPrototypeGroup;
}
public override void OnInspectorGUI()
{
GGrassPrototypeGroupInspectorDrawer.Create(instance).DrawGUI();
EditorUtility.SetDirty(instance);
}
public override bool RequiresConstantRepaint()
{
return false;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: acb1d04844a29744f9f027be786c6da2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,241 @@
#if GRIFFIN
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
using System.IO;
namespace Pinwheel.Griffin
{
public class GGrassPrototypeGroupInspectorDrawer
{
private GGrassPrototypeGroup instance;
public GGrassPrototypeGroupInspectorDrawer(GGrassPrototypeGroup group)
{
instance = group;
}
public static GGrassPrototypeGroupInspectorDrawer Create(GGrassPrototypeGroup group)
{
return new GGrassPrototypeGroupInspectorDrawer(group);
}
public void DrawGUI()
{
DrawInstruction();
DrawPrototypesListGUI();
DrawAddPrototypeGUI();
GEditorCommon.DrawAffLinks(
"These lively vegetation assets can bring your project to life",
"https://assetstore.unity.com/packages/3d/vegetation/trees/polygon-nature-low-poly-3d-art-by-synty-120152",
"https://assetstore.unity.com/lists/stylized-vegetation-120082");
GEditorCommon.Separator();
DrawConvertAssetGUI();
}
private void DrawInstruction()
{
string label = "Instruction";
string id = "instruction" + instance.GetInstanceID().ToString();
GEditorCommon.Foldout(label, false, id, () =>
{
string text = string.Format(
"Some properties require Foliage Data to be processed on a terrain to take effect.\n" +
"Go to Terrain > Foliage > CONTEXT > Update Grasses to do it.");
EditorGUILayout.LabelField(text, GEditorCommon.WordWrapItalicLabel);
});
}
private void DrawPrototypesListGUI()
{
for (int i = 0; i < instance.Prototypes.Count; ++i)
{
GGrassPrototype p = instance.Prototypes[i];
string label = string.Empty;
if (p.Shape != GGrassShape.DetailObject)
label = p.Texture != null && !string.IsNullOrEmpty(p.Texture.name) ? p.Texture.name : "Grass " + i;
else
label = p.Prefab != null && !string.IsNullOrEmpty(p.Prefab.name) ? p.Prefab.name : "Grass " + i;
string id = "grassprototype" + i + instance.GetInstanceID().ToString();
int index = i;
GenericMenu menu = new GenericMenu();
menu.AddItem(
new GUIContent("Remove"),
false,
() => { ConfirmAndRemovePrototypeAtIndex(index); });
GEditorCommon.Foldout(label, false, id, () =>
{
EditorGUI.BeginChangeCheck();
if (p.Shape != GGrassShape.DetailObject)
{
p.Texture = EditorGUILayout.ObjectField("Texture", p.Texture, typeof(Texture2D), false) as Texture2D;
p.Shape = (GGrassShape)EditorGUILayout.EnumPopup("Shape", p.Shape);
if (p.Shape == GGrassShape.CustomMesh)
{
p.CustomMesh = EditorGUILayout.ObjectField("Mesh", p.CustomMesh, typeof(Mesh), false) as Mesh;
}
}
else
{
DrawPreview(p.Prefab);
p.Shape = (GGrassShape)EditorGUILayout.EnumPopup("Shape", p.Shape);
p.Prefab = EditorGUILayout.ObjectField("Prefab", p.Prefab, typeof(GameObject), false) as GameObject;
GUI.enabled = false;
EditorGUILayout.ObjectField("Material", p.DetailMaterial, typeof(Material), false);
GUI.enabled = true;
}
p.Color = EditorGUILayout.ColorField("Color", p.Color);
if (EditorGUI.EndChangeCheck())
{
EditorUtility.SetDirty(instance);
}
EditorGUI.BeginChangeCheck();
p.Size = GEditorCommon.InlineVector3Field("Size", p.Size);
p.PivotOffset = EditorGUILayout.DelayedFloatField("Pivot Offset", p.PivotOffset);
if (EditorGUI.EndChangeCheck())
{
ResetNativeArrays();
EditorUtility.SetDirty(instance);
}
p.BendFactor = EditorGUILayout.FloatField("Bend Factor", p.BendFactor);
p.Layer = EditorGUILayout.LayerField("Layer", p.Layer);
p.AlignToSurface = EditorGUILayout.Toggle("Align To Surface", p.AlignToSurface);
p.ShadowCastingMode = (ShadowCastingMode)EditorGUILayout.EnumPopup("Cast Shadow", p.ShadowCastingMode);
p.ReceiveShadow = EditorGUILayout.Toggle("Receive Shadow", p.ReceiveShadow);
if (p.Shape != GGrassShape.DetailObject)
{
p.IsBillboard = EditorGUILayout.Toggle("Billboard", p.IsBillboard);
}
if (p.Shape == GGrassShape.DetailObject)
{
EditorGUILayout.LabelField("Detail Object uses the first sub-mesh and material found in its prefab, and may NOT affected by wind.", GEditorCommon.WarningLabel);
if (p.DetailMaterial!=null && !p.DetailMaterial.enableInstancing)
{
EditorGUILayout.LabelField("Prototype's material has GPU Instancing option turned off. This prototype will not be rendered.", GEditorCommon.WarningLabel);
}
}
if (p.Shape != GGrassShape.DetailObject && p.IsBillboard)
{
EditorGUILayout.LabelField("Billboard will not work if Interactive Grass is enabled.", GEditorCommon.WarningLabel);
}
},
menu);
}
}
private void ConfirmAndRemovePrototypeAtIndex(int index)
{
GGrassPrototype p = instance.Prototypes[index];
string label = p.Texture != null ? p.Texture.name : "Grass " + index;
if (EditorUtility.DisplayDialog(
"Confirm",
"Remove " + label,
"OK", "Cancel"))
{
instance.Prototypes.RemoveAt(index);
RefreshInstanceList();
EditorUtility.SetDirty(instance);
}
}
private void DrawPreview(GameObject g)
{
Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(GEditorCommon.selectionGridTileSizeMedium.y));
GEditorCommon.DrawPreview(r, g);
}
private void DrawAddPrototypeGUI()
{
EditorGUILayout.GetControlRect(GUILayout.Height(1));
Rect r0 = EditorGUILayout.GetControlRect(GUILayout.Height(GEditorCommon.objectSelectorDragDropHeight));
Texture2D t = GEditorCommon.ObjectSelectorDragDrop<Texture2D>(r0, "Drop a Texture here!", "t:Texture2D");
if (t != null)
{
GGrassPrototype g = GGrassPrototype.Create(t);
instance.Prototypes.Add(g);
RefreshInstanceList();
EditorUtility.SetDirty(instance);
}
EditorGUILayout.GetControlRect(GUILayout.Height(1));
Rect r1 = EditorGUILayout.GetControlRect(GUILayout.Height(GEditorCommon.objectSelectorDragDropHeight));
GameObject prefab = GEditorCommon.ObjectSelectorDragDrop<GameObject>(r1, "Drop a Game Object here!", "t:GameObject");
if (prefab != null)
{
GGrassPrototype p = GGrassPrototype.Create(prefab);
instance.Prototypes.Add(p);
RefreshInstanceList();
EditorUtility.SetDirty(instance);
}
}
private void RefreshInstanceList()
{
IEnumerator<GStylizedTerrain> terrains = GStylizedTerrain.ActiveTerrains.GetEnumerator();
while (terrains.MoveNext())
{
GStylizedTerrain t = terrains.Current;
if (t.TerrainData != null && t.TerrainData.Foliage.Grasses == instance)
{
t.TerrainData.Foliage.Refresh();
}
}
}
private void ResetNativeArrays()
{
IEnumerator<GStylizedTerrain> terrains = GStylizedTerrain.ActiveTerrains.GetEnumerator();
while (terrains.MoveNext())
{
GStylizedTerrain t = terrains.Current;
if (t.TerrainData != null && t.TerrainData.Foliage.Grasses == instance)
{
t.TerrainData.Foliage.GrassAllChanged();
}
}
}
private void DrawConvertAssetGUI()
{
if (GUILayout.Button("Create Prefab Prototype Group"))
{
ConvertToPrefabPrototypeGroup();
}
}
private void ConvertToPrefabPrototypeGroup()
{
GPrefabPrototypeGroup group = ScriptableObject.CreateInstance<GPrefabPrototypeGroup>();
for (int i = 0; i < instance.Prototypes.Count; ++i)
{
if (instance.Prototypes[i].Shape != GGrassShape.DetailObject)
continue;
GameObject prefab = instance.Prototypes[i].Prefab;
if (prefab != null)
{
group.Prototypes.Add(prefab);
}
}
string path = AssetDatabase.GetAssetPath(instance);
string directory = Path.GetDirectoryName(path);
string filePath = Path.Combine(directory, string.Format("{0}_{1}_{2}.asset", instance.name, "Prefabs", GCommon.GetUniqueID()));
AssetDatabase.CreateAsset(group, filePath);
Selection.activeObject = group;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d076df9064969fd4abd06c909bfa59df
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,73 @@
#if GRIFFIN
using UnityEditor;
using UnityEngine;
namespace Pinwheel.Griffin.PaintTool
{
[CustomEditor(typeof(GPrefabPrototypeGroup))]
public class GPrefabPrototypeGroupInspector : Editor
{
private GPrefabPrototypeGroup instance;
private void OnEnable()
{
instance = target as GPrefabPrototypeGroup;
}
public override void OnInspectorGUI()
{
GPrefabPrototypeGroupInspectorDrawer.Create(instance).DrawGUI();
EditorUtility.SetDirty(instance);
}
[MenuItem("CONTEXT/GPrefabPrototypeGroup/(Internal) Fix Missing Pine Prefab")]
public static void FixMissingPinePrefab()
{
Object o = Selection.activeObject;
if (o is GPrefabPrototypeGroup)
{
string[] prefabAssetPaths = new string[]
{
"Assets/Polaris - Low Poly Ecosystem/Polaris - Low Poly Terrain Engine/Samples/Pinwheel Studio/Prefabs/Pine_00.prefab",
"Assets/Polaris - Low Poly Ecosystem/Polaris - Low Poly Terrain Engine/Samples/Pinwheel Studio/Prefabs/Pine_01.prefab",
"Assets/Polaris - Low Poly Ecosystem/Polaris - Low Poly Terrain Engine/Samples/Pinwheel Studio/Prefabs/Dead.prefab",
"Assets/Polaris - Low Poly Ecosystem/Polaris - Low Poly Terrain Engine/Samples/Pinwheel Studio/Prefabs/Dead_Break.prefab"
};
GPrefabPrototypeGroup group = o as GPrefabPrototypeGroup;
group.Prototypes.Clear();
for (int i = 0; i < prefabAssetPaths.Length; ++i)
{
GameObject p = AssetDatabase.LoadAssetAtPath<GameObject>(prefabAssetPaths[i]);
group.Prototypes.Add(p);
}
EditorUtility.SetDirty(group);
}
}
[MenuItem("CONTEXT/GPrefabPrototypeGroup/(Internal) Fix Missing Rock Prefab")]
public static void FixMissingRockPrefab()
{
Object o = Selection.activeObject;
if (o is GPrefabPrototypeGroup)
{
string[] prefabAssetPaths = new string[]
{
"Assets/Polaris - Low Poly Ecosystem/Polaris - Low Poly Terrain Engine/Samples/Pinwheel Studio/Prefabs/Rock.prefab",
"Assets/Polaris - Low Poly Ecosystem/Polaris - Low Poly Terrain Engine/Samples/Pinwheel Studio/Prefabs/Rock1.prefab",
"Assets/Polaris - Low Poly Ecosystem/Polaris - Low Poly Terrain Engine/Samples/Pinwheel Studio/Prefabs/Rock2.prefab",
"Assets/Polaris - Low Poly Ecosystem/Polaris - Low Poly Terrain Engine/Samples/Pinwheel Studio/Prefabs/Rock3.prefab"
};
GPrefabPrototypeGroup group = o as GPrefabPrototypeGroup;
group.Prototypes.Clear();
for (int i = 0; i < prefabAssetPaths.Length; ++i)
{
GameObject p = AssetDatabase.LoadAssetAtPath<GameObject>(prefabAssetPaths[i]);
group.Prototypes.Add(p);
}
EditorUtility.SetDirty(group);
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 602cd2c335016fb48877fbf4021e91ca
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,169 @@
#if GRIFFIN
using UnityEditor;
using UnityEngine;
using System.IO;
namespace Pinwheel.Griffin.PaintTool
{
public class GPrefabPrototypeGroupInspectorDrawer
{
private GPrefabPrototypeGroup instance;
private GPrefabPrototypeGroupInspectorDrawer(GPrefabPrototypeGroup instance)
{
this.instance = instance;
}
public static GPrefabPrototypeGroupInspectorDrawer Create(GPrefabPrototypeGroup instance)
{
return new GPrefabPrototypeGroupInspectorDrawer(instance);
}
public void DrawGUI()
{
EditorGUI.BeginChangeCheck();
DrawPrototypesListGUI();
DrawAddPrototypeGUI();
if (EditorGUI.EndChangeCheck())
{
EditorUtility.SetDirty(instance);
}
GEditorCommon.DrawAffLinks(
"These rocks, props and models can help your scene to be more compelling",
"https://assetstore.unity.com/packages/3d/props/low-poly-ultimate-pack-54733",
"https://assetstore.unity.com/lists/stylized-rock-props-120083");
GEditorCommon.Separator();
DrawConvertAssetGUI();
}
private void DrawPrototypesListGUI()
{
instance.Prototypes.RemoveAll(g => g == null);
CachePrefabPath();
for (int i = 0; i < instance.Prototypes.Count; ++i)
{
GameObject g = instance.Prototypes[i];
if (g == null)
continue;
string label = g.name;
string id = "treeprototype" + i + instance.GetInstanceID().ToString();
int index = i;
GenericMenu menu = new GenericMenu();
menu.AddItem(
new GUIContent("Remove"),
false,
() => { ConfirmAndRemovePrototypeAtIndex(index); });
GEditorCommon.Foldout(label, false, id, () =>
{
DrawPreview(g);
}, menu);
}
}
private void CachePrefabPath()
{
instance.Editor_PrefabAssetPaths.Clear();
for (int i = 0; i < instance.Prototypes.Count; ++i)
{
if (instance.Prototypes[i] == null)
{
instance.Editor_PrefabAssetPaths[i] = string.Empty;
}
else
{
instance.Editor_PrefabAssetPaths[i] = AssetDatabase.GetAssetPath(instance.Prototypes[i]);
}
}
}
private void ConfirmAndRemovePrototypeAtIndex(int index)
{
GameObject g = instance.Prototypes[index];
string label = g.name;
if (EditorUtility.DisplayDialog(
"Confirm",
"Remove " + label,
"OK", "Cancel"))
{
instance.Prototypes.RemoveAt(index);
}
}
private void DrawPreview(GameObject g)
{
Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(GEditorCommon.selectionGridTileSizeMedium.y));
GEditorCommon.DrawPreview(r, g);
}
private void DrawAddPrototypeGUI()
{
EditorGUILayout.GetControlRect(GUILayout.Height(1));
Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(GEditorCommon.objectSelectorDragDropHeight));
GameObject g = GEditorCommon.ObjectSelectorDragDrop<GameObject>(r, "Drop a Game Object here!", "t:GameObject");
if (g != null)
{
if (!instance.Prototypes.Contains(g))
{
instance.Prototypes.Add(g);
}
}
}
private void DrawConvertAssetGUI()
{
if (GUILayout.Button("Create Tree Prototype Group"))
{
ConvertToTreePrototypeGroup();
}
if (GUILayout.Button("Create Grass/Detail Object Prototype Group"))
{
ConvertToGrassPrototypeGroup();
}
}
private void ConvertToTreePrototypeGroup()
{
GTreePrototypeGroup group = ScriptableObject.CreateInstance<GTreePrototypeGroup>();
for (int i = 0; i < instance.Prototypes.Count; ++i)
{
GameObject prefab = instance.Prototypes[i];
if (prefab != null)
{
group.Prototypes.Add(GTreePrototype.Create(prefab));
}
}
string path = AssetDatabase.GetAssetPath(instance);
string directory = Path.GetDirectoryName(path);
string filePath = Path.Combine(directory, string.Format("{0}_{1}_{2}.asset", instance.name, "Trees", GCommon.GetUniqueID()));
AssetDatabase.CreateAsset(group, filePath);
Selection.activeObject = group;
}
private void ConvertToGrassPrototypeGroup()
{
GGrassPrototypeGroup group = ScriptableObject.CreateInstance<GGrassPrototypeGroup>();
for (int i = 0; i < instance.Prototypes.Count; ++i)
{
GameObject prefab = instance.Prototypes[i];
if (prefab != null)
{
group.Prototypes.Add(GGrassPrototype.Create(prefab));
}
}
string path = AssetDatabase.GetAssetPath(instance);
string directory = Path.GetDirectoryName(path);
string filePath = Path.Combine(directory, string.Format("{0}_{1}_{2}.asset", instance.name, "DetailObjects", GCommon.GetUniqueID()));
AssetDatabase.CreateAsset(group, filePath);
Selection.activeObject = group;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: be6f505e3231e7145929a3c0aa150871
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,28 @@
#if GRIFFIN
using UnityEditor;
namespace Pinwheel.Griffin
{
[CustomEditor(typeof(GSplatPrototypeGroup))]
public class GSplatPrototypeGroupInspector : Editor
{
private GSplatPrototypeGroup instance;
public void OnEnable()
{
instance = (GSplatPrototypeGroup)target;
}
public override void OnInspectorGUI()
{
GSplatPrototypeGroupInspectorDrawer.Create(instance).DrawGUI();
EditorUtility.SetDirty(instance);
}
public override bool RequiresConstantRepaint()
{
return false;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a29eb1206bc1e634287f3f0fa4da1696
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,107 @@
#if GRIFFIN
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace Pinwheel.Griffin
{
public class GSplatPrototypeGroupInspectorDrawer
{
private GSplatPrototypeGroup instance;
public GSplatPrototypeGroupInspectorDrawer(GSplatPrototypeGroup group)
{
instance = group;
}
public static GSplatPrototypeGroupInspectorDrawer Create(GSplatPrototypeGroup group)
{
return new GSplatPrototypeGroupInspectorDrawer(group);
}
public void DrawGUI()
{
EditorGUI.BeginChangeCheck();
DrawPrototypesListGUI();
DrawAddPrototypeGUI();
if (EditorGUI.EndChangeCheck())
{
SetShadingDirty();
EditorUtility.SetDirty(instance);
}
GEditorCommon.DrawAffLinks(
"Explore the high quality textures for stunning low poly scenes",
"https://assetstore.unity.com/packages/2d/textures-materials/600-super-texture-collection-197591",
"https://assetstore.unity.com/lists/stylized-texture-18967160722750");
}
private void DrawPrototypesListGUI()
{
for (int i = 0; i < instance.Prototypes.Count; ++i)
{
GSplatPrototype p = instance.Prototypes[i];
string label = p.Texture != null && !string.IsNullOrEmpty(p.Texture.name) ? p.Texture.name : "Splat " + i;
string id = "splat" + i + instance.GetInstanceID().ToString();
int index = i;
GenericMenu menu = new GenericMenu();
menu.AddItem(
new GUIContent("Remove"),
false,
() => { ConfirmAndRemovePrototypeAtIndex(index); });
GEditorCommon.Foldout(label, false, id, () =>
{
p.Texture = EditorGUILayout.ObjectField("Texture", p.Texture, typeof(Texture2D), false) as Texture2D;
p.NormalMap = EditorGUILayout.ObjectField("Normal Map", p.NormalMap, typeof(Texture2D), false) as Texture2D;
p.TileSize = EditorGUILayout.Vector2Field("Tile Size", p.TileSize);
p.TileOffset = EditorGUILayout.Vector2Field("Tile Offset", p.TileOffset);
p.Metallic = EditorGUILayout.Slider("Metallic", p.Metallic, 0f, 1f);
p.Smoothness = EditorGUILayout.Slider("Smoothness", p.Smoothness, 0f, 1f);
}, menu);
}
}
private void ConfirmAndRemovePrototypeAtIndex(int index)
{
GSplatPrototype p = instance.Prototypes[index];
string label = p.Texture != null ? p.Texture.name : "Splat " + index;
if (EditorUtility.DisplayDialog(
"Confirm",
"Remove " + label,
"OK", "Cancel"))
{
instance.Prototypes.RemoveAt(index);
}
}
private void DrawAddPrototypeGUI()
{
EditorGUILayout.GetControlRect(GUILayout.Height(1));
Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(GEditorCommon.objectSelectorDragDropHeight));
Texture2D t = GEditorCommon.ObjectSelectorDragDrop<Texture2D>(r, "Drop a texture here!", "t:Texture2D");
if (t != null)
{
GSplatPrototype p = new GSplatPrototype();
p.Texture = t;
instance.Prototypes.Add(p);
}
}
private void SetShadingDirty()
{
IEnumerator<GStylizedTerrain> terrains = GStylizedTerrain.ActiveTerrains.GetEnumerator();
while (terrains.MoveNext())
{
GStylizedTerrain t = terrains.Current;
if (t.TerrainData != null)
{
t.TerrainData.SetDirty(GTerrainData.DirtyFlags.Shading);
}
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1067bbf76d53a2f42af6fe23e046671c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,24 @@
#if GRIFFIN
using UnityEditor;
using UnityEngine;
namespace Pinwheel.Griffin
{
[CustomEditor(typeof(GTerrainData))]
public class GTerrainDataInspector : Editor
{
private GTerrainData instance;
private void OnEnable()
{
instance = (GTerrainData)target;
}
public override void OnInspectorGUI()
{
EditorGUILayout.LabelField("Select the corresponding terrain in the scene to edit terrain data.", GEditorCommon.WordWrapItalicLabel);
EditorGUILayout.LabelField("Do NOT duplicate this asset, it won't work. Instead use Export/Import function to copy data.", GEditorCommon.WarningLabel);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8dd326069e823404ab021406f8e89828
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,43 @@
#if GRIFFIN
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
namespace Pinwheel.Griffin
{
[CustomEditor(typeof(GTerrainGeneratedData))]
public class GTerrainGeneratedDataInspector : Editor
{
private GTerrainGeneratedData instance;
private void OnEnable()
{
instance = target as GTerrainGeneratedData;
}
public override void OnInspectorGUI()
{
GUI.enabled = false;
EditorGUILayout.ObjectField("Terrain Data", instance.TerrainData, typeof(GTerrainData), false);
GUI.enabled = true;
DrawStatisticGUI();
}
private void DrawStatisticGUI()
{
string label = "Statistic";
string id = "statistic" + instance.GetInstanceID();
GEditorCommon.Foldout(label, true, id, () =>
{
string filePath = AssetDatabase.GetAssetPath(instance);
FileInfo fileInfo = new FileInfo(filePath);
if (fileInfo != null)
{
long length = fileInfo.Length;
EditorGUILayout.LabelField("Size", string.Format("{0} MB", (length / 1000000).ToString("0.00")));
}
});
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9da2591172abcaf4aa418698dc9aee55
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,128 @@
#if GRIFFIN
using UnityEditor;
using UnityEngine;
namespace Pinwheel.Griffin
{
[CustomEditor(typeof(GTreePrototypeGroup))]
public class GTreePrototypeGroupInspector : Editor
{
private GTreePrototypeGroup instance;
private void OnEnable()
{
instance = target as GTreePrototypeGroup;
}
public override void OnInspectorGUI()
{
GTreePrototypeGroupInspectorDrawer.Create(instance).DrawGUI();
EditorUtility.SetDirty(instance);
}
public override bool RequiresConstantRepaint()
{
return false;
}
[MenuItem("CONTEXT/GTreePrototypeGroup/Refresh Prototypes")]
public static void RefreshPrototypes()
{
Object o = Selection.activeObject;
if (o is GTreePrototypeGroup)
{
GTreePrototypeGroup group = o as GTreePrototypeGroup;
for (int i = 0; i < group.Prototypes.Count; ++i)
{
group.Prototypes[i].Refresh();
}
EditorUtility.SetDirty(group);
}
}
[MenuItem("CONTEXT/GTreePrototypeGroup/(Internal) Fix Missing Sample Trees")]
public static void FixMissingSampleTrees()
{
Object o = Selection.activeObject;
if (o is GTreePrototypeGroup)
{
string[] prefabAssetPaths = new string[]
{
"Assets/Polaris - Low Poly Ecosystem/Polaris - Low Poly Terrain Engine/Samples/Pinwheel Studio/Prefabs/AutumnTree1.prefab",
"Assets/Polaris - Low Poly Ecosystem/Polaris - Low Poly Terrain Engine/Samples/Pinwheel Studio/Prefabs/SpringTree1.prefab",
"Assets/Polaris - Low Poly Ecosystem/Polaris - Low Poly Terrain Engine/Samples/Pinwheel Studio/Prefabs/Pine_00.prefab",
"Assets/Polaris - Low Poly Ecosystem/Polaris - Low Poly Terrain Engine/Samples/Pinwheel Studio/Prefabs/Pine_01.prefab",
"Assets/Polaris - Low Poly Ecosystem/Polaris - Low Poly Terrain Engine/Samples/Pinwheel Studio/Prefabs/Dead.prefab",
"Assets/Polaris - Low Poly Ecosystem/Polaris - Low Poly Terrain Engine/Samples/Pinwheel Studio/Prefabs/Dead_Break.prefab"
};
GTreePrototypeGroup group = o as GTreePrototypeGroup;
group.Prototypes.Clear();
for (int i = 0; i < prefabAssetPaths.Length; ++i)
{
GameObject p = AssetDatabase.LoadAssetAtPath<GameObject>(prefabAssetPaths[i]);
GTreePrototype proto = GTreePrototype.Create(p);
proto.Refresh();
group.Prototypes.Add(proto);
}
EditorUtility.SetDirty(group);
}
}
[MenuItem("CONTEXT/GTreePrototypeGroup/(Internal) Fix missing trees Demo_00")]
public static void FixMissingTreeDemo00()
{
Object o = Selection.activeObject;
if (o is GTreePrototypeGroup)
{
string[] prefabAssetPaths = new string[]
{
"Assets/Polaris - Low Poly Ecosystem/Polaris - Low Poly Terrain Engine/Samples/Pinwheel Studio/Prefabs/Pine_00.prefab",
"Assets/Polaris - Low Poly Ecosystem/Polaris - Low Poly Terrain Engine/Samples/Pinwheel Studio/Prefabs/Dead.prefab",
"Assets/Polaris - Low Poly Ecosystem/Polaris - Low Poly Terrain Engine/Samples/Pinwheel Studio/Prefabs/Pine_01.prefab",
"Assets/Polaris - Low Poly Ecosystem/Polaris - Low Poly Terrain Engine/Samples/Pinwheel Studio/Prefabs/Dead_Break.prefab"
};
GTreePrototypeGroup group = o as GTreePrototypeGroup;
group.Prototypes.Clear();
for (int i = 0; i < prefabAssetPaths.Length; ++i)
{
GameObject p = AssetDatabase.LoadAssetAtPath<GameObject>(prefabAssetPaths[i]);
GTreePrototype proto = GTreePrototype.Create(p);
proto.Refresh();
group.Prototypes.Add(proto);
}
EditorUtility.SetDirty(group);
}
}
[MenuItem("CONTEXT/GTreePrototypeGroup/(Internal) Fix missing trees Demo_02")]
public static void FixMissingTreeDemo02()
{
Object o = Selection.activeObject;
if (o is GTreePrototypeGroup)
{
string[] prefabAssetPaths = new string[]
{
"Assets/Polaris - Low Poly Ecosystem/Polaris - Low Poly Terrain Engine/Samples/Pinwheel Studio/Prefabs/SpringTree1.prefab",
"Assets/Polaris - Low Poly Ecosystem/Polaris - Low Poly Terrain Engine/Samples/Pinwheel Studio/Prefabs/AutumnTree3.prefab",
};
GTreePrototypeGroup group = o as GTreePrototypeGroup;
group.Prototypes.Clear();
for (int i = 0; i < prefabAssetPaths.Length; ++i)
{
GameObject p = AssetDatabase.LoadAssetAtPath<GameObject>(prefabAssetPaths[i]);
GTreePrototype proto = GTreePrototype.Create(p);
proto.Refresh();
group.Prototypes.Add(proto);
}
EditorUtility.SetDirty(group);
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 735dbcf067079ca4391c130296950d18
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,200 @@
#if GRIFFIN
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
using System.IO;
namespace Pinwheel.Griffin
{
public class GTreePrototypeGroupInspectorDrawer
{
private GTreePrototypeGroup instance;
public GTreePrototypeGroupInspectorDrawer(GTreePrototypeGroup group)
{
instance = group;
}
public static GTreePrototypeGroupInspectorDrawer Create(GTreePrototypeGroup group)
{
return new GTreePrototypeGroupInspectorDrawer(group);
}
public void DrawGUI()
{
EditorGUI.BeginChangeCheck();
DrawPrototypesListGUI();
DrawAddPrototypeGUI();
if (EditorGUI.EndChangeCheck())
{
SetFoliageDirty();
EditorUtility.SetDirty(instance);
}
GEditorCommon.DrawAffLinks(
"These vivid vegetations can breath life into your project",
"https://assetstore.unity.com/packages/3d/vegetation/trees/polygon-nature-low-poly-3d-art-by-synty-120152",
"https://assetstore.unity.com/lists/stylized-vegetation-120082");
GEditorCommon.Separator();
DrawConvertAssetGUI();
}
private void DrawPrototypesListGUI()
{
string label, id;
for (int i = 0; i < instance.Prototypes.Count; ++i)
{
GTreePrototype p = instance.Prototypes[i];
CachePrefabPath(p);
label = p.Prefab != null && !string.IsNullOrEmpty(p.Prefab.name) ? p.Prefab.name : "Tree " + i;
id = "treeprototype" + i + instance.GetInstanceID().ToString();
int index = i;
GenericMenu menu = new GenericMenu();
menu.AddItem(
new GUIContent("Remove"),
false,
() => { ConfirmAndRemovePrototypeAtIndex(index); });
menu.AddItem(
new GUIContent("Sync with Prefab"),
false,
() => { p.Refresh(); });
GEditorCommon.Foldout(label, false, id, () =>
{
if (p.Prefab != null)
{
DrawPreview(p.Prefab);
}
p.Prefab = EditorGUILayout.ObjectField("Prefab", p.Prefab, typeof(GameObject), false) as GameObject;
p.Billboard = EditorGUILayout.ObjectField("Billboard", p.Billboard, typeof(BillboardAsset), false) as BillboardAsset;
EditorGUI.BeginChangeCheck();
p.PivotOffset = EditorGUILayout.Slider("Pivot Offset", p.PivotOffset, -1f, 1f);
p.BaseRotation = Quaternion.Euler(GEditorCommon.InlineVector3Field("Base Rotation", p.BaseRotation.eulerAngles));
p.BaseScale = GEditorCommon.InlineVector3Field("Base Scale", p.BaseScale);
if (EditorGUI.EndChangeCheck())
{
ResetNativeArrays();
}
GUI.enabled = !p.KeepPrefabLayer;
p.Layer = EditorGUILayout.LayerField("Layer", p.Layer);
GUI.enabled = true;
p.KeepPrefabLayer = EditorGUILayout.Toggle("Keep Prefab Layer", p.KeepPrefabLayer);
p.ShadowCastingMode = (ShadowCastingMode)EditorGUILayout.EnumPopup("Cast Shadow", p.ShadowCastingMode);
p.ReceiveShadow = EditorGUILayout.Toggle("Receive Shadow", p.ReceiveShadow);
p.BillboardShadowCastingMode = (ShadowCastingMode)EditorGUILayout.EnumPopup("Billboard Cast Shadow", p.BillboardShadowCastingMode);
p.BillboardReceiveShadow = EditorGUILayout.Toggle("Billboard Receive Shadow", p.BillboardReceiveShadow);
GUI.enabled = false;
EditorGUILayout.Toggle("Has Collider", p.HasCollider);
GUI.enabled = true;
}, menu);
}
}
private void CachePrefabPath(GTreePrototype p)
{
if (p.Prefab == null)
{
p.Editor_PrefabAssetPath = null;
}
else
{
p.Editor_PrefabAssetPath = AssetDatabase.GetAssetPath(p.Prefab);
}
}
private void ConfirmAndRemovePrototypeAtIndex(int index)
{
GTreePrototype p = instance.Prototypes[index];
string label = p.Prefab != null ? p.Prefab.name : "Tree " + index;
if (EditorUtility.DisplayDialog(
"Confirm",
"Remove " + label,
"OK", "Cancel"))
{
instance.Prototypes.RemoveAt(index);
}
}
private void DrawPreview(GameObject g)
{
Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(GEditorCommon.selectionGridTileSizeMedium.y));
GEditorCommon.DrawPreview(r, g);
}
private void DrawAddPrototypeGUI()
{
EditorGUILayout.GetControlRect(GUILayout.Height(1));
Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(GEditorCommon.objectSelectorDragDropHeight));
GameObject g = GEditorCommon.ObjectSelectorDragDrop<GameObject>(r, "Drop a Game Object here!", "t:GameObject");
if (g != null)
{
GTreePrototype p = GTreePrototype.Create(g);
instance.Prototypes.Add(p);
}
}
private void ResetNativeArrays()
{
IEnumerator<GStylizedTerrain> terrains = GStylizedTerrain.ActiveTerrains.GetEnumerator();
while (terrains.MoveNext())
{
GStylizedTerrain t = terrains.Current;
if (t.TerrainData != null && t.TerrainData.Foliage.Trees == instance)
{
t.TerrainData.Foliage.TreeAllChanged();
}
}
}
private void SetFoliageDirty()
{
IEnumerator<GStylizedTerrain> terrains = GStylizedTerrain.ActiveTerrains.GetEnumerator();
while (terrains.MoveNext())
{
GStylizedTerrain t = terrains.Current;
if (t.TerrainData != null)
{
t.TerrainData.SetDirty(GTerrainData.DirtyFlags.Foliage);
}
}
}
private void DrawConvertAssetGUI()
{
if (GUILayout.Button("Create Prefab Prototype Group"))
{
ConvertToPrefabPrototypeGroup();
}
}
private void ConvertToPrefabPrototypeGroup()
{
GPrefabPrototypeGroup group = ScriptableObject.CreateInstance<GPrefabPrototypeGroup>();
for (int i = 0; i < instance.Prototypes.Count; ++i)
{
GameObject prefab = instance.Prototypes[i].Prefab;
if (prefab != null)
{
group.Prototypes.Add(prefab);
}
}
string path = AssetDatabase.GetAssetPath(instance);
string directory = Path.GetDirectoryName(path);
string filePath = Path.Combine(directory, string.Format("{0}_{1}_{2}.asset", instance.name, "Prefabs", GCommon.GetUniqueID()));
AssetDatabase.CreateAsset(group, filePath);
Selection.activeObject = group;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4b1d0cc2a9ad7a045bdf180cd56f0c8c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: