tps camera issues
In reviewing some of the questions I have asked over the years I am almost embarrassed by some of them. A lot of people have been helpful and a lot of times I eventually figured it out or found a work around. Like this issue, for instance. My TPS camera that I got from the unity store acts really weird. As long as I run in the +Z direction or even + or -90 degrees in the X it works fine...but if i do an about face and go back in the -Z direction, the animation (run) seems to sheer left or right making it impossible to run in a straight line. I can WALK in a straight line but not run. It isn't the animation and my work around was to parent the camera to the player with the Simple Mouse Rotator script ( standard assets I believe) on the player. This gives me the same feel of steering the player with the mouse. I put the Smooth Follow script on the camera as well as a simple js to mousewheelzoom. The Rotator script works well for the horizontal movement but I have to clamp the vertical else it tilts the player. So I put the Rotator script on an empty gameObject clamping the horizontal and giving it 60 degrees of vertical motion so the camera can go up and down ( without tilting the player) as well as steer the player with the mouse. The camera is a child of said empty gameobject and that game object is a child of the player. WAAAAYY more complicated than just getting the stupid TPS to not mess up if I run in the -Z axis. Here is the TPS camera script. Can anybody see anything in it that would cause the animation to sheer? I mean if I try to follow a straight line I will suddenly cut to the left or right and when I move the mouse to compensate it runs straight for a few frames then sheers the other way - almost as if I am hitting a big wedge shaped invisible collider. The animation itself has the player running forward but sliding at an angle
/*******************************
* Script Author: Paul L. Davis *
*******************************/
using UnityEngine;
using System.Collections;
public class TPSCamera : MonoBehaviour {
/* These variables are what tell the camera how its going to function by
* setting the viewing target, collision layers, and other properties
* such as distance and viewing angles */
public Transform viewTarget, aimPoint;
public LayerMask collisionLayers;
public float distance = 2.5f;
public float height = 1.75f;
public float offset = 0.65f;
public float collisionOffset = 0.3f;
public float horizontalRotationSpeed = 250.0f;
public float verticalRotationSpeed = 150.0f;
public float rotationDampening = 0.75f;
public float minVerticalAngle = -60.0f;
public float maxVerticalAngle = 60.0f;
//public float minHorizontalalAngle = -60.0f;
//public float maxminHorizontalAngle = 60.0f;
public bool rotatePlayerWithCamera = true;
public bool invertPlayerAim = false;
/* These variables are meant to store values given by the script and
* not the user */
private float h, v;
private Vector3 newPosition;
private Quaternion newRotation, smoothRotation;
private Transform cameraTransform;
/* This is where we initialize our script */
void Start () {
Initialize ();
}
/* This is where we set our private variables, check for null errors,
* and anything else that needs to be called once during startup */
void Initialize () {
h = this.transform.eulerAngles.x;
v = this.transform.eulerAngles.y;
cameraTransform = this.transform;
NullErrorCheck ();
}
/* We check for null errors or warnings and notify the user to fix them */
void NullErrorCheck () {
if (!viewTarget) {
Debug.LogError("Please make sure to assign a view target!");
Debug.Break ();
}
if (collisionLayers == 0) {
Debug.LogWarning("Make sure to set the collision layers to the layers the camera should collide with!");
}
}
/* This is where we do all our camera updates. This is where the camera
* gets all of its functionality. From setting the position and rotation,
* to adjusting the camera to avoid geometry clipping */
void LateUpdate () {
if (!viewTarget)
return;
/* We check that the game isn't paused and lock the cursor */
if (Time.timeScale > 0.0f)
Screen.lockCursor = true;
Screen.showCursor = false;
h += Input.GetAxis ("Mouse X") * (horizontalRotationSpeed * Time.deltaTime);
v -= Input.GetAxis ("Mouse Y") * (verticalRotationSpeed * Time.deltaTime);
h = ClampAngle (h, -360.0f, 360.0f);// -360.0f, 360.0f
v = ClampAngle (v, minVerticalAngle, maxVerticalAngle);
newRotation = Quaternion.Euler(v, h, 0.0f);
/* We smooth the camera rotation using a growth function for a nicer viewing effect */
smoothRotation = Quaternion.Slerp (smoothRotation, newRotation, TimeSignature((1 / rotationDampening) * 100.0f));
newPosition = viewTarget.position;
newPosition += smoothRotation * new Vector3 (offset, height, -distance);
/* This calls our function to avoid camera clipping */
CheckSphere ();
smoothRotation.eulerAngles = new Vector3 (smoothRotation.eulerAngles.x, smoothRotation.eulerAngles.y, 0.0f);
cameraTransform.position = newPosition;
cameraTransform.rotation = smoothRotation;
Vector3 newTargetRot = new Vector3 (0.0f, cameraTransform.eulerAngles.y, 0.0f);
if (rotatePlayerWithCamera) {
/* We set our player's rotation to the cameras y rotation */
viewTarget.rotation = Quaternion.Euler (newTargetRot);
}
/* We set the players aim rotation to the cameras x rotation */
newTargetRot = aimPoint.eulerAngles;
if (invertPlayerAim)
newTargetRot.x = (cameraTransform.eulerAngles.x);
else
newTargetRot.x = -(cameraTransform.eulerAngles.x);
aimPoint.rotation = Quaternion.Euler (newTargetRot);
}
/* This is where the camera checks for a collsion hit within a specified radius,
* and then moves the camera above the location it hit with an offset value */
void CheckSphere () {
/* Add height to our spherecast origin */
Vector3 tmpVect = viewTarget.position;
tmpVect.x += offset;
tmpVect.y += height;
RaycastHit hit;
/* Get the direction from the camera position to the origin */
Vector3 dir = (newPosition - tmpVect).normalized;
/* Check a radius for collision hits and then set the new position for
* the camera */
if(Physics.SphereCast(tmpVect, 0.3f, dir, out hit, distance, collisionLayers)) {
newPosition = hit.point + (hit.normal * collisionOffset);
}
}
/* Keeps the angles values within their specificed minimum and maximum
* inputs while at the same time putting the values back to 0 if they
* go outside of the 360 degree range */
private float ClampAngle (float angle, float min, float max) {
if(angle < -360)
angle += 360;
if(angle > 360)
angle -= 360;
return Mathf.Clamp (angle, min, max);
}
/* This is our custom logistic growth time signature with speed as input */
private float TimeSignature(float speed) {
return 1.0f / (1.0f + 80.0f * Mathf.Exp(-speed * 0.02f));
}
}
Your answer
Follow this Question
Related Questions
player runs crooked in -z 0 Answers
Third Person Shooter Controller 0 Answers
Any game ideas? 0 Answers
Problem with player control with physical joystick 0 Answers
Please tell me how to make the camera for TPS in Chinemachine 1 Answer