浏览代码

Adding in BSP generation to select spawn positions for the symbols.

/main/staging/ngo_minigame_cleanup
nathaniel.buck@unity3d.com 2 年前
当前提交
26cfa9d6
共有 6 个文件被更改,包括 86 次插入10 次删除
  1. 2
      Assets/Prefabs/NGO/InGameLogic.prefab
  2. 1
      Assets/Prefabs/NGO/SymbolContainer.prefab
  3. 8
      Assets/Scripts/Netcode/InGameRunner.cs
  4. 80
      Assets/Scripts/Netcode/SequenceSelector.cs
  5. 3
      Assets/Scripts/Netcode/SymbolContainer.cs
  6. 2
      ProjectSettings/Packages/com.unity.services.vivox/Settings.json

2
Assets/Prefabs/NGO/InGameLogic.prefab


far clip plane: 50
field of view: 60
orthographic: 1
orthographic size: 7.5
orthographic size: 8.5
m_Depth: 0
m_CullingMask:
serializedVersion: 2

1
Assets/Prefabs/NGO/SymbolContainer.prefab


m_Name:
m_EditorClassIdentifier:
m_rb: {fileID: 6367926983050135602}
m_speed: 2

8
Assets/Scripts/Netcode/InGameRunner.cs


private void ResetPendingSymbolPositions()
{
m_pendingSymbolPositions.Clear();
for (int n = 0; n < SequenceSelector.k_symbolCount; n++)
{
// TEMP we need to do a BSP or some such to mix up the positions.
m_pendingSymbolPositions.Enqueue(new Vector2(-9 + (n % 10) * 2, n / 10 * 3));
}
IList<Vector2> points = m_sequenceSelector.GenerateRandomSpawnPoints(new Rect(-15, 0, 30, 120), 2);
foreach (Vector2 point in points)
m_pendingSymbolPositions.Enqueue(point);
}
/// <summary>

80
Assets/Scripts/Netcode/SequenceSelector.cs


using Unity.Netcode;
using UnityEngine;
using UnityEngine.UI;
using Random = UnityEngine.Random;
namespace LobbyRelaySample.ngo
{

{
[SerializeField] private SymbolData m_symbolData = default;
[SerializeField] private Image[] m_targetSequenceOutput = default;
public const int k_symbolCount = 100;
public const int k_symbolCount = 200;
private bool m_hasReceivedTargetSequence = false; // TODO: Perhaps split up members by client vs. host?
private ulong m_localId;
private bool m_canAnimateTargets = false;

m_targetSequence.Add(symbolsForThisGame[2]);
// Then, ensure that the target sequence is present in order throughout most of the full set of symbols to spawn.
int numTargetSequences = k_symbolCount / 6; // About 1/2 of the 3 symbols will be definitely part of the target sequence.
int numTargetSequences = (int)(k_symbolCount * 2/3f) / 3; // About 2/3 of the symbols will be definitely part of the target sequence.
for (; numTargetSequences >= 0; numTargetSequences--)
{ m_fullSequence.Add(m_targetSequence[2]); // We want a List instead of a Queue or Stack for faster insertion, but we will remove indices backwards so as to not reshift other entries.
m_fullSequence.Add(m_targetSequence[1]);

m_canAnimateTargets = true;
ScaleTargetUi(m_localId, 0);
}
}
/// <summary>
/// Used for the binary space partition (BSP) algorithm, which makes alternating "cuts" to subdivide rectangles.
/// </summary>
private struct RectCut
{
public Rect rect;
// The spawn region will be much taller than it is wide, so we'll do more horizontal cuts (instead of just alternating between horizontal and vertical).
public int cutIndex;
public bool isVertCut { get { return cutIndex % 3 == 2; } }
public RectCut(Rect rect, int cutIndex) { this.rect = rect; this.cutIndex = cutIndex; }
public RectCut(float xMin, float xMax, float yMin, float yMax, int cutIndex)
{
this.rect = new Rect(xMin, yMin, xMax - xMin, yMax - yMin);
this.cutIndex = cutIndex;
}
}
/// <summary>
/// Selects a randomized series of spawn positions within the provided xy-bounds, or just a simple grid of positions if selection fails.
/// </summary>
/// <param name="bounds">Rectangle of space to subdivide.</param>
/// <param name="extent">The minimum space between points, to ensure that spawned symbol objects won't overlap.</param>
/// <param name="count">How many positions to choose.</param>
/// <returns>Position list in arbitrary order.</returns>
public List<Vector2> GenerateRandomSpawnPoints(Rect bounds, float extent, int count = k_symbolCount)
{
int numTries = 3;
List<Vector2> points = new List<Vector2>();
while (numTries > 0)
{
Queue<RectCut> rects = new Queue<RectCut>();
points.Clear();
rects.Enqueue(new RectCut(bounds, -1)); // Start with an extra horizontal cut since the space is so tall.
// For each rect, subdivide it with an alternating cut, and then enqueue for recursion until enough points are chosen or the rects are all too small.
// This ensures a reasonable distribution of points which won't cause overlaps, though it will not necessarily be uniform.
while (rects.Count + points.Count < count && rects.Count > 0)
{
RectCut currRect = rects.Dequeue();
bool isLargeEnough = (currRect.isVertCut && currRect.rect.width > extent * 2) || (!currRect.isVertCut && currRect.rect.height > extent * 2);
if (!isLargeEnough)
{ points.Add(currRect.rect.center);
continue;
}
float xMin = currRect.rect.xMin, xMax = currRect.rect.xMax, yMin = currRect.rect.yMin, yMax = currRect.rect.yMax;
if (currRect.isVertCut)
{ float cutPosX = Random.Range(xMin + extent, xMax - extent);
rects.Enqueue( new RectCut(xMin, cutPosX, yMin, yMax, currRect.cutIndex + 1) );
rects.Enqueue( new RectCut(cutPosX, xMax, yMin, yMax, currRect.cutIndex + 1) );
}
else
{ float cutPosY = Random.Range(yMin + extent, yMax - extent);
rects.Enqueue( new RectCut(xMin, xMax, yMin, cutPosY, currRect.cutIndex + 1) );
rects.Enqueue( new RectCut(xMin, xMax, cutPosY, yMax, currRect.cutIndex + 1) );
}
}
while (rects.Count > 0)
points.Add(rects.Dequeue().rect.center);
if (points.Count >= count)
return points;
numTries--;
}
Debug.LogError("Failed to generate symbol spawn points. Defaulting to a simple grid of points.");
points.Clear();
int numPerLine = Mathf.CeilToInt(bounds.width / (extent * 1.5f));
for (int n = 0; n < count; n++)
points.Add(new Vector2(Mathf.Lerp(bounds.xMin, bounds.xMax, (n % numPerLine) / (numPerLine - 1f)), n / numPerLine * extent * 1.5f));
return points;
}
}
}

3
Assets/Scripts/Netcode/SymbolContainer.cs


public class SymbolContainer : NetworkBehaviour, IReceiveMessages
{
[SerializeField] private Rigidbody m_rb = default;
[SerializeField] private float m_speed = 1;
private bool m_isConnected = false;
private bool m_hasGameStarted = false;
private void OnGameStarted()

private void BeginMotion()
{
m_rb.velocity = Vector3.down;
m_rb.velocity = Vector3.down * m_speed;
}
public void OnReceiveMessage(MessageType type, object msg)

2
ProjectSettings/Packages/com.unity.services.vivox/Settings.json


{
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "isEnvironmentCustom",
"value": "{\"m_Value\":true}"
"value": "{\"m_Value\":false}"
},
{
"type": "System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",

正在加载...
取消
保存