一键导入
day-night-cycle
Time progression, directional light rotation, and event triggers for dawn and dusk.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Time progression, directional light rotation, and event triggers for dawn and dusk.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Detects, diagnoses, and eliminates Garbage Collector pressure in Unity (CoreCLR). Provides patterns for zero-alloc code, Profiler integration guidance, and a GC budget monitoring protocol.
Agentic repair loop for C# compilation errors. Reads compiler output, classifies errors by pattern, and applies targeted, minimal fixes to restore a green build.
Implements a runtime minimap using a second orthographic camera rendering to a RenderTexture, displayed in a UI Toolkit or UGUI panel. Supports icons, fog of war, and zoom.
Implements accessibility (A11y) standards for Unity games: WCAG 2.1 color contrast, font scaling, colorblind modes, motor-impaired input remapping, and audio cues for visually impaired players.
Implements GPU instancing and indirect rendering to render thousands of identical meshes in a single draw call. Covers DrawMeshInstanced, DrawMeshInstancedIndirect, and MaterialPropertyBlock.
Manages texture memory via Unity's Mip Streaming system and streaming budget configuration. Prevents VRAM exhaustion on mobile/console by loading only the required mip levels at runtime.
| name | day-night-cycle |
| description | Time progression, directional light rotation, and event triggers for dawn and dusk. |
| version | 2.0.0 |
| tags | ["gameplay","day-night","lighting","time"] |
| argument-hint | action='generate' cycle_minutes='24' |
| tier | 2 |
| requirements | {"unity_version":">=6.0","render_pipeline":"Any","dependencies":[]} |
| context_discovery | {"check_unity_version":false,"check_render_pipeline":true,"scan_manifest_for":[]} |
| performance_budget | {"gc_alloc_per_frame":"0 bytes","max_update_cost":"O(1) - single rotation and check per frame"} |
| tdd_first | true |
| disable-model-invocation | false |
| user-invocable | true |
| allowed-tools | ["run_command","list_dir","write_to_file"] |
A robust Day/Night cycle system decoupled from rendering. It rotates a Directional Light to simulate the sun, tracks in-game time (0-24 hours), and fires C# events when time-of-day phases change (e.g., Dawn, Noon, Dusk, Midnight).
┌─────────────────────────────────────────────────────────────┐
│ DAY NIGHT CYCLE │
├─────────────────────────────────────────────────────────────┤
│ │
│ TIME TRACKER LIGHT CONTROLLER │
│ ┌────────────────┐ ┌───────────────────────────┐ │
│ │ Tick() │──────────▶│ UpdateRotation() │ │
│ │ CurrentTime │ │ UpdateIntensity() │ │
│ │ OnDayPassed │ └───────────────────────────┘ │
│ └────────────────┘ │
│ │ │
│ ▼ (Events) │
│ ┌────────────────┐ │
│ │ World Events │ (Spawn monsters, close shops) │
│ └────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
[Test]
public void TimePasses_AccordingToTimeScale()
{
var timeSystem = new TimeSystem(dayLengthInSeconds: 60f);
timeSystem.Tick(15f); // Advance 1/4 of a day
Assert.AreEqual(6f, timeSystem.CurrentHour); // 6 AM
}
[Test]
public void TimePassesMidnight_RaisesDayPassedEvent()
{
var timeSystem = new TimeSystem(dayLengthInSeconds: 60f);
timeSystem.SetTime(23f); // 11 PM
bool eventRaised = false;
timeSystem.OnDayPassed += () => eventRaised = true;
timeSystem.Tick(5f); // Pass midnight
Assert.IsTrue(eventRaised);
Assert.AreEqual(1f, timeSystem.CurrentHour); // 1 AM
}
// --- TimeSystem.cs ---
using System;
using UnityEngine;
public class TimeSystem : MonoBehaviour
{
[Header("Settings")]
[Tooltip("How many real-world minutes a full in-game day takes.")]
[SerializeField] private float _dayLengthInMinutes = 24f;
[SerializeField] private Transform _sunLight;
public float CurrentHour { get; private set; } = 8f; // Start at 8 AM
public int CurrentDay { get; private set; } = 1;
public event Action OnDayPassed;
public event Action<float> OnHourChanged;
private float _lastHourBroadcast = -1f;
private void Update()
{
Tick(Time.deltaTime);
}
public void Tick(float deltaSeconds)
{
float timeScale = 24f / (_dayLengthInMinutes * 60f);
CurrentHour += deltaSeconds * timeScale;
if (CurrentHour >= 24f)
{
CurrentHour -= 24f;
CurrentDay++;
OnDayPassed?.Invoke();
}
int intHour = Mathf.FloorToInt(CurrentHour);
if (intHour != _lastHourBroadcast)
{
_lastHourBroadcast = intHour;
OnHourChanged?.Invoke(CurrentHour);
}
UpdateSunRotation();
}
private void UpdateSunRotation()
{
if (_sunLight == null) return;
// 6 AM = 0 degrees (sunrise), 12 PM = 90 degrees (noon), 6 PM = 180 degrees (sunset)
float sunAngle = (CurrentHour - 6f) / 24f * 360f;
_sunLight.rotation = Quaternion.Euler(sunAngle, 0f, 0f);
}
public void SetTime(float newHour) => CurrentHour = Mathf.Repeat(newHour, 24f);
}
OnHourChanged, OnDayPassed) so other systems can react without polling.@save-load-serialization — Save the CurrentDay and CurrentHour.@event-bus-system — Broadcast time changes globally without tight coupling.