- Home /
Mecanim character wobbles when changing camera relative direction.
Hi guys,
I have a game character who is animated using Mecanim, with Speed and Direction floats as per this YouTube tutorial: http://www.youtube.com/watch?v=Xx21y9eJq1U
I've implemented camera relative controls using some help from the code that was posted as a partial answer at the following link:
http://answers.unity3d.com/questions/390879/how-do-i-move-a-mecanim-driven-character-relative.html
My implementation is designed to work with the FingerGestures plugin, and it looks like this:
using UnityEngine;
using System.Collections.Generic;
[RequireComponent( typeof( TapGesture ) )]
[RequireComponent( typeof( SwipeGesture ) )]
public class PlayerCharacterControlScript : TouchControlScript {
...
public float directionDampTime = 0.25f;
...
void OnMovementDrag( DragGesture gesture )
{
if (gesture.StartPosition.x < ScreenMidpoint.x)
{
// TODO: Make this into camera-relative movement.
// dont apply drag rotation if more than one touch is on the screen
//if( FingerGestures.Touches.Count > 1 )
// return;
// wait for drag cooldown timer to wear off
// used to avoid dragging right after a pinch or pan, when lifting off one finger but the other one is still on screen
if( Time.time < nextDragTime )
return;
// Turn the player whith horizontal swipes, get horizontal swipe length.
float h = ( (gesture.Position.x - gesture.StartPosition.x) * yawSensitivity * turningFactor / ScreenWidth );
// Prevent the swipe input value from exceeding the input limits.
if (h > 1)
h = 1;
if (h < -1)
h = -1;
// Move player whith vertical swipes, get vertical swipe length.
float v = ( (gesture.Position.y - gesture.StartPosition.y) * pitchSensitivity * turningFactor / ScreenHeight );
// Prevent the swipe input value from exceeding the input limits.
if (v > 1)
v = 1;
if (v < -1)
v = -1;
OrientPlayer(h, v);
if( gesture.Phase == ContinuousGesturePhase.Ended)
{
StopPlayer();
}
}
}
...
public void OrientPlayer(float h, float v)
{
// Camera orientation data
Vector3 forwardAvatar = new Vector3(thisTransform.forward.x, 0.0f, thisTransform.forward.z).normalized;
Vector3 forward = MainCamera.transform.TransformDirection(Vector3.forward);
forward.y = 0f;
forward = forward.normalized;
Vector3 right = new Vector3(forward.z, 0.0f, -forward.x);
// Data for orienting player relative to camera
Vector3 direction = ((h * right) + (v * forward)).normalized;
float deltaAngle = Vector3.Angle(direction, forwardAvatar);
float dot = Vector3.Dot(forwardAvatar, Vector3.Cross(direction, Vector3.up));
// Set the direction based on the swipe input value
// New camera relative movement
animator.SetFloat("Speed", (h * h) + (v * v), directionDampTime, Time.deltaTime);
float headingOffset = deltaAngle * Mathf.Sign(dot);
animator.SetFloat("Direction", headingOffset, directionDampTime, Time.deltaTime);
// Reset player turning at end of gesture
if (debugMode)
{
Debug.Log("Player Movement Direction Float:" + animator.GetFloat("Direction"));
Debug.Log("Player Movement Speed Float:" + animator.GetFloat("Speed"));
}
}
void StopPlayer()
{
if (debugMode)
Debug.Log("Stopping Player");
animator.SetFloat("Speed", 0.0f);
animator.SetFloat("Direction", 0.0f); // Prevent turning on start
// Clear target when stopped
target = null;
}
...
}
My character turns as expected, but he jerks back and forth for half a second or so when turning to a new direction. The wobbling occurs only when the character faces the desired direction, and subsides within a secon. Does anyone have any ideas for smoothing out the motion?
MachCUBED