I’m encountering a strange problem right now involving move() on a CharacterController where it’s not behaving like I would expect, and I’ve isolated the problem down to a single move() call that results in movement even when passed a zero vector, so I’m wondering if I’m misunderstanding how it works or what is going on.
I’ve been implementing a basic cover system in my game, where for now I have the player stand at a certain point in a coverable area and if a certain key is pressed then the player is teleported behind the cover a short distance ahead and teleported back out and to the side of the cover when the key is released. In the final version there will presumably be some sort of animation between these positions but this is what I’ve decided upon for now.
So what’s been happening is, if we take these three X-coord positions representing the different positions involved…
-56.0f : The “enter cover” position the player must stand at to enter the cover (facing left, standing to the right of the cover).
-55.5f : The “in cover” position the player is teleported to.
-55.0f : The “exit cover” position the player should be teleported to after releasing the cover key, resuming normal walking behavior.
What is happening now is that it all seems to be functioning correctly except that right after the player teleports to the correct exit position, they for some reason instantly teleport back to the X-coord of the “in cover” position. I had a few ideas based on how my movement system works as to what might have been happening but everything I was able to check seemed to be working as intended.
However, I experimented by skipping a certain move() call once just after my exitCover() function is called (where the player is set back to walk mode etc.) by setting a boolean, and sure enough the strange behavior is stopped and everything seems to work fine from that point on.
What could be happening here? I’ve been trying to trace what’s going on but I think I’ve hit a brick wall until I understand how CharacterController’s move() function works.
At first I thought the X component of the Vector3 I pass to move() was somehow being set to something other than 0 erroneously and that was why I was seeing the movement, but as an experiment I just passed in Vector3.zero and I still get the same behavior.
How/why would this be happening? Regardless of what might be happening in other parts of the code, surely called CharacterController.move( Vector3.zero ) should never result in the object being moved? Or is that not how it’s meant to work and outside forces can sometimes lead to this causing movement?
Given the X coord is correctly going from -55.5f to -55.0f, THEN suddenly jumping back to -55.5f (and it appears to always jump exactly to the cover position no matter how I change it), it’s almost like it’s reverting back to its previous position from the last frame… as though it was “cached” some way or another. Are there incorrect ways of using move() where calling it can somehow move the character back to where it was? Is this some kind of interpolation/smoothing?
Just had a thought… could there be some kind of conflict between my cover system moving the player by setting “transform.position” and then in the same frame (as move() IIRC would be called later in the same frame as exitCover() which sets the player’s “transform.position”) calling move() even with a zero vector which theoretically should not cause movement?
e.g. The CharacterController’s move() function makes a note of where the player is before exitCover() is called, then exitCover() changes the transform directly, the position is updated and the player is rendered in the correct position, but then in the next frame if move() is called it gets confused because the most recent position it knows about is a complete aberration and it returns to the last valid position it knows about? Maybe it’s for collisions…?
Am I to assume it’s a really bad idea to mix directly setting the position via transform and using move()? Should a CharacterController never have its position altered directly during play or only in certain circumstances?
TL;DR Is the answer probably to stop using “transform.position =” and instead calculate what the difference is between the current position and where I want to move, and apply that to the movement vector? Although, if I actually did want to teleport a character arbitrarily, could that cause collision issues?