SetPositionAndRotation without resetting the vertical view direction?

Pat

New member
Hi,

I'm trying to implement seamless portals. For that, I'm using SetPositionAndRotation(newPosition, newRotation, true, false), so snapAnimator is set to true in case this makes a difference.

Teleporting works fine for the position part and the rotation, apart from the vertical view direction (the x value of the rotation, I noticed this on the camera) - it is always reset to 0. I'm not sure what exactly is causing this. Is there a way to keep the original x-value when using SetPositionAndRotation?

Thanks,
Best regards,
Pat
 
As long as you're passing in the character's current rotation, I don't see why the x value would get reset. How/where are you calling SetPositionAndRotation? Is it during FixedUpdate?
 
  • Like
Reactions: Pat
I'm calling it during OnTriggerEnter.

In an attempt to understand what is going on, I've also tried SetPositionAndRotation in Update, FixedUpdate and LateUpdate, but it doesn't change the outcome. It also reproduces in a freshly created project with only UFPS v2.2.5 imported, Unity v2019.4.13f1. I did it using the demo scene, attaching this script (in this case with FixedUpdate) to a new gameobject and assigning Nolan:

using Opsive.UltimateCharacterController.Character;
using UnityEngine;

public class RotateCharacter : MonoBehaviour
{
public bool RotateRight;
public UltimateCharacterLocomotion characterLocomotion;

void FixedUpdate()
{
if (RotateRight)
{
characterLocomotion.SetPositionAndRotation(characterLocomotion.transform.position, characterLocomotion.transform.rotation * Quaternion.Euler(0, 90, 0));
RotateRight = false;
}
}
}

When entering play mode, looking up or down and toggling the boolean will make the character rotate by 90 degrees and lose the vertical view rotation.
Does that reproduce for you too?
 
The camera will automatically reset when the character is teleported to a new position. I will add this to my todo list to allow the camera not to snap. For now you can edit the CameraController code to not snap into place when the ImmediateTransformChange event is sent.
 
  • Like
Reactions: Pat
Thanks Justin, I got it to work with your approach. Though I recognized that snapAnimator=true is not what I want, as this resets the animation (sorry, that one's on me - not my brightest moment when thinking about *seamless* transitions).

Unfortunately, without snapAnimator=true, SetPositionAndRotation won't apply the rotational change. I've modified the script above like this to reproduce it also in the demo scene of a fresh project (UFPS v2.2.5 and Unity v2019.4.13f1):

using Opsive.UltimateCharacterController.Character;
using UnityEngine;

public class RotateCharacter : MonoBehaviour
{
public bool RotateRight;
public UltimateCharacterLocomotion characterLocomotion;

void Update()
{
if (RotateRight)
{
characterLocomotion.SetPositionAndRotation(characterLocomotion.transform.position, Quaternion.Euler(0, 90, 0) * characterLocomotion.transform.rotation, false, false);
RotateRight = false;
}
}
}

The SetPositionAndRotation-call does things just fine, until the OnCharacterImmediateTransformChange event is executed. Somewhere further down the rabbit hole, the method Rotate of FirstPerson.cs is called, which doesn't seem to take the changed rotation of the character into account. While debugging, I noticed that the value of m_CharacterTransform.rotation has the expected value, but the return-statement at the end uses m_CharacterRotation (which is in Euler angles left unset at (0,0,0)) and returns the rotation the character had before calling SetPositionAndRotation... Unfortunately, my Quaternion-Fu is too weak to wrap my head around it and solve it.

Does that reproduce for you? Am I maybe going at it the wrong way?
 
That makes sense. Right now the camera controller will always reset the rotation. I'm not able to right now but I have this on my list to add as a flag that you can set (or maybe will just not automatically rotate the camera when snapAnimator is true?)
 
Thanks Justin. I also noticed that SetRotation has the same issue (supposedly because it uses the same functionality internally).

Is there any way I can work around that for now and rotate my character via code without having the animation being reset?
 
Right now it'll take some modification within the camera controller code. I haven't done it yet so I don't have a step by step guide, but CameraController.PositionImmediately gets called and it's here that you'll need to start modifying.
 
I found a way that is working for the time being. I have implemented a new view type which ignores resets, change to that before teleporting, disable the animator monitor (so that it doesn't act on the event), call SetPositionAndRotation with snapAnimator=true and finally change the view type back and enable the animator monitor again.

Thanks again. Solved for me.
 
Top