How would you implement an auto-walk function?
- Hazelnut
- Posts: 3016
- Joined: Sat Aug 26, 2017 2:46 pm
- Contact:
Re: How would you implement an auto-walk function?
Yeah I agree. I did have some daydreams about making a travel mod myself involving carriages where you would see the journey in real time with variable time acceleration buttons but felt that was probably not going to work until roads have been modded in, and that's not a trivial task.
See my mod code for examples of how to change various aspects of DFU: https://github.com/ajrb/dfunity-mods
- Interkarma
- Posts: 7247
- Joined: Sun Mar 22, 2015 1:51 am
Re: How would you implement an auto-walk function?
It seems you've resolved your issues. In any case, here's some more detail I put together for you. You can work out target location rect from anywhere without needing to wait for location to load first. May be helpful later on.
In any case, happy to hear you're making progress. I'll bow out of this one now.
Code: Select all
// Get player's current horizontal position in exterior world
PlayerGPS playerGPS = GameManager.Instance.PlayerGPS;
int worldX = playerGPS.WorldX;
int worldZ = playerGPS.WorldZ;
// Safely get target location detail by name (can also use index overload)
DFLocation targetLocation;
if (!DaggerfallUnity.Instance.ContentReader.GetLocation("Daggerfall", "Gothway Garden", out targetLocation))
return;
// Get the longitude/latitude of location
int longitude = targetLocation.MapTableData.Longitude;
int latitude = targetLocation.MapTableData.Latitude;
// Convert longitude/latitude into map pixel position
DFPosition mapPixel = MapsFile.LongitudeLatitudeToMapPixel(longitude, latitude);
// Convert map pixel into world coordinates (SW corner of map pixel in world space)
DFPosition worldCoord = MapsFile.MapPixelToWorldCoord(mapPixel.X, mapPixel.Y);
// Following is a helper to get actual location rect in world space directly from DFLocation data
// I've added this to the code now as DaggerfallLocation.GetLocationRect()
/// <summary>
/// Helper to get location rect in world coordinates.
/// </summary>
/// <param name="location">Target location.</param>
/// <returns>Location rect in world space. xMin,yMin is SW corner. xMax,yMax is NE corner.</returns>
public static Rect GetLocationRect(DFLocation location)
{
// This finds the absolute SW origin of map pixel in world coords
DFPosition mapPixel = MapsFile.LongitudeLatitudeToMapPixel(location.MapTableData.Longitude, location.MapTableData.Latitude);
DFPosition worldOrigin = MapsFile.MapPixelToWorldCoord(mapPixel.X, mapPixel.Y);
// Find tile offset point using same logic as terrain helper
DFPosition tileOrigin = TerrainHelper.GetLocationTerrainTileOrigin(location);
// Adjust world origin by tileorigin*2 in world units
worldOrigin.X += (tileOrigin.X * 2) * MapsFile.WorldMapTileDim;
worldOrigin.Y += (tileOrigin.Y * 2) * MapsFile.WorldMapTileDim;
// Get width and height of location in world units
int width = location.Exterior.ExteriorData.Width * MapsFile.WorldMapRMBDim;
int height = location.Exterior.ExteriorData.Height * MapsFile.WorldMapRMBDim;
// Create location rect in world coordinates
Rect locationRect = new Rect() {
xMin = worldOrigin.X,
xMax = worldOrigin.X + width,
yMin = worldOrigin.Y,
yMax = worldOrigin.Y + height,
};
return locationRect;
}
WorldX and WorldZ coordinates are the player's absolute position in world space. With the above code, you can compare player's absolute coordinates vs. the absolute coordinates of any location in the world. I use this extensively in the quest system to determine if player is in correct city, within a location area, etc.
In any case, happy to hear you're making progress. I'll bow out of this one now.
-
- Posts: 201
- Joined: Sat Sep 15, 2018 9:49 am
Re: How would you implement an auto-walk function?
Great, thanks a lot everybody, especially Interkarma!
Yeah, I'm not going to bother with roads... Just point as the crow flies. Might have some weird results in mountainous regions, but I'm not going for perfection here. The main point will be to see how long it actually *takes*.felt that was probably not going to work until roads have been modded in, and that's not a trivial task.
- Jay_H
- Posts: 4072
- Joined: Tue Aug 25, 2015 1:54 am
- Contact:
Re: How would you implement an auto-walk function?
Something to consider is to grant the PC no-clip status. Every once in a while there'll be a town with a building, like those in L-shape, that'll trap him or her and make the journey endless. It'll be rare, but something sufficiently important to think about, I believe.
-
- Posts: 201
- Joined: Sat Sep 15, 2018 9:49 am
Re: How would you implement an auto-walk function?
Not actually as rare as you think... happens all the time, in fact. Good forward-thinking skills there! I haven't taken care of it yet because it's not quite the priority at this point, so I haven't looked into how to do that yet. Do I have to get the players collider and turn it off, or is there something in the daggerfallworkshop API to facilitate this?It'll be rare, but something sufficiently important to think about, I believe.
-
- Posts: 201
- Joined: Sat Sep 15, 2018 9:49 am
Re: How would you implement an auto-walk function?
Hummmm, turning off that collision detection is turning out to be a problem. I fully anticipated that I'd have toe look a bit for how to set it, but I'm running out of ideas.
The PlayerController conveniently provides a property "detectCollisions". Most inconveniently, this property does not have any effect.
So I noticed the PlayerCollision script, dug that out of the component tree and disabled it. That too has no effect.
Finally I dug out the player objects very own collider and disabled that, only to realise that now the player couldn't move at all. The reason for this is pretty simple once I took a closer look: The PlayerController I tried first *is* the colider (it inherits it), so effectively I was having the same object on hand as before, and since there's no player model or anything, that collider really is the physical representation of the player in the game world. If it's disabled it can't move, hence the player can't move. That's the way it looks to me right now anyways.
It also seems to be a time-honored unity hack to turn colliders into triggers for this purpose, but if I try to do that the CharacterController explicitly slaps me with an exception.
From where I stand right now, I don't think disabling collision detection for the player is possible unless specifically supported by the API. Have I missed something here?
The PlayerController conveniently provides a property "detectCollisions". Most inconveniently, this property does not have any effect.
So I noticed the PlayerCollision script, dug that out of the component tree and disabled it. That too has no effect.
Finally I dug out the player objects very own collider and disabled that, only to realise that now the player couldn't move at all. The reason for this is pretty simple once I took a closer look: The PlayerController I tried first *is* the colider (it inherits it), so effectively I was having the same object on hand as before, and since there's no player model or anything, that collider really is the physical representation of the player in the game world. If it's disabled it can't move, hence the player can't move. That's the way it looks to me right now anyways.
It also seems to be a time-honored unity hack to turn colliders into triggers for this purpose, but if I try to do that the CharacterController explicitly slaps me with an exception.
From where I stand right now, I don't think disabling collision detection for the player is possible unless specifically supported by the API. Have I missed something here?
- Interkarma
- Posts: 7247
- Joined: Sun Mar 22, 2015 1:51 am
Re: How would you implement an auto-walk function?
Yep, the CharacterController is responsible for both movement and collisions. But even if you could just switch off collisions, you probably don't want to do this anyway as player would just fall through terrain. There's at least two other ways you could approach this.
First approach is add steering behaviour to make player route around location areas. Wouldn't need true pathfinding or anything like that, just basic obstacle avoidance. If you really wanted to go nuts with it, you could route player towards nearby taverns automatically once a day, and allow player to start/stop journey as they wish. Then they could do a little RP in town before resuming their journey.
Second approach if you just want to ghost through towns in a straight line for now is disable CharacterController and move player object manually via its transform.position. You can keep them aligned above terrain using a raycast down from current position. Set controller active again when player ends cruise control. Will probably want to toggle a couple of other movement-related components as well to avoid any weird side-effects of controller being disabled.
It will be interesting to see where you go with this once the early problems are solved.
First approach is add steering behaviour to make player route around location areas. Wouldn't need true pathfinding or anything like that, just basic obstacle avoidance. If you really wanted to go nuts with it, you could route player towards nearby taverns automatically once a day, and allow player to start/stop journey as they wish. Then they could do a little RP in town before resuming their journey.
Second approach if you just want to ghost through towns in a straight line for now is disable CharacterController and move player object manually via its transform.position. You can keep them aligned above terrain using a raycast down from current position. Set controller active again when player ends cruise control. Will probably want to toggle a couple of other movement-related components as well to avoid any weird side-effects of controller being disabled.
It will be interesting to see where you go with this once the early problems are solved.
-
- Posts: 201
- Joined: Sat Sep 15, 2018 9:49 am
Re: How would you implement an auto-walk function?
Yeah, I was afraid this might be the case.But even if you could just switch off collisions, you probably don't want to do this anyway as player would just fall through terrain.
Code: Select all
First approach is add steering behaviour to make player route around location areas.
Code: Select all
If you really wanted to go nuts with it, you could route player towards nearby taverns automatically once a day
That part is working already, as is interruption by enemies. There's quite a few of the later, I wonder if I'll need to tweak spawn rates a bit. I guess I'll decide based on the feedback from a first release.allow player to start/stop journey as they wish.
I'd also have loved to put in a bit of an RPG mechanic, with a skillcheck when entering a new tile that sets the player off-course when he fails, but alas daggerfall has absolutely no nature related skills at all...