Location Transform.Position.Y Issue

Discuss modding questions and implementation details.
Post Reply
l3lessed
Posts: 1399
Joined: Mon Aug 12, 2019 4:32 pm
Contact:

Location Transform.Position.Y Issue

Post by l3lessed »

So, I'm working on my minimap mod, and I came across an interesting issue with grabbing the GameManager.Instance.StreamingWorld.CurrentPlayerLocationObject.transform.position.y property.

The issue is, if I leave a dungeon and I fast travel to a new location block, the GameManager.Instance.StreamingWorld.CurrentPlayerLocationObject.transform.position.y property will read out positive even when the location is a negative value.

The odd thing is if I walk into a new location block, and then start fast traveling to other blocks, the property reflects the correct value and doesn't turn into a positive value when the location block in the editor shows it as a negative y value.

I thought maybe fast travel would cause this, but again, it works fine if I walk into and load a new location block.

Any idea what is happening here?
My Daggerfall Mod Github: l3lessed DFU Mod Github

My Beth Mods: l3lessed Nexus Page

Daggerfall Unity mods: Combat Overhaul Mod

Enjoy the free work I'm doing? Consider lending your support.

User avatar
Interkarma
Posts: 7236
Joined: Sun Mar 22, 2015 1:51 am

Re: Location Transform.Position.Y Issue

Post by Interkarma »

Due to size of world, DFU has a floating origin system that operates in X, Y, Z. As player moves away from origin (0,0,0) the world and everything in it is shifted back towards origin as a negative offset. This keeps all the action close to origin so as not to create precision problems in movement, flickering shadows, etc. The player's transform is only relative to the world from most recent floating origin offset. Different objects might operate in different domains, ultimately all coming together at the same spot in scene space.

Keep in mind that WorldCompensation itself will shift around as player moves through world, teleports, loads saves, fast travels, and so on. You can't really rely on X,Y,Z positions to really mean anything and need to calculate your way through each time you need it. Take a look at CityNavigation.WorldToScenePosition() to see an example of how this is done for mobile NPCs walking around local terrain.

If you're restoring something from serialized data, it gets harder because the current world offset might not be the same as the one serialized. In this case you'll need to get the difference between the serialized offset and the live offset. See SerializableEnemy.RestoreExteriorPositionHandler() for an example of this one.

It's a hard thing to explain well. The best I can suggest is to play around with it and look for other examples in code until you can grok it.

l3lessed
Posts: 1399
Joined: Mon Aug 12, 2019 4:32 pm
Contact:

Re: Location Transform.Position.Y Issue

Post by l3lessed »

Very interesting stuff. Thanks for the info. I was thinking it was probably something to do with how the world setup the origin because I did notice the player always starting at 0,0,0.

If I use the player objects y for height location data instead, it works. I wanted the location block height though because I thought it would probably be less bug prone having a set standard height. The players object height will shift some since blocks themselves have large height differences built into their terrain. However, cities are always flat, so really won't be a huge deal. I can also use the gimmick of pushing the camera and minimap icons way into the sky; being top/down ortho camera this would be fine.
My Daggerfall Mod Github: l3lessed DFU Mod Github

My Beth Mods: l3lessed Nexus Page

Daggerfall Unity mods: Combat Overhaul Mod

Enjoy the free work I'm doing? Consider lending your support.

l3lessed
Posts: 1399
Joined: Mon Aug 12, 2019 4:32 pm
Contact:

Re: Location Transform.Position.Y Issue

Post by l3lessed »

So, I'm having one last issue. Any time I try to fast travel into a cell, it tries to grab the location data before it is loaded, causing a null error crash. I have tried everything to ensure it doesn't grab it before the location object is loaded to stop this null error, but I keep getting it. What am I missing here. I know it's fast travel too, as I can walk into locations without an issue.

Code: Select all

       // Don't update building and location data unless region or location has changed.
                if (GameManager.Instance.PlayerGPS.CurrentLocation.RegionIndex != lastRegionIndex ||
                    GameManager.Instance.PlayerGPS.CurrentLocation.LocationIndex != lastLocationIndex)
                {
                    //update last region/location ids for checking.
                    lastRegionIndex = GameManager.Instance.PlayerGPS.CurrentLocation.RegionIndex;
                    lastLocationIndex = GameManager.Instance.PlayerGPS.CurrentLocation.LocationIndex;
                    //grab players current location.
                    DFLocation location = GameManager.Instance.PlayerGPS.CurrentLocation;
                    //check if location is loaded, if player is in an actual location rect, and if the location has changed by name.
                    if (location.Loaded && GameManager.Instance.PlayerGPS.IsPlayerInLocationRect && currentLocationName != lastLocationName)
                    {
                        //update location name check and ensure player is not inside.
                        lastLocationName = currentLocationName;
                        if (!GameManager.Instance.IsPlayerInside)
                        {
                            minimapControls.updateMinimapUI();
                            SetupBuildingIndicators();
                        }
                    }
                }
My Daggerfall Mod Github: l3lessed DFU Mod Github

My Beth Mods: l3lessed Nexus Page

Daggerfall Unity mods: Combat Overhaul Mod

Enjoy the free work I'm doing? Consider lending your support.

l3lessed
Posts: 1399
Joined: Mon Aug 12, 2019 4:32 pm
Contact:

Re: Location Transform.Position.Y Issue

Post by l3lessed »

I also want to point out, when I grab the raw location object using the streaming world object and the grabbed location's transform positions, it doesn't cause any issues for placing the markers, even without using the

Code: Select all

cityNavigation.WorldToScenePosition(GameManager.Instance.PlayerGPS.CurrentMapPixel)
method.

It is only the y cordinate that is off, and it is not even off. It is merely reversed from positive to negative. The transform values seem spot on outside that making the y height property always positive on fast traveling into the location.
My Daggerfall Mod Github: l3lessed DFU Mod Github

My Beth Mods: l3lessed Nexus Page

Daggerfall Unity mods: Combat Overhaul Mod

Enjoy the free work I'm doing? Consider lending your support.

User avatar
Interkarma
Posts: 7236
Joined: Sun Mar 22, 2015 1:51 am

Re: Location Transform.Position.Y Issue

Post by Interkarma »

I'll move this one to Modder Discussion, as topic is more about mod implementation rather than help playing or setting up DFU.

For your null error, try moving code to a later point in time or handling a different event. It's not clear how/when you're triggering this code from the snip above, but it sounds too early if the game isn't done setting up location yet.

You should always do a null check before accessing something that might return null anyway. If you're waiting on some parallel execution to finish, do the null check in Update and run your setup code from Update only when environment is ready. Raise a flag like isSetup once done to short out the setup check next loop. Lower flag when needed, e.g. if player exits location rect and setup needs to run again.

My apologies is that's not helpful. Hopefully someone else in the mod development space can offer support also.

l3lessed
Posts: 1399
Joined: Mon Aug 12, 2019 4:32 pm
Contact:

Re: Location Transform.Position.Y Issue

Post by l3lessed »

Roger. I was thinking it should of went there. Thanks.
My Daggerfall Mod Github: l3lessed DFU Mod Github

My Beth Mods: l3lessed Nexus Page

Daggerfall Unity mods: Combat Overhaul Mod

Enjoy the free work I'm doing? Consider lending your support.

l3lessed
Posts: 1399
Joined: Mon Aug 12, 2019 4:32 pm
Contact:

Re: Location Transform.Position.Y Issue

Post by l3lessed »

I hear you. I think I'm just missing something to null check and code flow like you say.

As for the transform property, I'm at a loss here. I'm unsure why the block properties come out fine, but the Y is always positive, even when the location object itself is a negative value. Could this also be tied to the terrain creation process? By fast traveling, could I be accidently grabbing the location data before the height data is fully generated and set to its final value? When you fast travel, I know it recreates the terrain again from scratch no matter where you fast travel, which would again explain the odd behavior only when I fast travel.
My Daggerfall Mod Github: l3lessed DFU Mod Github

My Beth Mods: l3lessed Nexus Page

Daggerfall Unity mods: Combat Overhaul Mod

Enjoy the free work I'm doing? Consider lending your support.

User avatar
Interkarma
Posts: 7236
Joined: Sun Mar 22, 2015 1:51 am

Re: Location Transform.Position.Y Issue

Post by Interkarma »

It does sound like things are happening moments too early after the fast travel process. There's a post fast travel process where player is repositioned once target location is ready. Screen is blacked out during this period then fades in again. Maybe you're grabbing player position before the reposition process has completed? The player should always arrive above terrain in world coordinates once everything is done.

I'm not in front of my dev environment for a while, so working from memory here. Check through StreamingWorld for a method called RepositionPlayer. This does the actual work of aligning player to terrain after fast travel. I recall there's a flag here like isPositioningPlayer (or isRepositioningPlayer) that's raised then lowered during this process. Try grabbing player position only when that's done if possible.

l3lessed
Posts: 1399
Joined: Mon Aug 12, 2019 4:32 pm
Contact:

Re: Location Transform.Position.Y Issue

Post by l3lessed »

Got it. Did a null check on the object before running it. I dropped it behind a location change check so it only checks it when the location changes.

Code: Select all

GameManager.Instance.StreamingWorld.GetCurrentCityNavigation().WorldToScenePosition(GameManager.Instance.PlayerGPS.CurrentMapPixel, true) != null
Also, to grab the height, your recommendations worked after a little digging.

Code: Select all

GameManager.Instance.StreamingWorld.GetCurrentCityNavigation().WorldToScenePosition(GameManager.Instance.PlayerGPS.CurrentMapPixel, true)
This grabs the correct vector3 coordinates based on the origin point system. Thanks.
My Daggerfall Mod Github: l3lessed DFU Mod Github

My Beth Mods: l3lessed Nexus Page

Daggerfall Unity mods: Combat Overhaul Mod

Enjoy the free work I'm doing? Consider lending your support.

Post Reply