Added overlay to view nutrient mapping

This commit is contained in:
2025-08-06 22:08:15 -07:00
parent 3a909fda70
commit a30cbca5c9
9 changed files with 496 additions and 223 deletions
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4a6775d730c776843b78662d9c2bc80e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+137
View File
@@ -0,0 +1,137 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &-8882854773283282475
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 9
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: test
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap:
RenderType: Opaque
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BaseMap:
m_Texture: {fileID: 2800000, guid: 97c1df594a1bc8447a058044bea5a739, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 2800000, guid: 97c1df594a1bc8447a058044bea5a739, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SpecGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_LightmapsInd:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_ShadowMasks:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _AddPrecomputedVelocity: 0
- _AlphaClip: 0
- _AlphaToMask: 0
- _Blend: 0
- _BlendModePreserveSpecular: 1
- _BumpScale: 1
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
- _Cutoff: 0.5
- _DetailAlbedoMapScale: 1
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _DstBlendAlpha: 0
- _EnvironmentReflections: 1
- _GlossMapScale: 0
- _Glossiness: 0
- _GlossyReflections: 0
- _Metallic: 0
- _OcclusionStrength: 1
- _Parallax: 0.005
- _QueueOffset: 0
- _ReceiveShadows: 1
- _Smoothness: 0.5
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 0
- _WorkflowMode: 1
- _XRMotionVectorsPass: 1
- _ZWrite: 1
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d9a99873f9b971549b15a1ed09446b88
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
@@ -1,10 +1,14 @@
using UnityEditor.TextCore.Text;
using UnityEngine;
using static UnityEngine.GraphicsBuffer;
using static UnityEngine.UIElements.UxmlAttributeDescription;
public class NutrientController : MonoBehaviour
{
private float[,] nutrientMap;
[SerializeField, Range(10, 100)] int sizeX;
[SerializeField, Range(10, 100)] int sizeY;
[SerializeField] MeshRenderer meshRenderer;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
@@ -40,4 +44,63 @@ public class NutrientController : MonoBehaviour
nutrientMap[locX, locY] -= used;
}
public void AddNutrients(float x, float y, float added)
{
int locX = Mathf.FloorToInt(x * sizeX);
int locY = Mathf.FloorToInt(y * sizeY);
nutrientMap[locX, locY] += added;
}
private void Render()
{
Texture2D texture = new Texture2D(sizeX, sizeY);
for (int r = 0; r < sizeX; r++)
{
for (int c = 0; c < sizeY; c++)
{
float colorValue = nutrientMap[r, c];
texture.SetPixel(r, c, new Color(colorValue, colorValue, colorValue));
}
}
texture.Apply();
meshRenderer.material.mainTexture = texture;
}
private void ConsoleDump()
{
string toPrint = "\n";
for (int r = 0; r < sizeX; r++)
{
for (int c = 0; c < sizeY; c++)
{
toPrint += nutrientMap[r, c] + " ";
}
toPrint += "\n";
}
Debug.Log(toPrint);
}
#if UNITY_EDITOR
[UnityEditor.CustomEditor(typeof(NutrientController))]
public class NutrientControllerEditor: UnityEditor.Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if (GUILayout.Button("Sample Button"))
{
(target as NutrientController).Render();
}
if(GUILayout.Button("Dump it"))
{
(target as NutrientController).ConsoleDump();
}
}
}
#endif
}
+12 -6
View File
@@ -7,6 +7,7 @@ public class Plant : MonoBehaviour
private float healthCurrent;
private float nutrientNeed;
private float growthRate;
private float nutrientsConsumed;
public bool isAlive;
private GameObject visualPrefab;
@@ -29,6 +30,7 @@ public class Plant : MonoBehaviour
{
visual = Instantiate(visualPrefab, transform);
healthCurrent = healthMax;
nutrientsConsumed = 0;
isAlive = true;
}
@@ -37,22 +39,26 @@ public class Plant : MonoBehaviour
{
Terrain terrain = Core.instance.ground;
NutrientController nutrientCont = Core.instance.nutrientCont;
float x = transform.position.x / terrain.terrainData.size.x;
float y = transform.position.y / terrain.terrainData.size.y;
float nutrientsAvailable = nutrientCont.GetNutrients(x, y);
if(nutrientNeed > nutrientsAvailable)
float x = transform.position.x / terrain.terrainData.size.x;
float y = transform.position.z / terrain.terrainData.size.z;
float nutrientsAvailable = nutrientCont.GetNutrients(x, y);
float nutrientsNeededFrame = (nutrientNeed * Time.deltaTime);
if (nutrientsNeededFrame > nutrientsAvailable)
{
healthCurrent -= Time.deltaTime * (0.1f * healthMax);
healthCurrent -= Time.deltaTime * 0.1f * healthMax;
}
else
{
visual.transform.localScale += visual.transform.localScale * (growthRate * Time.deltaTime);
nutrientCont.UseNutrients(x, y, (nutrientNeed * Time.deltaTime));
nutrientCont.UseNutrients(x, y, nutrientsNeededFrame);
nutrientsConsumed += nutrientsNeededFrame;
}
if (healthCurrent <= 0)
{
nutrientCont.AddNutrients(x, y, (nutrientsConsumed * 0.9f));
isAlive = false;
}
}
+3 -2
View File
@@ -17,11 +17,12 @@ public class PlantController : MonoBehaviour
Terrain terrain = Core.instance.ground;
xBound = terrain.GetComponent<Terrain>().terrainData.size.x;
zBound = terrain.GetComponent<Terrain>().terrainData.size.z;
for (int i = 0; i < 100; i++)
{
GameObject newPlant = Instantiate(plantPrefab, transform);
GameObject newPlant = Instantiate(plantPrefab);
newPlant.GetComponent<Plant>().SetVisual(plantModels[Random.Range(0, plantModels.Count - 1)]);
newPlant.GetComponent<Plant>().SetValues(Random.Range(10f, 100f), Random.Range(0f, 0.5f), Random.Range(0f, 0.5f));
newPlant.GetComponent<Plant>().SetValues(Random.Range(10f, 100f), Random.Range(0.1f, 0.2f), Random.Range(0.1f, 0.25f));
float x = Random.Range(0, xBound);
float z = Random.Range(0, zBound);
float y = terrain.SampleHeight(new Vector3(x, 0, z));