- Home /
How do I make my character lean to the sides?
Hey Guys, this is my first time on the forums asking for help as I usually find the answer here for any unity project, so I hope this question isn't too complex.
To begin, I've been working on an FPS controller that has the ability to lean left and right to allow the player to peek using the "Q" and "E" keys similar to alot of horror games. So if you press those buttons, the character's head will tilt to the respective side to peek corners. My method was to modify the MouseLook.cs script in order to get the results I needed.
This code works fine except that it'll only work as expected if I face a direction where the x axis is 0 and the y axis is also 0 or 90. If you try to use the peek feature on an axis that are not those the camera will keep rotating endlessly and until i pause the scene. It would help alot to have a code sample with the code fix.
Thanks anyways for reading! Hope I can get some answer soon.
using System; using UnityEngine; using UnityStandardAssets.CrossPlatformInput;
namespace UnityStandardAssets.Characters.FirstPerson
{
public class MouseLook : MonoBehaviour
{
public float XSensitivity = 3f;
public float YSensitivity = 3f;
public bool clampVerticalRotation = true;
public float MinimumX = -90F;
public float MaximumX = 90F;
public bool smooth;
public float smoothTime = 14f;
private bool freezeX;
private bool freezeY;
private Quaternion m_CharacterTargetRot;
private Quaternion m_CameraTargetRot;
float yRot;
float xRot;
float zRot = 0f;
bool isInMiddle = true;
bool isLeaning = false;
//Misc
bool deleteActivator = false;
public void Init(Transform character, Transform camera)
{
m_CharacterTargetRot = character.localRotation;
m_CameraTargetRot = camera.localRotation;
}
public void LookRotation(Transform character, Transform camera)
{
yRot = CrossPlatformInputManager.GetAxis("Mouse X") * XSensitivity;
xRot = CrossPlatformInputManager.GetAxis("Mouse Y") * YSensitivity;
m_CharacterTargetRot.z = Mathf.Clamp(m_CharacterTargetRot.z, -0.25f, 0.25f);
m_CharacterTargetRot *= Quaternion.Euler(0f, yRot, zRot);
m_CameraTargetRot *= Quaternion.Euler(-xRot, 0f, 0f);
if (clampVerticalRotation)
m_CameraTargetRot = ClampRotationAroundXAxis(m_CameraTargetRot);
if (smooth)
{
character.localRotation = Quaternion.Slerp(character.localRotation, m_CharacterTargetRot,
smoothTime * Time.deltaTime);
camera.localRotation = Quaternion.Slerp(camera.localRotation, m_CameraTargetRot,
smoothTime * Time.deltaTime);
}
else
{
character.localRotation = m_CharacterTargetRot;
camera.localRotation = m_CameraTargetRot;
}
if (m_CharacterTargetRot.z >= 0.25f)
zRot = 0;
else if (m_CharacterTargetRot.z <= -0.25f)
zRot = 0;
if (m_CharacterTargetRot.z >= 0.005f || m_CharacterTargetRot.z <= -0.0051f)
{
yRot = 0;
isInMiddle = false;
deleteActivator = true;
}
else
isInMiddle = true;
if (m_CharacterTargetRot.z <= 0.25f || m_CharacterTargetRot.z >= -0.25f)
Debug.Log(m_CharacterTargetRot.z);
}
Quaternion ClampRotationAroundXAxis(Quaternion q)
{
q.x /= q.w;
q.y /= q.w;
q.z /= q.w;
q.w = 1.0f;
float angleX = 2.0f * Mathf.Rad2Deg * Mathf.Atan(q.x);
angleX = Mathf.Clamp(angleX, MinimumX, MaximumX);
q.x = Mathf.Tan(0.5f * Mathf.Deg2Rad * angleX);
return q;
}
//Peeking Functions
public void LeanLeft()
{
if (m_CharacterTargetRot.z <= 0.25f)
zRot = 1f;
isLeaning = true;
}
public void LeanRight()
{
if (m_CharacterTargetRot.z >= -0.25f)
zRot = -1f;
isLeaning = true;
}
public void LeanBack()
{
isLeaning = false;
if (isInMiddle && !isLeaning)
{
zRot = 0;
}
else if (m_CharacterTargetRot.z > 0 && !isInMiddle && !isLeaning)
{
zRot = -1.1f;
}
else if (m_CharacterTargetRot.z < 0 && !isInMiddle && !isLeaning)
{
zRot = 1.1f;
}
// m_CharacterTargetRot *= Quaternion.Euler(0f, yRot, 0);
}
public bool isCentered()
{
return (isInMiddle && deleteActivator);
}
}
}