feat: Phase 19 - visual polish and cinematic lighting
Backend: - Add weather transition processing logic Unity Client: - Add smooth UI bar transitions with lerp animations - Implement cinematic lighting system (dawn/day/dusk/night cycle) - Add VisualEffectsManager for advanced effects - Support premium sprite loading for agents - Add character and environment sprite sheets 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -215,6 +215,35 @@ class GameEngine:
|
|||||||
# =========================================================================
|
# =========================================================================
|
||||||
# Day/Night cycle (Phase 2)
|
# Day/Night cycle (Phase 2)
|
||||||
# =========================================================================
|
# =========================================================================
|
||||||
|
async def _process_weather(self) -> None:
|
||||||
|
"""Process weather transitions."""
|
||||||
|
with get_db_session() as db:
|
||||||
|
world = db.query(WorldState).first()
|
||||||
|
if not world:
|
||||||
|
return
|
||||||
|
|
||||||
|
world.weather_duration += 1
|
||||||
|
|
||||||
|
# Should we transition?
|
||||||
|
if world.weather_duration >= random.randint(WEATHER_MIN_DURATION, WEATHER_MAX_DURATION):
|
||||||
|
old_weather = world.weather
|
||||||
|
transitions = WEATHER_TRANSITIONS.get(old_weather, {"Sunny": 1.0})
|
||||||
|
|
||||||
|
# Biased random choice
|
||||||
|
choices = list(transitions.keys())
|
||||||
|
weights = list(transitions.values())
|
||||||
|
new_weather = random.choices(choices, weights=weights, k=1)[0]
|
||||||
|
|
||||||
|
if new_weather != old_weather:
|
||||||
|
world.weather = new_weather
|
||||||
|
world.weather_duration = 0
|
||||||
|
|
||||||
|
await self._broadcast_event(EventType.WEATHER_CHANGE, {
|
||||||
|
"old_weather": old_weather,
|
||||||
|
"new_weather": new_weather,
|
||||||
|
"message": f"The weather is changing to {new_weather}."
|
||||||
|
})
|
||||||
|
|
||||||
async def _advance_time(self) -> Optional[dict]:
|
async def _advance_time(self) -> Optional[dict]:
|
||||||
"""Advance time and return phase change info if applicable."""
|
"""Advance time and return phase change info if applicable."""
|
||||||
with get_db_session() as db:
|
with get_db_session() as db:
|
||||||
|
|||||||
@@ -151,13 +151,47 @@ namespace TheIsland.UI
|
|||||||
rect.sizeDelta = size;
|
rect.sizeDelta = size;
|
||||||
rect.anchoredPosition = Vector2.zero;
|
rect.anchoredPosition = Vector2.zero;
|
||||||
|
|
||||||
// Semi-transparent background
|
// Semi-transparent glass background
|
||||||
var bg = panel.AddComponent<Image>();
|
var bg = panel.AddComponent<Image>();
|
||||||
bg.color = new Color(0, 0, 0, 0.5f);
|
bg.color = new Color(0.1f, 0.12f, 0.18f, 0.6f);
|
||||||
|
|
||||||
|
// Add border highlight
|
||||||
|
var border = new GameObject("Border");
|
||||||
|
border.transform.SetParent(panel.transform);
|
||||||
|
var bRect = border.AddComponent<RectTransform>();
|
||||||
|
bRect.anchorMin = Vector2.zero;
|
||||||
|
bRect.anchorMax = Vector2.one;
|
||||||
|
bRect.offsetMin = new Vector2(-1, -1);
|
||||||
|
bRect.offsetMax = new Vector2(1, 1);
|
||||||
|
var bImg = border.AddComponent<Image>();
|
||||||
|
bImg.color = new Color(1f, 1f, 1f, 0.1f);
|
||||||
|
border.transform.SetAsFirstSibling();
|
||||||
|
|
||||||
return panel;
|
return panel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private float _currentHp;
|
||||||
|
private float _currentEnergy;
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
if (_hpBarFill != null && _currentData != null)
|
||||||
|
{
|
||||||
|
_currentHp = Mathf.Lerp(_currentHp, _currentData.hp, Time.deltaTime * 5f);
|
||||||
|
float hpPercent = _currentHp / 100f;
|
||||||
|
_hpBarFill.rectTransform.anchorMax = new Vector2(hpPercent, 1);
|
||||||
|
_hpBarFill.color = Color.Lerp(hpLowColor, hpHighColor, hpPercent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_energyBarFill != null && _currentData != null)
|
||||||
|
{
|
||||||
|
_currentEnergy = Mathf.Lerp(_currentEnergy, _currentData.energy, Time.deltaTime * 5f);
|
||||||
|
float energyPercent = _currentEnergy / 100f;
|
||||||
|
_energyBarFill.rectTransform.anchorMax = new Vector2(energyPercent, 1);
|
||||||
|
_energyBarFill.color = Color.Lerp(energyLowColor, energyHighColor, energyPercent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private TextMeshProUGUI CreateText(GameObject parent, string name, string text,
|
private TextMeshProUGUI CreateText(GameObject parent, string name, string text,
|
||||||
float fontSize, Color color, FontStyles style = FontStyles.Normal)
|
float fontSize, Color color, FontStyles style = FontStyles.Normal)
|
||||||
{
|
{
|
||||||
@@ -296,25 +330,11 @@ namespace TheIsland.UI
|
|||||||
{
|
{
|
||||||
_currentData = data;
|
_currentData = data;
|
||||||
|
|
||||||
// Update HP
|
|
||||||
float hpPercent = data.hp / 100f;
|
|
||||||
if (_hpBarFill != null)
|
|
||||||
{
|
|
||||||
_hpBarFill.rectTransform.anchorMax = new Vector2(hpPercent, 1);
|
|
||||||
_hpBarFill.color = Color.Lerp(hpLowColor, hpHighColor, hpPercent);
|
|
||||||
}
|
|
||||||
if (_hpText != null)
|
if (_hpText != null)
|
||||||
{
|
{
|
||||||
_hpText.text = $"HP: {data.hp}";
|
_hpText.text = $"HP: {data.hp}";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update Energy
|
|
||||||
float energyPercent = data.energy / 100f;
|
|
||||||
if (_energyBarFill != null)
|
|
||||||
{
|
|
||||||
_energyBarFill.rectTransform.anchorMax = new Vector2(energyPercent, 1);
|
|
||||||
_energyBarFill.color = Color.Lerp(energyLowColor, energyHighColor, energyPercent);
|
|
||||||
}
|
|
||||||
if (_energyText != null)
|
if (_energyText != null)
|
||||||
{
|
{
|
||||||
_energyText.text = $"Energy: {data.energy}";
|
_energyText.text = $"Energy: {data.energy}";
|
||||||
|
|||||||
@@ -82,6 +82,14 @@ namespace TheIsland.Visual
|
|||||||
private Vector3 _targetPosition;
|
private Vector3 _targetPosition;
|
||||||
private bool _isMoving;
|
private bool _isMoving;
|
||||||
private float _moveSpeed = 3f;
|
private float _moveSpeed = 3f;
|
||||||
|
|
||||||
|
// UI Smoothing (Phase 19)
|
||||||
|
private float _currentHpPercent;
|
||||||
|
private float _currentEnergyPercent;
|
||||||
|
private float _currentMoodPercent;
|
||||||
|
private float _targetHpPercent;
|
||||||
|
private float _targetEnergyPercent;
|
||||||
|
private float _targetMoodPercent;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
@@ -157,6 +165,35 @@ namespace TheIsland.Visual
|
|||||||
pos.y = 1f + _bobOffset;
|
pos.y = 1f + _bobOffset;
|
||||||
_spriteRenderer.transform.localPosition = pos;
|
_spriteRenderer.transform.localPosition = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Phase 19: Smooth UI Bar Transitions
|
||||||
|
UpdateSmoothBars();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateSmoothBars()
|
||||||
|
{
|
||||||
|
float lerpSpeed = 5f * Time.deltaTime;
|
||||||
|
|
||||||
|
if (_hpBarFill != null)
|
||||||
|
{
|
||||||
|
_currentHpPercent = Mathf.Lerp(_currentHpPercent, _targetHpPercent, lerpSpeed);
|
||||||
|
_hpBarFill.rectTransform.anchorMax = new Vector2(_currentHpPercent, 1);
|
||||||
|
_hpBarFill.color = Color.Lerp(hpLowColor, hpHighColor, _currentHpPercent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_energyBarFill != null)
|
||||||
|
{
|
||||||
|
_currentEnergyPercent = Mathf.Lerp(_currentEnergyPercent, _targetEnergyPercent, lerpSpeed);
|
||||||
|
_energyBarFill.rectTransform.anchorMax = new Vector2(_currentEnergyPercent, 1);
|
||||||
|
_energyBarFill.color = Color.Lerp(energyLowColor, energyHighColor, _currentEnergyPercent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_moodBarFill != null)
|
||||||
|
{
|
||||||
|
_currentMoodPercent = Mathf.Lerp(_currentMoodPercent, _targetMoodPercent, lerpSpeed);
|
||||||
|
_moodBarFill.rectTransform.anchorMax = new Vector2(_currentMoodPercent, 1);
|
||||||
|
_moodBarFill.color = GetMoodColor(_currentData?.mood_state ?? "neutral");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trigger a jump animation (to be called by events)
|
// Trigger a jump animation (to be called by events)
|
||||||
@@ -218,7 +255,10 @@ namespace TheIsland.Visual
|
|||||||
_currentData = data;
|
_currentData = data;
|
||||||
gameObject.name = $"Agent_{data.id}_{data.name}";
|
gameObject.name = $"Agent_{data.id}_{data.name}";
|
||||||
|
|
||||||
// Apply unique color based on agent ID
|
// Loading premium assets (Phase 19)
|
||||||
|
TryLoadPremiumSprite(data.id);
|
||||||
|
|
||||||
|
// Apply unique color based on agent ID (as fallback/tint)
|
||||||
ApplyAgentColor(data.id);
|
ApplyAgentColor(data.id);
|
||||||
|
|
||||||
// Set UI text
|
// Set UI text
|
||||||
@@ -229,6 +269,45 @@ namespace TheIsland.Visual
|
|||||||
Debug.Log($"[AgentVisual] Initialized: {data.name}");
|
Debug.Log($"[AgentVisual] Initialized: {data.name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void TryLoadPremiumSprite(int id)
|
||||||
|
{
|
||||||
|
// Load the collection texture from Assets
|
||||||
|
// Note: In a real build, we'd use Resources.Load or Addressables.
|
||||||
|
// For this environment, we'll try to find it in the path or use a static reference.
|
||||||
|
// Since we can't easily use Resources.Load at runtime for arbitrary paths,
|
||||||
|
// we'll implement a simple runtime texture loader if needed, or assume it's assigned to a manager.
|
||||||
|
|
||||||
|
// For now, let's assume the texture is assigned or loaded.
|
||||||
|
// I'll add a static reference to the collection texture in NetworkManager or AgentVisual.
|
||||||
|
|
||||||
|
if (characterSprite != null) return; // Already has a sprite
|
||||||
|
|
||||||
|
StartCoroutine(LoadSpriteCoroutine(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerator LoadSpriteCoroutine(int id)
|
||||||
|
{
|
||||||
|
// This is a simplified runtime loader for the demonstration
|
||||||
|
string path = Application.dataPath + "/Sprites/Characters.png";
|
||||||
|
if (!System.IO.File.Exists(path)) yield break;
|
||||||
|
|
||||||
|
byte[] fileData = System.IO.File.ReadAllBytes(path);
|
||||||
|
Texture2D tex = new Texture2D(2, 2);
|
||||||
|
tex.LoadImage(fileData);
|
||||||
|
|
||||||
|
// Slice the 1x3 collection (3 characters in a row)
|
||||||
|
int charIndex = id % 3;
|
||||||
|
float charWidth = tex.width / 3f;
|
||||||
|
Rect rect = new Rect(charIndex * charWidth, 0, charWidth, tex.height);
|
||||||
|
|
||||||
|
characterSprite = Sprite.Create(tex, rect, new Vector2(0.5f, 0.5f), 100f);
|
||||||
|
if (_spriteRenderer != null)
|
||||||
|
{
|
||||||
|
_spriteRenderer.sprite = characterSprite;
|
||||||
|
_spriteRenderer.color = Color.white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void ApplyAgentColor(int agentId)
|
private void ApplyAgentColor(int agentId)
|
||||||
{
|
{
|
||||||
// Generate unique color per agent
|
// Generate unique color per agent
|
||||||
@@ -702,28 +781,23 @@ namespace TheIsland.Visual
|
|||||||
rect.anchoredPosition = Vector2.zero;
|
rect.anchoredPosition = Vector2.zero;
|
||||||
|
|
||||||
var bg = panel.AddComponent<Image>();
|
var bg = panel.AddComponent<Image>();
|
||||||
bg.sprite = CreateRoundedRectSprite(32, 32, 8);
|
bg.sprite = CreateRoundedRectSprite(32, 32, 12);
|
||||||
bg.type = Image.Type.Sliced;
|
bg.type = Image.Type.Sliced;
|
||||||
bg.color = new Color(0.1f, 0.12f, 0.18f, 0.6f); // Lower alpha for glass effect
|
bg.color = new Color(0.05f, 0.08f, 0.15f, 0.45f); // Darker, more transparent glass
|
||||||
|
|
||||||
// Add subtle border
|
// Add inner glow border (Phase 19)
|
||||||
var borderObj = new GameObject("Border");
|
var borderObj = new GameObject("Border");
|
||||||
borderObj.transform.SetParent(panel.transform);
|
borderObj.transform.SetParent(panel.transform);
|
||||||
borderObj.transform.localPosition = Vector3.zero;
|
|
||||||
borderObj.transform.localRotation = Quaternion.identity;
|
|
||||||
borderObj.transform.localScale = Vector3.one;
|
|
||||||
|
|
||||||
var borderRect = borderObj.AddComponent<RectTransform>();
|
var borderRect = borderObj.AddComponent<RectTransform>();
|
||||||
borderRect.anchorMin = Vector2.zero;
|
borderRect.anchorMin = Vector2.zero;
|
||||||
borderRect.anchorMax = Vector2.one;
|
borderRect.anchorMax = Vector2.one;
|
||||||
borderRect.offsetMin = new Vector2(-2, -2);
|
borderRect.offsetMin = new Vector2(1, 1);
|
||||||
borderRect.offsetMax = new Vector2(2, 2);
|
borderRect.offsetMax = new Vector2(-1, -1);
|
||||||
borderRect.SetAsFirstSibling();
|
|
||||||
|
|
||||||
var borderImg = borderObj.AddComponent<Image>();
|
var borderImg = borderObj.AddComponent<Image>();
|
||||||
borderImg.sprite = CreateRoundedRectSprite(32, 32, 8);
|
borderImg.sprite = CreateRoundedRectSprite(32, 32, 12);
|
||||||
borderImg.type = Image.Type.Sliced;
|
borderImg.type = Image.Type.Sliced;
|
||||||
borderImg.color = new Color(0.3f, 0.35f, 0.45f, 0.5f);
|
borderImg.color = new Color(1f, 1f, 1f, 0.15f); // Subtle highlight
|
||||||
|
|
||||||
return panel;
|
return panel;
|
||||||
}
|
}
|
||||||
@@ -918,38 +992,21 @@ namespace TheIsland.Visual
|
|||||||
{
|
{
|
||||||
_currentData = data;
|
_currentData = data;
|
||||||
|
|
||||||
// Update HP bar
|
// Set targets for smooth lerping (Phase 19)
|
||||||
float hpPercent = data.hp / 100f;
|
_targetHpPercent = data.hp / 100f;
|
||||||
if (_hpBarFill != null)
|
_targetEnergyPercent = data.energy / 100f;
|
||||||
{
|
_targetMoodPercent = data.mood / 100f;
|
||||||
_hpBarFill.rectTransform.anchorMax = new Vector2(hpPercent, 1);
|
|
||||||
_hpBarFill.color = Color.Lerp(hpLowColor, hpHighColor, hpPercent);
|
|
||||||
}
|
|
||||||
if (_hpText != null)
|
if (_hpText != null)
|
||||||
{
|
{
|
||||||
_hpText.text = $"HP: {data.hp}";
|
_hpText.text = $"HP: {data.hp}";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update Energy bar
|
|
||||||
float energyPercent = data.energy / 100f;
|
|
||||||
if (_energyBarFill != null)
|
|
||||||
{
|
|
||||||
_energyBarFill.rectTransform.anchorMax = new Vector2(energyPercent, 1);
|
|
||||||
_energyBarFill.color = Color.Lerp(energyLowColor, energyHighColor, energyPercent);
|
|
||||||
}
|
|
||||||
if (_energyText != null)
|
if (_energyText != null)
|
||||||
{
|
{
|
||||||
_energyText.text = $"Energy: {data.energy}";
|
_energyText.text = $"Energy: {data.energy}";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update Mood bar
|
|
||||||
float moodPercent = data.mood / 100f;
|
|
||||||
if (_moodBarFill != null)
|
|
||||||
{
|
|
||||||
_moodBarFill.rectTransform.anchorMax = new Vector2(moodPercent, 1);
|
|
||||||
_moodBarFill.color = GetMoodColor(data.mood_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for mood change (Visual Expression)
|
// Check for mood change (Visual Expression)
|
||||||
if (_moodState != data.mood_state)
|
if (_moodState != data.mood_state)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ namespace TheIsland.Visual
|
|||||||
}
|
}
|
||||||
_instance = this;
|
_instance = this;
|
||||||
|
|
||||||
|
LoadEnvironmentTexture();
|
||||||
_mainCamera = Camera.main;
|
_mainCamera = Camera.main;
|
||||||
CreateEnvironment();
|
CreateEnvironment();
|
||||||
}
|
}
|
||||||
@@ -103,6 +104,12 @@ namespace TheIsland.Visual
|
|||||||
|
|
||||||
// Set initial sky
|
// Set initial sky
|
||||||
UpdateSkyColors();
|
UpdateSkyColors();
|
||||||
|
|
||||||
|
// Phase 19: Add Visual Effects Manager
|
||||||
|
if (FindObjectOfType<VisualEffectsManager>() == null)
|
||||||
|
{
|
||||||
|
new GameObject("VisualEffectsManager").AddComponent<VisualEffectsManager>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Update()
|
private void Update()
|
||||||
@@ -116,11 +123,58 @@ namespace TheIsland.Visual
|
|||||||
UpdateSkyMaterial();
|
UpdateSkyMaterial();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Phase 19: Cinematic Lighting
|
||||||
|
AnimateLighting();
|
||||||
|
|
||||||
// Animate environment (Water & Trees)
|
// Animate environment (Water & Trees)
|
||||||
AnimateEnvironment();
|
AnimateEnvironment();
|
||||||
AnimateClouds();
|
AnimateClouds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void AnimateLighting()
|
||||||
|
{
|
||||||
|
if (_mainLight == null) return;
|
||||||
|
|
||||||
|
// Simple 120s cycle for demonstration (30s per phase)
|
||||||
|
float cycleDuration = 120f;
|
||||||
|
float t = (Time.time % cycleDuration) / cycleDuration;
|
||||||
|
|
||||||
|
// t: 0=Dawn, 0.25=Noon, 0.5=Dusk, 0.75=Midnight
|
||||||
|
float intensity = 1f;
|
||||||
|
Color lightColor = Color.white;
|
||||||
|
|
||||||
|
if (t < 0.2f) // Dawn
|
||||||
|
{
|
||||||
|
float p = t / 0.2f;
|
||||||
|
intensity = Mathf.Lerp(0.5f, 1.2f, p);
|
||||||
|
lightColor = Color.Lerp(new Color(1f, 0.6f, 0.4f), Color.white, p);
|
||||||
|
}
|
||||||
|
else if (t < 0.5f) // Day
|
||||||
|
{
|
||||||
|
intensity = 1.2f;
|
||||||
|
lightColor = Color.white;
|
||||||
|
}
|
||||||
|
else if (t < 0.7f) // Dusk
|
||||||
|
{
|
||||||
|
float p = (t - 0.5f) / 0.2f;
|
||||||
|
intensity = Mathf.Lerp(1.2f, 0.4f, p);
|
||||||
|
lightColor = Color.Lerp(Color.white, new Color(1f, 0.4f, 0.2f), p);
|
||||||
|
}
|
||||||
|
else // Night
|
||||||
|
{
|
||||||
|
float p = (t - 0.7f) / 0.3f;
|
||||||
|
intensity = Mathf.Lerp(0.4f, 0.2f, p);
|
||||||
|
lightColor = new Color(0.4f, 0.5f, 1f); // Moonlight
|
||||||
|
}
|
||||||
|
|
||||||
|
_mainLight.intensity = intensity;
|
||||||
|
_mainLight.color = lightColor;
|
||||||
|
|
||||||
|
// Rotate sun
|
||||||
|
float sunAngle = t * 360f - 90f;
|
||||||
|
_mainLight.transform.rotation = Quaternion.Euler(sunAngle, -30f, 0);
|
||||||
|
}
|
||||||
|
|
||||||
private void OnDestroy()
|
private void OnDestroy()
|
||||||
{
|
{
|
||||||
var network = NetworkManager.Instance;
|
var network = NetworkManager.Instance;
|
||||||
@@ -338,11 +392,14 @@ namespace TheIsland.Visual
|
|||||||
for (int x = 0; x < size; x++)
|
for (int x = 0; x < size; x++)
|
||||||
{
|
{
|
||||||
float t = (float)y / size;
|
float t = (float)y / size;
|
||||||
Color baseColor = Color.Lerp(waterShallowColor, waterDeepColor, t);
|
// Add some noise to the base color
|
||||||
|
float n = Mathf.PerlinNoise(x * 0.05f, y * 0.05f) * 0.1f;
|
||||||
|
Color baseColor = Color.Lerp(waterShallowColor, waterDeepColor, t + n);
|
||||||
|
|
||||||
// Add wave highlights
|
// Add caustic-like highlights
|
||||||
float wave = Mathf.Sin(x * 0.2f + y * 0.1f) * 0.5f + 0.5f;
|
float wave1 = Mathf.Sin(x * 0.15f + y * 0.05f + Time.time * 0.2f) * 0.5f + 0.5f;
|
||||||
baseColor = Color.Lerp(baseColor, Color.white, wave * 0.1f);
|
float wave2 = Mathf.Cos(x * 0.08f - y * 0.12f + Time.time * 0.15f) * 0.5f + 0.5f;
|
||||||
|
baseColor = Color.Lerp(baseColor, Color.white, (wave1 * wave2) * 0.15f);
|
||||||
|
|
||||||
tex.SetPixel(x, y, baseColor);
|
tex.SetPixel(x, y, baseColor);
|
||||||
}
|
}
|
||||||
@@ -356,8 +413,11 @@ namespace TheIsland.Visual
|
|||||||
if (_waterMaterial == null) return;
|
if (_waterMaterial == null) return;
|
||||||
|
|
||||||
// Simple UV scrolling for wave effect
|
// Simple UV scrolling for wave effect
|
||||||
float offset = Time.time * waveSpeed * 0.1f;
|
float offset = Time.time * waveSpeed * 0.05f;
|
||||||
_waterMaterial.mainTextureOffset = new Vector2(offset, offset * 0.5f);
|
_waterMaterial.mainTextureOffset = new Vector2(offset, offset * 0.3f);
|
||||||
|
|
||||||
|
// Periodically update texture for dynamic caustic effect (expensive but looks premium)
|
||||||
|
// Or just use the original UV scrolling if performance is an issue.
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateLighting()
|
private void CreateLighting()
|
||||||
@@ -414,8 +474,27 @@ namespace TheIsland.Visual
|
|||||||
trunkSprite.transform.localScale = new Vector3(scale * 0.5f, scale, 1);
|
trunkSprite.transform.localScale = new Vector3(scale * 0.5f, scale, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Texture2D _envTexture;
|
||||||
|
|
||||||
|
private void LoadEnvironmentTexture()
|
||||||
|
{
|
||||||
|
string path = Application.dataPath + "/Sprites/Environment.png";
|
||||||
|
if (System.IO.File.Exists(path))
|
||||||
|
{
|
||||||
|
byte[] data = System.IO.File.ReadAllBytes(path);
|
||||||
|
_envTexture = new Texture2D(2, 2);
|
||||||
|
_envTexture.LoadImage(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Sprite CreateTreeSprite()
|
private Sprite CreateTreeSprite()
|
||||||
{
|
{
|
||||||
|
if (_envTexture != null)
|
||||||
|
{
|
||||||
|
// Slice palm tree (Assuming it's in the top-left quadrant of the collection)
|
||||||
|
return Sprite.Create(_envTexture, new Rect(0, _envTexture.height / 2f, _envTexture.width / 2f, _envTexture.height / 2f), new Vector2(0.5f, 0f), 100f);
|
||||||
|
}
|
||||||
|
|
||||||
int width = 64;
|
int width = 64;
|
||||||
int height = 128;
|
int height = 128;
|
||||||
Texture2D tex = new Texture2D(width, height);
|
Texture2D tex = new Texture2D(width, height);
|
||||||
@@ -530,6 +609,12 @@ namespace TheIsland.Visual
|
|||||||
|
|
||||||
private Sprite CreateRockSprite()
|
private Sprite CreateRockSprite()
|
||||||
{
|
{
|
||||||
|
if (_envTexture != null)
|
||||||
|
{
|
||||||
|
// Slice rock from Environment.png (Assuming bottom-right quadrant)
|
||||||
|
return Sprite.Create(_envTexture, new Rect(_envTexture.width / 2f, 0, _envTexture.width / 2f, _envTexture.height / 2f), new Vector2(0.5f, 0.5f), 100f);
|
||||||
|
}
|
||||||
|
|
||||||
int size = 32;
|
int size = 32;
|
||||||
Texture2D tex = new Texture2D(size, size);
|
Texture2D tex = new Texture2D(size, size);
|
||||||
|
|
||||||
@@ -575,7 +660,16 @@ namespace TheIsland.Visual
|
|||||||
private void HandleWeatherChange(WeatherChangeData data)
|
private void HandleWeatherChange(WeatherChangeData data)
|
||||||
{
|
{
|
||||||
_currentWeather = data.new_weather;
|
_currentWeather = data.new_weather;
|
||||||
UpdateSkyColors();
|
Debug.Log($"[EnvironmentManager] Weather changed to: {_currentWeather}");
|
||||||
|
|
||||||
|
// Notify VFX manager
|
||||||
|
if (VisualEffectsManager.Instance != null)
|
||||||
|
{
|
||||||
|
VisualEffectsManager.Instance.SetWeather(_currentWeather);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adjust lighting based on weather
|
||||||
|
UpdateSkyColors(); // This will use the new weather in its logic
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleTick(TickData data)
|
private void HandleTick(TickData data)
|
||||||
|
|||||||
243
unity-client/Assets/Scripts/Visual/VisualEffectsManager.cs
Normal file
243
unity-client/Assets/Scripts/Visual/VisualEffectsManager.cs
Normal file
@@ -0,0 +1,243 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace TheIsland.Visual
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Manages environmental visual effects like fireflies, stars, and weather (Phase 19 & 20).
|
||||||
|
/// </summary>
|
||||||
|
public class VisualEffectsManager : MonoBehaviour
|
||||||
|
{
|
||||||
|
public static VisualEffectsManager Instance { get; private set; }
|
||||||
|
|
||||||
|
[Header("Fireflies")]
|
||||||
|
[SerializeField] private int fireflyCount = 20;
|
||||||
|
[SerializeField] private Color fireflyColor = new Color(1f, 1f, 0.5f, 0.8f);
|
||||||
|
[SerializeField] private Vector2 islandBounds = new Vector2(10, 10);
|
||||||
|
|
||||||
|
[Header("Stars & Meteors")]
|
||||||
|
[SerializeField] private int starCount = 50;
|
||||||
|
[SerializeField] private Color starColor = Color.white;
|
||||||
|
[SerializeField] private float meteorInterval = 15f;
|
||||||
|
|
||||||
|
[Header("Weather VFX")]
|
||||||
|
[SerializeField] private int rainDensity = 120;
|
||||||
|
private List<GameObject> _rainDrops = new List<GameObject>();
|
||||||
|
private string _activeWeather = "Sunny";
|
||||||
|
private Sprite _rainSprite;
|
||||||
|
|
||||||
|
private List<GameObject> _fireflies = new List<GameObject>();
|
||||||
|
private List<GameObject> _stars = new List<GameObject>();
|
||||||
|
private float _meteorTimer;
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
Instance = this;
|
||||||
|
_rainSprite = CreateRainSprite();
|
||||||
|
CreateFireflies();
|
||||||
|
CreateStars();
|
||||||
|
CreateRain();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetWeather(string weather)
|
||||||
|
{
|
||||||
|
_activeWeather = weather;
|
||||||
|
Debug.Log($"[VFXManager] Setting weather visuals for: {weather}");
|
||||||
|
|
||||||
|
// Toggle systems
|
||||||
|
bool isRainy = weather == "Rainy" || weather == "Stormy";
|
||||||
|
foreach (var drop in _rainDrops) drop.SetActive(isRainy);
|
||||||
|
|
||||||
|
if (weather == "Stormy") StartCoroutine(LightningLoop());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
UpdateAtmosphere();
|
||||||
|
UpdateRain();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateAtmosphere()
|
||||||
|
{
|
||||||
|
float t = (Time.time % 120f) / 120f;
|
||||||
|
bool isNight = t > 0.65f || t < 0.15f;
|
||||||
|
float starAlpha = isNight ? (t > 0.75f || t < 0.05f ? 1f : 0.5f) : 0f;
|
||||||
|
|
||||||
|
foreach (var star in _stars)
|
||||||
|
{
|
||||||
|
var sprite = star.GetComponent<SpriteRenderer>();
|
||||||
|
sprite.color = new Color(starColor.r, starColor.g, starColor.b, starAlpha * 0.8f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNight)
|
||||||
|
{
|
||||||
|
_meteorTimer += Time.deltaTime;
|
||||||
|
if (_meteorTimer >= meteorInterval)
|
||||||
|
{
|
||||||
|
_meteorTimer = 0;
|
||||||
|
if (Random.value < 0.3f) StartCoroutine(ShootMeteor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CreateFireflies()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < fireflyCount; i++)
|
||||||
|
{
|
||||||
|
var firefly = new GameObject($"Firefly_{i}");
|
||||||
|
firefly.transform.SetParent(transform);
|
||||||
|
float x = Random.Range(-islandBounds.x, islandBounds.x);
|
||||||
|
float z = Random.Range(-islandBounds.y, islandBounds.y);
|
||||||
|
firefly.transform.position = new Vector3(x, Random.Range(1f, 3f), z);
|
||||||
|
|
||||||
|
var sprite = firefly.AddComponent<SpriteRenderer>();
|
||||||
|
sprite.sprite = CreateGlowSprite();
|
||||||
|
sprite.color = fireflyColor;
|
||||||
|
sprite.sortingOrder = 50;
|
||||||
|
firefly.AddComponent<Billboard>();
|
||||||
|
_fireflies.Add(firefly);
|
||||||
|
StartCoroutine(AnimateFirefly(firefly));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CreateStars()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < starCount; i++)
|
||||||
|
{
|
||||||
|
var star = new GameObject($"Star_{i}");
|
||||||
|
star.transform.SetParent(transform);
|
||||||
|
float x = Random.Range(-25f, 25f);
|
||||||
|
float y = Random.Range(10f, 15f);
|
||||||
|
float z = Random.Range(-25f, 25f);
|
||||||
|
star.transform.position = new Vector3(x, y, z);
|
||||||
|
|
||||||
|
var sprite = star.AddComponent<SpriteRenderer>();
|
||||||
|
sprite.sprite = CreateGlowSprite();
|
||||||
|
sprite.color = new Color(1, 1, 1, 0);
|
||||||
|
sprite.sortingOrder = -50;
|
||||||
|
star.AddComponent<Billboard>().ConfigureForUI();
|
||||||
|
_stars.Add(star);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CreateRain()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < rainDensity; i++)
|
||||||
|
{
|
||||||
|
var drop = new GameObject($"Rain_{i}");
|
||||||
|
drop.transform.SetParent(transform);
|
||||||
|
var sprite = drop.AddComponent<SpriteRenderer>();
|
||||||
|
sprite.sprite = _rainSprite;
|
||||||
|
sprite.color = new Color(0.8f, 0.9f, 1f, 0.6f);
|
||||||
|
sprite.sortingOrder = 100;
|
||||||
|
ResetRainDrop(drop);
|
||||||
|
drop.SetActive(false);
|
||||||
|
_rainDrops.Add(drop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResetRainDrop(GameObject drop)
|
||||||
|
{
|
||||||
|
float x = Random.Range(-20f, 20f);
|
||||||
|
float y = Random.Range(10f, 15f);
|
||||||
|
float z = Random.Range(-20f, 20f);
|
||||||
|
drop.transform.position = new Vector3(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateRain()
|
||||||
|
{
|
||||||
|
if (_activeWeather != "Rainy" && _activeWeather != "Stormy") return;
|
||||||
|
float speed = _activeWeather == "Stormy" ? 40f : 20f;
|
||||||
|
foreach (var drop in _rainDrops)
|
||||||
|
{
|
||||||
|
drop.transform.position += Vector3.down * speed * Time.deltaTime;
|
||||||
|
drop.transform.position += Vector3.left * speed * 0.2f * Time.deltaTime;
|
||||||
|
if (drop.transform.position.y < -2f) ResetRainDrop(drop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerator LightningLoop()
|
||||||
|
{
|
||||||
|
while (_activeWeather == "Stormy")
|
||||||
|
{
|
||||||
|
yield return new WaitForSeconds(Random.Range(3f, 10f));
|
||||||
|
var flash = new GameObject("LightningFlash");
|
||||||
|
var img = flash.AddComponent<SpriteRenderer>();
|
||||||
|
img.sprite = CreateGlowSprite();
|
||||||
|
img.color = new Color(1, 1, 1, 0.8f);
|
||||||
|
flash.transform.position = new Vector3(0, 10, 0);
|
||||||
|
flash.transform.localScale = new Vector3(100, 100, 1);
|
||||||
|
yield return new WaitForSeconds(0.05f);
|
||||||
|
img.color = new Color(1, 1, 1, 0.3f);
|
||||||
|
yield return new WaitForSeconds(0.05f);
|
||||||
|
Destroy(flash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerator ShootMeteor()
|
||||||
|
{
|
||||||
|
var meteor = new GameObject("Meteor");
|
||||||
|
meteor.transform.SetParent(transform);
|
||||||
|
Vector3 startPos = new Vector3(Random.Range(-20, 20), 15, Random.Range(-20, 20));
|
||||||
|
Vector3 direction = new Vector3(Random.Range(-10, 10), -5, Random.Range(-10, 10)).normalized;
|
||||||
|
meteor.transform.position = startPos;
|
||||||
|
var sprite = meteor.AddComponent<SpriteRenderer>();
|
||||||
|
sprite.sprite = CreateGlowSprite();
|
||||||
|
sprite.color = Color.white;
|
||||||
|
sprite.transform.localScale = new Vector3(0.5f, 0.1f, 1f);
|
||||||
|
float duration = 1.0f;
|
||||||
|
float elapsed = 0;
|
||||||
|
while (elapsed < duration)
|
||||||
|
{
|
||||||
|
elapsed += Time.deltaTime;
|
||||||
|
meteor.transform.position += direction * 30f * Time.deltaTime;
|
||||||
|
sprite.color = new Color(1, 1, 1, 1f - (elapsed / duration));
|
||||||
|
yield return null;
|
||||||
|
}
|
||||||
|
Destroy(meteor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Sprite CreateRainSprite()
|
||||||
|
{
|
||||||
|
Texture2D tex = new Texture2D(2, 8);
|
||||||
|
for (int y = 0; y < 8; y++)
|
||||||
|
for (int x = 0; x < 2; x++) tex.SetPixel(x, y, Color.white);
|
||||||
|
tex.Apply();
|
||||||
|
return Sprite.Create(tex, new Rect(0, 0, 2, 8), new Vector2(0.5f, 0.5f));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Sprite CreateGlowSprite()
|
||||||
|
{
|
||||||
|
int size = 32;
|
||||||
|
Texture2D tex = new Texture2D(size, size);
|
||||||
|
tex.filterMode = FilterMode.Bilinear;
|
||||||
|
for (int y = 0; y < size; y++)
|
||||||
|
for (int x = 0; x < size; x++) {
|
||||||
|
float dist = Vector2.Distance(new Vector2(x, y), new Vector2(size/2f, size/2f)) / (size/2f);
|
||||||
|
float alpha = Mathf.Exp(-dist * 4f);
|
||||||
|
tex.SetPixel(x, y, new Color(1, 1, 1, alpha));
|
||||||
|
}
|
||||||
|
tex.Apply();
|
||||||
|
return Sprite.Create(tex, new Rect(0, 0, size, size), new Vector2(0.5f, 0.5f));
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerator AnimateFirefly(GameObject firefly)
|
||||||
|
{
|
||||||
|
Vector3 startPos = firefly.transform.position;
|
||||||
|
float seed = Random.value * 100f;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
float t = Time.time + seed;
|
||||||
|
float dx = (Mathf.PerlinNoise(t * 0.2f, 0) - 0.5f) * 2f;
|
||||||
|
float dy = (Mathf.PerlinNoise(0, t * 0.2f) - 0.5f) * 1f;
|
||||||
|
float dz = (Mathf.PerlinNoise(t * 0.1f, t * 0.1f) - 0.5f) * 2f;
|
||||||
|
firefly.transform.position = startPos + new Vector3(dx, dy, dz);
|
||||||
|
var sprite = firefly.GetComponent<SpriteRenderer>();
|
||||||
|
float pulse = Mathf.PingPong(t, 1f) * 0.5f + 0.5f;
|
||||||
|
sprite.color = new Color(fireflyColor.r, fireflyColor.g, fireflyColor.b, pulse * fireflyColor.a);
|
||||||
|
yield return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 47dcba28f3d78421ca5bdf74a4365bed
|
||||||
BIN
unity-client/Assets/Sprites/Characters.png
Normal file
BIN
unity-client/Assets/Sprites/Characters.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 357 KiB |
143
unity-client/Assets/Sprites/Characters.png.meta
Normal file
143
unity-client/Assets/Sprites/Characters.png.meta
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2976a69bb8c114901b263e613a7b6006
|
||||||
|
TextureImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 13
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 1
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
flipGreenChannel: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
vTOnly: 0
|
||||||
|
ignoreMipmapLimit: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 1
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 0
|
||||||
|
wrapV: 0
|
||||||
|
wrapW: 0
|
||||||
|
nPOTScale: 1
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 0
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 0
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 0
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
flipbookRows: 1
|
||||||
|
flipbookColumns: 1
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
ignorePngGamma: 0
|
||||||
|
applyGammaDecoding: 0
|
||||||
|
swizzle: 50462976
|
||||||
|
cookieLightType: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 4
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 4
|
||||||
|
buildTarget: Standalone
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 4
|
||||||
|
buildTarget: WebGL
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 4
|
||||||
|
buildTarget: iOS
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
customData:
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID:
|
||||||
|
internalID: 0
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
secondaryTextures: []
|
||||||
|
spriteCustomMetadata:
|
||||||
|
entries: []
|
||||||
|
nameFileIdTable: {}
|
||||||
|
mipmapLimitGroupName:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
unity-client/Assets/Sprites/Environment.png
Normal file
BIN
unity-client/Assets/Sprites/Environment.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 632 KiB |
143
unity-client/Assets/Sprites/Environment.png.meta
Normal file
143
unity-client/Assets/Sprites/Environment.png.meta
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8ea1b9777c2a54dea9d8f4fb46a00d03
|
||||||
|
TextureImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 13
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 1
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
flipGreenChannel: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
vTOnly: 0
|
||||||
|
ignoreMipmapLimit: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 1
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 0
|
||||||
|
wrapV: 0
|
||||||
|
wrapW: 0
|
||||||
|
nPOTScale: 1
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 0
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 0
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 0
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
flipbookRows: 1
|
||||||
|
flipbookColumns: 1
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
ignorePngGamma: 0
|
||||||
|
applyGammaDecoding: 0
|
||||||
|
swizzle: 50462976
|
||||||
|
cookieLightType: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 4
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 4
|
||||||
|
buildTarget: Standalone
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 4
|
||||||
|
buildTarget: WebGL
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 4
|
||||||
|
buildTarget: iOS
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
customData:
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID:
|
||||||
|
internalID: 0
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
secondaryTextures: []
|
||||||
|
spriteCustomMetadata:
|
||||||
|
entries: []
|
||||||
|
nameFileIdTable: {}
|
||||||
|
mipmapLimitGroupName:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Reference in New Issue
Block a user