Skip to content

Commit 48106f4

Browse files
committed
Moved automap 10,000 meters below the world, so it no longer overlaps geo
This solves the issue where it occasionally consumes raycasts meant to hit e.g. levers.
1 parent ff59bc3 commit 48106f4

2 files changed

Lines changed: 65 additions & 41 deletions

File tree

Assets/Scripts/Game/Automap.cs

Lines changed: 47 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ public override string ToString()
168168
const float raycastDistanceDown = 3.0f; // 3 meters should be enough (note: flying too high will result in geometry not being revealed by this raycast
169169
const float raycastDistanceViewDirection = 30.0f; // don't want to make it too easy to discover big halls - although it shouldn't be to small as well
170170
const float raycastDistanceEntranceMarkerReveal = 100.0f;
171+
static readonly Vector3 automapOffset = new Vector3(0, -10000.0f, 0); // positional offset of the automap geometry, so that it does not overlap real geo
171172

172173
const float scanRateGeometryDiscoveryInHertz = 5.0f; // n times per second the discovery of new geometry/meshes is checked
173174

@@ -389,6 +390,22 @@ public void SetState(Dictionary<string, AutomapDungeonState> savedDictAutomapDun
389390
dictAutomapDungeonsDiscoveryState = savedDictAutomapDungeonsDiscoveryState;
390391
}
391392

393+
/// <summary>
394+
/// Conversion of real game world position to automap position
395+
/// </summary>
396+
public Vector3 ToAutomapPosition(Vector3 realPosition)
397+
{
398+
return realPosition + automapOffset;
399+
}
400+
401+
/// <summary>
402+
/// Conversion of automap position to real game world position
403+
/// </summary>
404+
public Vector3 FromAutomapPosition(Vector3 automapPosition)
405+
{
406+
return automapPosition - automapOffset;
407+
}
408+
392409
/// <summary>
393410
/// sets the number of dungeons that are memorized
394411
/// </summary>
@@ -406,10 +423,10 @@ public void UpdateAutomapStateOnWindowPush()
406423
// since new teleporters could have been discovered by pc since last time map was open this must be checked here
407424
CreateTeleporterMarkers();
408425

409-
gameobjectPlayerMarkerArrow.transform.position = gameObjectPlayerAdvanced.transform.position;
426+
gameobjectPlayerMarkerArrow.transform.position = ToAutomapPosition(gameObjectPlayerAdvanced.transform.position);
410427
gameobjectPlayerMarkerArrow.transform.rotation = gameObjectPlayerAdvanced.transform.rotation;
411428

412-
gameobjectBeaconPlayerPosition.transform.position = gameObjectPlayerAdvanced.transform.position + rayPlayerPosOffset;
429+
gameobjectBeaconPlayerPosition.transform.position = ToAutomapPosition(gameObjectPlayerAdvanced.transform.position + rayPlayerPosOffset);
413430

414431
// create camera (if not present) that will render automap level geometry
415432
CreateAutomapCamera();
@@ -653,7 +670,7 @@ public bool UpdateMouseHoverOverGameObjects(Vector2 screenPosition)
653670
}
654671
}
655672

656-
gameobjectTeleporterConnection.transform.position = (connection.teleporterEntrance.position + connection.teleporterExit.position) * 0.5f;
673+
gameobjectTeleporterConnection.transform.position = ToAutomapPosition((connection.teleporterEntrance.position + connection.teleporterExit.position) * 0.5f);
657674
gameobjectTeleporterConnection.transform.localScale = new Vector3(0.2f, (connection.teleporterEntrance.position - connection.teleporterExit.position).magnitude * 0.5f, 0.2f);
658675
gameobjectTeleporterConnection.transform.rotation = Quaternion.FromToRotation(Vector3.up, (connection.teleporterEntrance.position - connection.teleporterExit.position));
659676

@@ -763,7 +780,7 @@ public void TryToAddOrEditUserNoteMarkerOnDungeonSegmentAtScreenPosition(Vector2
763780
if (!nearestHit.Value.transform.name.StartsWith(NameGameobjectUserNoteMarkerSubStringStart))
764781
{
765782
// add a new user note marker
766-
Vector3 spawningPosition = (nearestHit.Value.point) + nearestHit.Value.normal * 0.7f;
783+
Vector3 spawningPosition = FromAutomapPosition(nearestHit.Value.point + nearestHit.Value.normal * 0.7f);
767784

768785
// test if there is already a user note marker near to the requested spawning position
769786
var enumerator = listUserNoteMarkers.GetEnumerator();
@@ -825,7 +842,7 @@ public void TryCenterAutomapCameraOnDungeonSegmentAtScreenPosition(Vector2 scree
825842

826843
if (nearestHit.HasValue)
827844
{
828-
float distance = (cameraAutomap.transform.position - gameObjectPlayerAdvanced.transform.position).magnitude;
845+
float distance = (cameraAutomap.transform.position - ToAutomapPosition(gameObjectPlayerAdvanced.transform.position)).magnitude;
829846
cameraAutomap.transform.position = (nearestHit.Value.point);
830847
cameraAutomap.transform.position -= cameraAutomap.transform.forward * distance;
831848
}
@@ -858,9 +875,10 @@ public void TryTeleportPlayerToDungeonSegmentAtScreenPosition(Vector2 screenPosi
858875

859876
if (nearestHit.HasValue)
860877
{
861-
gameObjectPlayerAdvanced.transform.position = nearestHit.Value.point + Vector3.up * 0.1f;
862-
gameobjectBeaconPlayerPosition.transform.position = nearestHit.Value.point + rayPlayerPosOffset;
863-
gameobjectPlayerMarkerArrow.transform.position = nearestHit.Value.point + rayPlayerPosOffset;
878+
Vector3 realHitPoint = FromAutomapPosition(nearestHit.Value.point);
879+
gameObjectPlayerAdvanced.transform.position = realHitPoint + Vector3.up * 0.1f;
880+
gameobjectBeaconPlayerPosition.transform.position = ToAutomapPosition(realHitPoint + rayPlayerPosOffset);
881+
gameobjectPlayerMarkerArrow.transform.position = ToAutomapPosition(realHitPoint + rayPlayerPosOffset);
864882
}
865883

866884
// don't forget to update micro map texture, so new player position is visualized correctly on micro map
@@ -1080,11 +1098,12 @@ void Update()
10801098
#endif
10811099

10821100
// main raycast (on Colliders in layer "Automap")
1083-
bool didHit1 = Physics.Raycast(rayStartPos, rayDirection, out hit1, rayDistance, 1 << layerAutomap);
1101+
Vector3 automapRayStartPos = ToAutomapPosition(rayStartPos);
1102+
bool didHit1 = Physics.Raycast(automapRayStartPos, rayDirection, out hit1, rayDistance, 1 << layerAutomap);
10841103
// 2nd (protection) raycast (on Colliders in layer "Automap") with offset (protection against hole in daggerfall geometry prevention)
1085-
bool didHit2 = Physics.Raycast(rayStartPos + offsetSecondProtectionRaycast, rayDirection, out hit2, rayDistance, 1 << layerAutomap);
1104+
bool didHit2 = Physics.Raycast(automapRayStartPos + offsetSecondProtectionRaycast, rayDirection, out hit2, rayDistance, 1 << layerAutomap);
10861105
// 3rd (protection) raycast (on Colliders in layer "Automap") with offset (protection against hole in daggerfall geometry prevention)
1087-
bool didHit3 = Physics.Raycast(rayStartPos + offsetThirdProtectionRaycast, rayDirection, out hit3, rayDistance, 1 << layerAutomap);
1106+
bool didHit3 = Physics.Raycast(automapRayStartPos + offsetThirdProtectionRaycast, rayDirection, out hit3, rayDistance, 1 << layerAutomap);
10881107

10891108
#if DEBUG_RAYCASTS
10901109
//Debug.Log(String.Format("hitTG1: {0}, hitTG2: {1}, hitTG3: {2}, hit1: {3}, hit2: {4}, hit3: {5}", didHitTrueLevelGeometry1, didHitTrueLevelGeometry2, didHitTrueLevelGeometry3, didHit1, didHit2, didHit3));
@@ -1197,7 +1216,7 @@ void CheckForNewlyDiscoveredMeshes()
11971216

11981217
int layerMask = (1 << layerPlayer) + 1; // test against player and level geometry (+1... == 1 << 1 == "Default" layer == level geometry)
11991218

1200-
Vector3 entranceMarkerPos = gameObjectEntrancePositionCubeMarker.transform.position;
1219+
Vector3 entranceMarkerPos = FromAutomapPosition(gameObjectEntrancePositionCubeMarker.transform.position);
12011220
Vector3 playerColliderPos = playerCollider.transform.position; //GameManager.Instance.PlayerGPS.transform.position; //Camera.main.transform.position;
12021221
// raycast 1
12031222
Vector3 rayStartPos = entranceMarkerPos;
@@ -1283,7 +1302,7 @@ private void UpdateSlicingPositionY()
12831302
{
12841303
float slicingPositionY;
12851304
if (!DaggerfallUnity.Settings.AutomapAlwaysMaxOutSliceLevel)
1286-
slicingPositionY = gameObjectPlayerAdvanced.transform.position.y + Camera.main.transform.localPosition.y + slicingBiasY;
1305+
slicingPositionY = ToAutomapPosition(gameObjectPlayerAdvanced.transform.position + Camera.main.transform.localPosition).y + slicingBiasY;
12871306
else
12881307
slicingPositionY = float.MaxValue;
12891308
Shader.SetGlobalFloat("_SclicingPositionY", slicingPositionY);
@@ -1324,7 +1343,7 @@ private void SetupBeacons(StaticDoor ?entranceDoor = null)
13241343
gameobjectPlayerMarkerArrow.layer = layerAutomap;
13251344
gameobjectPlayerMarkerArrow.AddComponent<MeshCollider>();
13261345
}
1327-
gameobjectPlayerMarkerArrow.transform.position = gameObjectPlayerAdvanced.transform.position;
1346+
gameobjectPlayerMarkerArrow.transform.position = ToAutomapPosition(gameObjectPlayerAdvanced.transform.position);
13281347
gameobjectPlayerMarkerArrow.transform.rotation = gameObjectPlayerAdvanced.transform.rotation;
13291348

13301349
if (!gameobjectBeaconPlayerPosition)
@@ -1340,7 +1359,7 @@ private void SetupBeacons(StaticDoor ?entranceDoor = null)
13401359
//SetMaterialTransparency(material);
13411360
gameobjectBeaconPlayerPosition.GetComponent<MeshRenderer>().material = material;
13421361
}
1343-
gameobjectBeaconPlayerPosition.transform.position = gameObjectPlayerAdvanced.transform.position + rayPlayerPosOffset;
1362+
gameobjectBeaconPlayerPosition.transform.position = ToAutomapPosition(gameObjectPlayerAdvanced.transform.position + rayPlayerPosOffset);
13441363

13451364
if (!gameobjectBeaconRotationPivotAxis)
13461365
{
@@ -1411,17 +1430,19 @@ private void SetupBeacons(StaticDoor ?entranceDoor = null)
14111430
{
14121431
// entrance marker to dungeon start marker
14131432
DaggerfallDungeon dungeon = GameManager.Instance.DungeonParent.GetComponentInChildren<DaggerfallDungeon>();
1414-
gameobjectBeaconEntrancePosition.transform.position = dungeon.StartMarker.transform.position + rayEntrancePosOffset;
1433+
gameobjectBeaconEntrancePosition.transform.position = ToAutomapPosition(dungeon.StartMarker.transform.position + rayEntrancePosOffset);
14151434
gameobjectBeaconEntrancePosition.SetActive(false); // set do undiscovered
14161435
}
14171436
else
14181437
{
14191438
// entrance marker to current position (position player entered)
14201439
StaticDoor door = entranceDoor.Value;
1421-
gameobjectBeaconEntrancePosition.transform.position = door.ownerRotation * door.buildingMatrix.MultiplyPoint3x4(door.centre);
1422-
gameobjectBeaconEntrancePosition.transform.position += door.ownerPosition;
1440+
Vector3 entrancePosition = door.ownerRotation * door.buildingMatrix.MultiplyPoint3x4(door.centre);
1441+
entrancePosition += door.ownerPosition;
1442+
gameobjectBeaconEntrancePosition.transform.position = ToAutomapPosition(entrancePosition);
14231443
gameobjectBeaconEntrancePosition.SetActive(true); // set do discovered
14241444
}
1445+
14251446
}
14261447

14271448
private void DestroyBeacons()
@@ -1543,7 +1564,7 @@ private GameObject CreateUserMarker(int id, Vector3 spawningPosition)
15431564
}
15441565
GameObject gameObjectUserNoteMarker = CreateDiamondShapePrimitive();
15451566
gameObjectUserNoteMarker.transform.SetParent(gameObjectUserNoteMarkers.transform);
1546-
gameObjectUserNoteMarker.transform.position = spawningPosition;
1567+
gameObjectUserNoteMarker.transform.position = ToAutomapPosition(spawningPosition);
15471568
gameObjectUserNoteMarker.name = NameGameobjectUserNoteMarkerSubStringStart + id;
15481569
Material materialUserNoteMarker = new Material(Shader.Find("Standard"));
15491570
materialUserNoteMarker.color = new Color(1.0f, 0.55f, 0.0f);
@@ -1594,7 +1615,7 @@ private void AddTeleporterMarkerOnMap(TeleporterTransform startPoint, Teleporter
15941615
{
15951616
GameObject gameObjectTeleporterEntrance = new GameObject(teleporterEntranceName);
15961617
gameObjectTeleporterEntrance.transform.SetParent(gameobjectTeleporterMarkers.transform);
1597-
gameObjectTeleporterEntrance.transform.position = startPoint.position; // + Vector3.up * 1.0f;
1618+
gameObjectTeleporterEntrance.transform.position = ToAutomapPosition(startPoint.position); // + Vector3.up * 1.0f;
15981619
gameObjectTeleporterEntrance.transform.rotation = startPoint.rotation;
15991620
gameObjectTeleporterEntrance.transform.Rotate(0.0f, 90.0f, 0.0f);
16001621
gameObjectTeleporterEntrance.layer = layerAutomap;
@@ -1618,7 +1639,7 @@ private void AddTeleporterMarkerOnMap(TeleporterTransform startPoint, Teleporter
16181639
{
16191640
GameObject gameObjectTeleporterExit = new GameObject(teleporterExitName);
16201641
gameObjectTeleporterExit.transform.SetParent(gameobjectTeleporterMarkers.transform);
1621-
gameObjectTeleporterExit.transform.position = endPoint.position; // + Vector3.up * 0.2f;
1642+
gameObjectTeleporterExit.transform.position = ToAutomapPosition(endPoint.position); // + Vector3.up * 0.2f;
16221643
//gameObjectTeleporterExit.transform.rotation = endPoint.rotation;
16231644
//gameObjectTeleporterExit.transform.Rotate(0.0f, 180.0f, 0.0f);
16241645
gameObjectTeleporterExit.transform.rotation = startPoint.rotation; // take rotation from portal entrance
@@ -1812,7 +1833,7 @@ private void GetRayCastNearestHitOnAutomapLayer(Vector2 screenPosition, out Rayc
18121833
float nearestDistance = float.MaxValue;
18131834
foreach (RaycastHit hit in hits)
18141835
{
1815-
if ((hit.distance < nearestDistance) && (hit.collider.gameObject.GetComponent<MeshRenderer>().enabled))
1836+
if ((hit.distance < nearestDistance) && hit.collider.gameObject.TryGetComponent(out MeshRenderer meshRend) && meshRend.enabled)
18161837
{
18171838
nearestHit = hit;
18181839
nearestDistance = hit.distance;
@@ -1856,7 +1877,7 @@ private void CreateIndoorGeometryForAutomap(StaticDoor door)
18561877
gameobjectInterior.transform.SetParent(gameobjectGeometry.transform);
18571878

18581879
// copy position and rotation from real level geometry
1859-
gameobjectGeometry.transform.position = elem.transform.position;
1880+
gameobjectGeometry.transform.position = ToAutomapPosition(elem.transform.position);
18601881
gameobjectGeometry.transform.rotation = elem.transform.rotation;
18611882

18621883
// do this (here in createIndoorGeometryForAutomap()) analog in the same way and the same place like in createDungeonGeometryForAutomap()
@@ -1920,7 +1941,7 @@ private void CreateDungeonGeometryForAutomap()
19201941
gameobjectDungeon.transform.SetParent(gameobjectGeometry.transform);
19211942

19221943
// copy position and rotation from real level geometry
1923-
gameobjectGeometry.transform.position = elem.transform.position;
1944+
gameobjectGeometry.transform.position = ToAutomapPosition(elem.transform.position);
19241945
gameobjectGeometry.transform.rotation = elem.transform.rotation;
19251946

19261947
// do this here when DaggerfallDungeon GameObject is present, so that a call to SetupBeacons() will not fail (it needs the DaggerfallDungeon component of this GameObject)
@@ -1950,7 +1971,7 @@ private void AddWater(GameObject parent, short nativeBlockWaterLevel)
19501971
if (nativeBlockWaterLevel == 10000)
19511972
return;
19521973

1953-
float waterLevel = nativeBlockWaterLevel * -1 * MeshReader.GlobalScale;
1974+
float waterLevel = ToAutomapPosition(new Vector3(0, nativeBlockWaterLevel * -1 * MeshReader.GlobalScale, 0)).y;
19541975
MeshRenderer[] renderers = parent.GetComponentsInChildren<MeshRenderer>();
19551976

19561977
if (renderers != null)
@@ -2556,7 +2577,7 @@ private void RaiseOnInjectMeshAndMaterialPropertiesEvent(bool resetDiscoveryStat
25562577
if (GameManager.Instance.IsPlayerInsideBuilding)
25572578
playerIsInsideBuilding = true;
25582579

2559-
Vector3 playerAdvancedPos = gameObjectPlayerAdvanced.transform.position;
2580+
Vector3 playerAdvancedPos = ToAutomapPosition(gameObjectPlayerAdvanced.transform.position);
25602581
Material automapMaterial = new Material(Shader.Find("Daggerfall/Automap"));
25612582
automapMaterial.SetColor("_WaterColor", GameManager.Instance.PlayerEnterExit.UnderwaterFog.waterMapColor);
25622583

0 commit comments

Comments
 (0)