This commit is contained in:
2026-09-28 16:11:10 +02:00
parent fb630e5a7a
commit b0c6111d57
5 changed files with 92 additions and 8 deletions
+1 -1
View File
@@ -57,7 +57,7 @@ public sealed class PortalExitMarker : MonoBehaviour
}
private void LateUpdate()
{
if (!meadow || !meadow.Following || period <= 0) return;
if (!meadow || !meadow.Endless || period <= 0) return;
float poolPeriod = period * 3;
foreach (Transform marker in markers)
{
+8 -6
View File
@@ -29,8 +29,8 @@ public sealed class PortalMeadow : MonoBehaviour
[SerializeField, Min(1)] private float boundsPadding = 128;
[Tooltip("Rendering layers of every generated PortalB renderer, so lights can be restricted to this world.")]
[SerializeField] private RenderingLayerMask renderingLayers = 1u;
[Tooltip("While not following the player, the bend is computed from this frame (e.g. the portal, looking along its forward axis) " +
"instead of the camera, so it stays aligned and still behind the portal.")]
[Tooltip("Entrance (e.g. the portal). While not following the player, the bend is computed from this frame (looking along its forward axis) " +
"instead of the camera, and the disk is centred on it, so everything stays aligned and still behind the portal.")]
[SerializeField] private Transform bendAnchor;
[Tooltip("Blend from the anchor frame to the camera once the player follows.")]
[SerializeField, Min(0)] private float bendFadeDuration = 1.5f;
@@ -65,7 +65,7 @@ public sealed class PortalMeadow : MonoBehaviour
public bool Endless => endless && Application.isPlaying;
/// <summary>Endless and currently recentering on the player (see SetFollowPlayer).</summary>
public bool Following => Endless && followPlayer;
public Vector3 SurfaceCenter => Following && capturedPlayer ? surfaceCenter : Center;
public Vector3 SurfaceCenter => Endless ? surfaceCenter : Center;
public void ConfigureRegion(Material target)
{
@@ -112,9 +112,11 @@ public sealed class PortalMeadow : MonoBehaviour
{
frameBlend = !Following ? 0 : bendFadeDuration > 0 ? Mathf.MoveTowards(frameBlend, 1, Time.deltaTime / bendFadeDuration) : 1;
surfaceCenter = Center;
if (Following && capturedPlayer)
// Before the crossing, the disk is already centred on the entrance, so following the player does not jump.
Transform focus = !Endless ? null : Following ? capturedPlayer : bendAnchor;
if (focus)
{
Vector3 p = transform.InverseTransformPoint(capturedPlayer.position);
Vector3 p = transform.InverseTransformPoint(focus.position);
surfaceCenter.x = p.x; surfaceCenter.z = p.z;
}
if (groundCollider) groundCollider.center = SurfaceCenter + Vector3.down * (colliderThickness * 0.5f);
@@ -129,7 +131,7 @@ public sealed class PortalMeadow : MonoBehaviour
{
Transform tile = tiles[i];
Vector3 p = tile.localPosition;
if (Following)
if (Endless)
{
p.x += Mathf.Floor((SurfaceCenter.x - p.x - tileSize.x * 0.5f + patchSize.x * 0.5f) / patchSize.x) * patchSize.x;
p.z += Mathf.Floor((SurfaceCenter.z - p.z - tileSize.y * 0.5f + patchSize.y * 0.5f) / patchSize.y) * patchSize.y;
+15 -1
View File
@@ -32,6 +32,8 @@ public sealed class PortalServerGrid : MonoBehaviour
private bool rebuild;
private readonly Dictionary<Material, Material> curvedMaterials = new Dictionary<Material, Material>();
private readonly List<Transform> servers = new List<Transform>();
private readonly List<Collider> colliders = new List<Collider>();
private bool collidersEnabled = true;
private float wrapExtent;
// Distance between the centres of two repeated server clusters.
public float RepetitionPeriod => wrapExtent * 2;
@@ -63,6 +65,8 @@ public sealed class PortalServerGrid : MonoBehaviour
if (!meadow) meadow = GetComponent<PortalMeadow>();
if (!meadow) return;
SyncBend();
// Servers are invisible until the player crossed the portal, so they only block once the meadow follows the player.
SetCollidersEnabled(!meadow.Endless || meadow.Following);
if (!rebuild && lastSize == meadow.Size && lastCenter == meadow.Center && lastEndless == meadow.Endless) return;
rebuild = false;
lastSize = meadow.Size;
@@ -77,7 +81,7 @@ public sealed class PortalServerGrid : MonoBehaviour
}
private void LateUpdate()
{
if (!meadow || !meadow.Following || wrapExtent <= 0) return;
if (!meadow || !meadow.Endless || wrapExtent <= 0) return;
Vector3 centre = meadow.SurfaceCenter;
float period = wrapExtent * 2;
foreach (Transform server in servers)
@@ -89,6 +93,12 @@ public sealed class PortalServerGrid : MonoBehaviour
server.localPosition = p;
}
}
private void SetCollidersEnabled(bool enabled)
{
if (collidersEnabled == enabled) return;
collidersEnabled = enabled;
foreach (Collider collider in colliders) if (collider) collider.enabled = enabled;
}
[ContextMenu("Regenerate server rings")]
private void Regenerate() { rebuild = true; }
@@ -104,6 +114,7 @@ public sealed class PortalServerGrid : MonoBehaviour
foreach (Material material in curvedMaterials.Values) if (material) Release(material);
curvedMaterials.Clear();
servers.Clear();
colliders.Clear();
}
private GameObject CreateServer()
{
@@ -182,6 +193,9 @@ public sealed class PortalServerGrid : MonoBehaviour
servers.Add(server.transform);
}
if (count == 0) { Clear(); return; }
colliders.AddRange(generated.GetComponentsInChildren<Collider>(true));
collidersEnabled = true; // As instantiated from the prefab.
SetCollidersEnabled(!meadow.Endless || meadow.Following);
SyncBend();
generated.SetActive(true);
}