Unity中twoSides为true时如何生成双列等间距路径灯光?
Hey Daniel, let's get that two-sided lighting sorted out properly. I know the current setup just doubles up lights in a single line when twoSides is enabled, and your modified duplicateObject method is causing uneven spacing and path drift—let's fix this with clean, path-aligned logic.
The Core Issue
The original approach wasn't accounting for perpendicular alignment to the path—it was just spawning duplicates near the original lights instead of creating a parallel column. This leads to lights drifting off the path and inconsistent gaps between columns.
Step-by-Step Solution
First, add a public variable to control how far apart your two columns are (easy to tweak in the Inspector):
public float columnSpacing = 2f; // Adjust this value to set your desired column gap
Next, we need to calculate a consistent perpendicular direction relative to each path segment. This ensures our second column stays parallel to the path, no matter how the waypoints turn. Update your light-spawning logic with this:
Refactored Spawning Logic
Let's assume you have a loop that iterates between waypoints and calculates light positions along the path. Replace your existing spawn code with this:
// Inside your waypoint traversal loop Vector3 currentWaypoint = waypoints[i]; Vector3 nextWaypoint = waypoints[i + 1]; // Calculate direction of the current path segment Vector3 pathDirection = (nextWaypoint - currentWaypoint).normalized; // Get perpendicular direction (use Vector3.forward if working in top-down Z-up space) Vector3 perpendicularDirection = Vector3.Cross(pathDirection, Vector3.up).normalized; // Iterate along the segment to spawn lights (t = 0 to 1) for (float t = 0; t <= 1; t += lightSpacing) // lightSpacing is your original single-column gap { Vector3 centerPosition = Vector3.Lerp(currentWaypoint, nextWaypoint, t); // Spawn left column light GameObject leftLight = Instantiate(lightPrefab, centerPosition + perpendicularDirection * (columnSpacing / 2f), lightPrefab.transform.rotation); leftLight.transform.parent = transform; // Spawn right column light GameObject rightLight = Instantiate(lightPrefab, centerPosition - perpendicularDirection * (columnSpacing / 2f), lightPrefab.transform.rotation); rightLight.transform.parent = transform; }
If You Want to Keep the duplicateObject Method
If you prefer using your existing duplicateObject method, refactor it to accept the perpendicular offset:
private void duplicateObject(GameObject originalPrefab, Vector3 centerPos, Vector3 perpDir, float halfColumnSpacing) { // Spawn left column light GameObject leftLight = Instantiate(originalPrefab, centerPos + perpDir * halfColumnSpacing, originalPrefab.transform.rotation); leftLight.transform.parent = transform; // Spawn right column light GameObject rightLight = Instantiate(originalPrefab, centerPos - perpDir * halfColumnSpacing, originalPrefab.transform.rotation); rightLight.transform.parent = transform; }
Then call it from your loop like this:
Vector3 centerPosition = Vector3.Lerp(currentWaypoint, nextWaypoint, t); duplicateObject(lightPrefab, centerPosition, perpendicularDirection, columnSpacing / 2f);
Key Fixes Breakdown
- Perpendicular Alignment: Using
Vector3.Crossgives us a direction 90 degrees to the path, so both columns stay parallel even on curved paths. SwapVector3.upwith your scene's up axis if needed (e.g.,Vector3.forwardfor top-down games). - Centered Columns: Splitting
columnSpacinginto two halves ensures both columns are equidistant from the original path line—no more drift. - Even Spacing: By spawning two lights at each interpolated position along the path, you maintain the same gap between lights (both within columns and across columns) as your single-column setup.
Quick Tweak for Light Count
If you want the same total number of lights as single-column mode, halve your lightSpacing value when twoSides is enabled. Otherwise, you'll end up with twice as many lights (which is usually desired for two full columns).
内容的提问来源于stack exchange,提问作者Daniel Lip

