Forum rules - please read before posting.

First person player in a variable gravity vector environment

I've seen variations of this question posted in a few forums but nothing that seems to address my specific challenge. I have done extensive searching and research and tried many things, but nothing seems to get me to exactly where I need to be. I'm starting to wonder if an assumption in AC is preventing this from working so I thought I would reach out. Any help would be greatly appreciated!

So I have a room that is actually the inside of a dodecahedron (12 sided object) where each face represents a different "room" of the structure. For example, one face may be the kitchen and another face may be the lounge. At the start of the scene everything is normal where gravity is the usual (0,-9.81,0) and the face on which the player is standing is perpendicular to that so all good. What I want is for the player to be able to click on another face and say "Go to room" where gravity will be readjusted to be perpendicular to that face and the player will be moved to a marker on there that is at the correct angle, direction, rotation, etc, and the player should then be rotated to match that marker. Once the transition is complete, from the players point of view (ie the camera), it should appear as though they are standing on a flat surface that is at the bottom of the whole structure, just like it appeared at the start of the game. Basically, at that point their "up" is pointing from the side on which they are standing to the opposite side even though in reality, they are standing at an angle that is different to when they started.

I've tried many variations of setting up, setting forward, changing rotation, using AC functions like movetopoint, etc to no avail. I've already spent a long time on it so before I continue to dive down the rabbit hole of my math to make sure I haven't miscalculated somewhere (which I've already done a couple of times) I thought I would make sure this actually CAN work in the first place, ie, that there is nothing obvious that would prevent it from working even if my math was correct.

I've also tried the alternative approach of rotating the entire room instead of changing gravity but this isn't suitable for my purposes as I also want the player to be able to open a "window" to admit sunlight from outside (including any indirect light generated) and in order to do that well I need to bake lighting into the textures for which I need to mark the geometry as static.

I suppose another approach I could take is to have separate scenes for when each face is on the "ground" and transition between them, but I would prefer to avoid that if I can and I also don't know how I would create a smooth transition between the scenes where the player gradually and smoothly moves and rotates towards the target point.

Any help appreciated!

Also a side question, I also notice that the AC movetopoint API function has nowhere near as many options as the actionlist editor call provides (eg, ignore gravity, copy marker angle, wait until finish, etc). Is that intentional or are they actually two different things?

Thanks all.

Comments

  • Welcome to the community, @vincent_a_nativo.

    Ahem, I'll start with the easy one first:

    I also notice that the AC movetopoint API function has nowhere near as many options as the actionlist editor call provides (eg, ignore gravity, copy marker angle, wait until finish, etc). Is that intentional or are they actually two different things?

    These are different things. The Character: Move to point Action actualls uses the MoveAlongPoints function so that it has more control over things like the Path's own gravity setting, etc. The ability to wait until finish is a feature of the Action system, whereby it merely waits until the character is no longer pathfinding. At this point, it's then able to run a separate call to SetLookDirection to copy the Marker angle.

    This Action, as with all, can be duplicated, modified, and inserted as a custom Action if necessary. This particular Action is in the ActionCharPathFind.cs script.

    So I have a room that is actually the inside of a dodecahedron (12 sided object) where each face represents a different "room" of the structure.

    This is a tricky one. Until you mentioned you'd tried this already, my first suggestion was going to be to look into rotating the room as a whole. If the main roadblock here is about baked lighting, I wonder if this may be possible with further investigation. Perhaps unmarking the geometry as static, after baking the lighting (no automated baking) is one avenue to explore.

    You mention that this is a first-person game. What is the regular method of navigation? Directly controlling the Player, or solely relying on Pathfinding / pre-generated Paths?

    AC's first-person mode does assume that "up is up", and I'd recommend use of a custom motion controller if you're looking to navigate an environment in 360 degrees. IIRC, KCC does this very well and AC has an integration for it here.

    For navigation between the different rooms, you could rely on pre-set Paths for the transitions. For example, a simple two-point Path that starts at the dividing edge, and then in the centre of the next room.

    AC's pathfinding algorithm's do make the assumption that "up is up" - as does Unity's, which you can see when baking NavMeshes in the Navigation window. However, the "Mesh Collider" pathfinding algorithm does seem like it'd be the best starting-off point, as the "up" direction is chiefly guided by the "new Vector3" instances in the script (NavigationEngine_meshCollider). It's possible to duplicate this and rely on a modified copy - is this more along the lines of what you're after?

  • Thanks for the welcome Chris! Also thanks for the incredibly prompt reply.

    As for your suggestion of baking and then changing an object back to non-static afterwards, I tried that but I'm not sure how I can verify whether or not the light I'm seeing is coming from the pre-baked texture OR the real time lights. Anyway, I know this is more of a Unity pure question rather than AC so we don't have to delve into that too deeply, I'm happy to approach other groups. The only reason I mentioned it was that the general consensus in the community is that you don't make room geometry dynamic, mainly due to lighting and performance considerations, at least that's how I've interpreted it. You also don't get access to all lighting functions in real time, eg, area lights or emissions lighting other objects.

    To answer your question, the player can move about freely on the face on which they are standing (which currently, is only the one they start on) with the arrow keys. I haven't created any navmeshes yet as I haven't needed to use any path finding. That's not to say I won't, just haven't got to that point yet.

    The Kinematic controller looks interesting, I think I will investigate that integration further as that seems like the most promising path for me, a lot of the feature descriptions in the assets store seem to apply to my situation. Thanks for the recommendation! Do you have any thoughts about more deeply / tightly integrating it into AC as an alternative controller to the default Unity /AC one? Or even extend the AC one to include Kinematic options? Just a thought. I know strictly speaking AC is about creating adventure games and considerations like 360 character movement seem to belong more to the realm of other genres that are more action oriented. But I also think that the lines between genres are getting more blurred every year as people try to create new genres or fusion genres in an effort to stand out / disrupt. I'm using AC because at it's heart I want my game to be driven by a strong narrative and include complex conversation / dialog as well as interactions, all of which AC handle amazingly.

    Thanks again.

  • I've tried out a lot of the motion controllers out there - and attempted my fair share from scratch - and KCC is my personal preference.

    AC's built-in controller will serve the needs of most games that stick to more traditional adventure styles, but motion controllers are a beast unto themselves. For full control over things like changes in gravity direction, moving platforms etc, relying on a dedicated asset is always going to be the best way to go.

    What AC does try to provide, in this case, is to allow integration with third-party controllers. However, given that each controller is different, there's no "one size fits all" approach. This is doubly true given that the needs of each game, in the way that the two are integrated, are different

    The integration script on the wiki should be enough for a basic link between the two, but modifications/tweaks may be necessary to suit your exact needs. The general principles involved are covered in the Manual's "Custom motion controllers" chapter, as well as this tutorial.

    Regarding the pathfinding: I've looked into the "Mesh Collider" algorithm and will see about allowing the user to set the "up" vector - even if only by duplicating/modifying the class.

  • @ChrisIceBox , thank you for all the info. This should be enough to keep me going and find a way out.....a bit like playing an adventure game, trying to build one. And not always as much fun, but close! :)

    For the mesh collider change you are considering, could you explain this a little more to me? So once you make that change what's the general outline of what I would need to do to set up a transition from the starting face which is perpendicular to default up, to another face which isn't. Based on what you've said I would assume I need to set up a two point path dynamically between where the player is currently standing and a point on the destination face (I could use markers for this). Then presumably disable gravity, move along the path, adjust the up vector of the mesh collider and then re-enable gravity on the new vector. Alternatively I could make the player ignore gravity too I suppose until it's been changed to the new vector.

    Did I mention I'd be happy to help you test this out if you end up doing it? :)

  • For the mesh collider change you are considering, could you explain this a little more to me?

    By Mesh Collider, I'm referring to the Mesh Collider method of pathfinding - see the Manual's "Mesh collider pathfinding" chapter for more on how this is typically used. This method is used by the 3D Demo, and the main advantage of this over Unity Navigation is that you can easily swap in/out different NavMeshes at runtime.

    The code for this is all in the NavigationEngine_meshCollider script. Currently, it assumes a regular gravity direction - meaning a NavMesh turned on its side won't work. The change I'm looking into is to have the "up direction" determined by a single vector variable. I'm still thinking about how this might be user-configurable.

    The principle would be that each room would have its own NavMesh - and each with it's own "up direction" value. Rather than one big NavMesh, you'd switch NavMesh depending on which scene you're in.

    For movement between rooms, and hence between different NavMeshes, you would have to rely on a pre-built Path. Though since the Player can be made to move to the Paths' first node, the first node could be at the border, with the second in e.g. the centre of the next room.

    Do note that the player's motion, and path calculation, are two separate things. What I'm talking about here is just the raw collection of nav points. While you'll still need to have a custom motion controller to handle movement in non-upwards gravity, you'll also need to force the Player's own pathfinding to allow for vertical movement. This is best done by hooking into the OnCharacterSetPath custom event:

    void OnEnable ()
    {
        EventManager.OnCharacterSetPath += My_OnCharacterSetPath;
    }
    
    void OnDisable ()
    {
        EventManager.OnCharacterSetPath -= My_OnCharacterSetPath;
    }
    
    void My_OnCharacterSetPath (AC.Char character, Paths path)
    {
        if (character.IsPlayer)
        {
            path.affectY = true;
        }
    }
    
  • Thanks @ChrisIceBox ! All very helpful and detailed info. I'll keep plugging away!

  • I decided to try out KCC along with the integration. I have to say it's been extremely frustrating and I haven't managed to get it working well and since I've already put far too many hours into it I'm humbly asking for some more guidance.

    I've tried both using the Example Character prefabs as well as creating everything from scratch. Yes I've followed the KCC walkthrough guide and have learned a lot about the KCC scripts along the way which is good, but it hasn't gotten me where I want to go. And yes, I do realise that if you follow the walkthrough you end up with scripts that have different names to the Example Character so you need to change the type declarations in the KCCIntegration script for the public parameters.

    Where I'm unclear is exactly how the object hierarchy should end up looking once the integration is fully in place and functioning correctly. I've tried so many permutations and combinations now of what object is a child of what and which objects have which components and which object is the AC player but nothing has ended up working or free of AC errors like "First person camera not found on player" for example (In the KCC guide it ends up being a child of the character object). The KCC guide prescribes a character object that contains the motor and a separate player object, and what's confusing me is how this separate player object fits into the whole integration picture with AC.

    So, what would be your expectation of how the object hierarchy looks in the end and also, which components (both AC and KCC) are on which objects?

  • What exactly is the issue at this point? Does your KCC character work in a non-AC scene prior to adding any AC scripts?

    There should be 4 key components to deal with: KCC Controller and Motor scripts, and AC's Player and KCC Integration scripts. In my experience, these should all be on the root object.

    A first-person KCC character would have it's own first-person camera set up - you shouldn't have to assign AC's First Person Camera component, and warnings about this can be ignored.

    Any other components or objects that aren't auto-generated should typically be non-essential.

    It is possible that KCC's API and/or workflow has changed since the integration was written. I shall go through it again and see if there are any new issues.

  • I can't see any changes made since that would cause issue. Do note, though, that the AC Player component's "Motion control" must be set to "Manual" to allow KCC to override it.

    KCC and AC can be set up quickly with KCC's provided sample character:

    1. Drop KCC's ExampleCharacter prefab into the scene. Both the Example Character Controller and Kinematic Character Motor components should be on the root
    2. Attach AC's Player component, and the KCC Integration script, to the root
    3. Configure the KCC Integration script's Inspector by assigning both the Character AC and Kinematic Controller fields
    4. Set the Player component's Motion control field to Manual. For animation to play, you'll need to set the Animation engine to Mecanim and configure the parameter fields, but for pure motion this is not necessary
    5. This should work now for Direct movement, but for First-Person movement you'll have to take extra steps to attach a camera that allows for free-aiming. This'd be a case of following the steps in KCC - you'll want to get this working by itself before incorporating AC.

    If necessary, you may have to rely on a custom GameCamera or disable AC's MainCamera - see the Manual's "Custom cameras" and "Disabling the MainCamera" chapters for more on this topic.

  • I did test one of KCC's sample scenes sans AC that uses the ExampleCamera prefab and I was able to make it first person by setting the default camera distance to zero in the KCC settings and this gets the result I want.

    So I'm getting close! I followed the steps you suggested and then to add first person I used the ExampleCamera prefab from KCC and put it under my character object. As per the AC manual I added the Basic Camera script to it. I then added a camera switch to the first person camera in the opening cut scene action list. This "works" except for the fact that the camera movement with the mouse cursor is jerky, not smooth at all. I suspect this is probably due to the KCC example scripts not using a rotation approach that is perfectly smooth so I'm going to see if I can refine that a little.

    The other thing I noticed is that the rotation of the character didn't match the playerstart markers rotation on launch, even thought the position was correct. Perhaps this is due to the forward vector of the character not being what I think it is. I'll investigate that.

    Lastly, I take it that since the AC Player script is on the Character root object then I should create a prefab out of it and drag that onto the Player field in the AC settings? That's what I've done anyway.

    Thanks!

  • As per the AC manual I added the Basic Camera script to it. I then added a camera switch to the first person camera in the opening cut scene action list.

    Are you looking to use any other cameras to e.g. cutaway during cutscenes or interactions? If not, you could consider disabling the MainCamera, or directly parenting it to the Player - but I'd only advise that if that's the only way to get smooth camera motion.

    The other thing I noticed is that the rotation of the character didn't match the playerstart markers rotation on launch, even thought the position was correct.

    The KCC Integration script's OnTeleport function is triggered at this time - which then reads the AC Player's GetTargetRotation() function to determine the rotation. The latter function should be correct, but perhaps your character needs to make use of it differently.

    Lastly, I take it that since the AC Player script is on the Character root object then I should create a prefab out of it and drag that onto the Player field in the AC settings?

    This is typically more for convenience than anything, as AC will then be able to spawn the Player in at runtime whenever a scene loads without one.

    This is entirely optional, however, and may not always be the best approach - e.g. if you need the Player to refer to other components/objects in the scene, which is possible when using custom scripts/motion controllers.

    If a Player is present in a scene, it will override the "default" one assigned in the Settings Manager. You can use local Players for all scenes, if necessary.

  • I've solved every other issue I had except for the orientation of the character when changing the gravity vector. When I change gravity I can move around OK on the surface that is perpendicular to it, but the character is still oriented towards world up. When trying the same thing in a sample KCC scene (sans AC), it works as expected in that the player's up has changed to be the opposite of gravity and from the players point of view, it looks like you are standing on normal ground.

    I went back and applied things step by step in my AC scene and all works fine UNTIL you attach the AC Player script to the KCC character object. At that point, the rotations that are automatically applied by the KCC script as part of normal Updates no longer remain in place and revert back to world up. I remember you saying that this is assumed in AC so that's no surprise really, but it makes me think that there is actually no way to marry KCC to AC in a single object as far as arbitrary gravity goes as things stand. The integration seems to work well for all other scenarios, but not this one.

    So I am now thinking that perhaps I should maintain separate objects, one for the KCC character and one for AC that wouldn't be visible. The KCC one is the one the player would be controlling (and it would also have to be the one I use to do cutscene or automatic movement). The AC player object would be there to handle everything else like dialog, inventory, interactions, etc and it could move with the KCC object, just not rotate which wouldn't matter.

  • Be aware that dialogue, inventory and interactions can all work without a Player - there just won't be a hard coded "physical reaction" in the form of moving to a Hotspot / on-screen presence etc.

    It's true that AC does have a fixed gravity direction - and this'll be reflected in e.g. its GetTargetRotation function that the KCC Integration script relies on.

    When the Player component's Motion control is set to Manual, it should be the case that AC doesn't manipulate the transform at all - so it may just be a case that the KCC Integration component needs to be amended to account for the change in gravity.

    What is the effect of keeping the Player component, but removing KCC Integration?

  • Happy to report that I just got it all working exactly the way I wanted, thanks in large part to your help @ChrisIceBox. As I mentioned above I am maintaining two separate player objects, one for AC and one for KCC. I also created a script on the KCC object that will re-position the AC player in it's Update to always match it's own position. This is working at the moment.

    Thanks for making me aware of the fact I don't actually have to have a player. Given that I have to handle all the movement myself anyway (at least, via KCC) then it's probably OK that I don't get the "physical reaction" stuff, but I might just keep it around for now just in case I need it for something. I can always drop it later.

    To answer your question the behaviour I described was before I had added the integration script so I don't think that was the problem. Previously I had also tried all sorts of changes in the integration script like manual rotations of the KCC character, AC character, KCC camera, one of more of the above, all of the above. What I was noticing was that no matter what I did in the integration script the player would still be stubbornly pointing towards to world up even though it was accurately moving along the new gravity vector and I could find no way to rectify it. I am a relative beginner however so it could just be that I didn't know what to attempt. However, I'm OK with how I have things at the moment.

    I am happy write up a summary of how I have things now if you want it but I suspect that you could probably find an alternative, more integrated solution than what I have.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.