I made a 2 drawings of my setup and what i want to achieve
In short CB should always be perpendicular(90 angle) to AB.
UPDATE : I have found this Vector3.OrthoNormalize but im not sure how to use it for my problem?
Vector3 A; is the empty childObject of the character or player.
Vector3 B; is an empty object that will spin in a cricle around Vector A around Y axis at a fixed distance,based on Mouse X axis.
Vector3 C; is the Camera that will follow VectorB; camera will move up/down at a clamped min/max angle based on Mouse Y axis.
What ive achieved so far:
-
Object B spins around A at fixed distance around Y axis based on mouse input;
-
Camera follows B position,and can rotate up/down based on mouse input;
-
Camera can zoom in/out with mouseWheel;
This how the camera should behave:
What i dont know how to aproach:
- Camera doesnt spin along with B Vector at a 90* angle,all that camera does is update position back and forth depending where B has rotated and follows that.
Im not very good at math either,I dont know how to give Camera a constant 90 angle towards B.I tought of raycasthit and the normal angle but B is not a physical object.
Should i calculate 3 vectors and make like a triangle between a,b,c and if the b angle is less or over 90 set it to 90 like each frame and update camera based of that? but i dont know exactly how to do that either or if its viable.Or some calculation based of the tangent created by B.
This is my code or part of it i have 3 scripts so far,this is based of 3DBuzz TPS Camera and Unity StealthGame Tutorials.
LookAtMain is Vector A on the drawing, LookAtSecond is Vector B;
using UnityEngine;
using System.Collections;
public class TPCamera : MonoBehaviour {
public TPCamera Instance;
public Transform LookAtMain;
public Transform LookAtSecond;
private GameObject _camera;
float _distance = 3f;
float DistanceMin = 1f;
float DistanceMax = 4f;
float desiredDistance = 0f;
float startDistance = 5f;
float MouseWheelSensitivity = 6f;
float DistanceSmooth = 0.05f;
float velDistance = 0f;
float smooth = 2.5f;
float mouseX;
float mouseY;
float XMouseSensitivity = 2f;
float YMouseSensitivity = 1f;
float Y_MinLimit = -40f;
float Y_MaxLimit = 60f;
Vector3 CameraToPivot = Vector3.zero;
Vector3 pivotToHead = Vector3.zero;
Vector3 _camPos = Vector3.zero;
Vector3 _pivotPos = Vector3.zero;
void Awake(){
Instance = this;
}
void Start () {
_camera = this.gameObject;
Reset();
}
void LateUpdate()
{
HandlePlayerInput();
CalculateDesiredPosition();
UpdatePivot();
UpdateCamera();
}
void HandlePlayerInput(){
var deadZone = 0.01f;
if (!Input.GetKey(KeyCode.LeftAlt)) {
mouseX += Input.GetAxis("Mouse X") * XMouseSensitivity;
mouseY -= Input.GetAxis("Mouse Y") * YMouseSensitivity;
Screen.lockCursor = true;
}
else
Screen.lockCursor = false;
mouseY = Helper.ClampAngle(mouseY, Y_MinLimit, Y_MaxLimit);
if (Input.GetAxis("Mouse ScrollWheel") < -deadZone || Input.GetAxis("Mouse ScrollWheel") > deadZone)
{
desiredDistance = Mathf.Clamp(_distance - Input.GetAxis("Mouse ScrollWheel") * MouseWheelSensitivity, DistanceMin, DistanceMax);
}
}
void CalculateDesiredPosition()
{
_distance = Mathf.Lerp(_distance, desiredDistance, smooth * Time.deltaTime);
pivotToHead = PivotPosition(mouseX);
CameraToPivot = CameraPosition(mouseY, _distance);
}
// /////////////////////////////////////// PIVOT AREA ////////////////////////////////////////////// //
Vector3 PivotPosition(float rotY)
{
float distance = 1f;
Vector3 direction = new Vector3(distance, 0, 0);
Quaternion rotation = Quaternion.Euler(0, rotY* 0.5f, 0);
direction = Vector3.Normalize(direction);
direction = direction / 1.65f;
return LookAtMain.position + rotation * direction;
}
void UpdatePivot()
{
LookAtSecond.transform.position = _pivotPos + pivotToHead;
LookAtSecond.transform.LookAt(LookAtMain);
}
// /////////////////////////////////////// CAMERA AREA ////////////////////////////////////////////// //
Vector3 CameraPosition(float rotX,float distance)
{
Vector3 direction = new Vector3(0, 0, -distance);
Quaternion rotation = Quaternion.Euler(rotX, 0, 0);
return LookAtSecond.position + rotation* direction;
}
void UpdateCamera()
{
var posX = Mathf.SmoothDamp(_camPos.x, CameraToPivot.x, ref velDistance, DistanceSmooth);
var posY = Mathf.SmoothDamp(_camPos.y, CameraToPivot.y, ref velDistance, DistanceSmooth);
var posZ = Mathf.SmoothDamp(_camPos.z, CameraToPivot.z, ref velDistance, DistanceSmooth);
_camPos = new Vector3(posX, posY, posZ);
_camera.transform.position = CameraToPivot + _pivotPos;
_camera.transform.LookAt(LookAtSecond);
}
public void Reset()
{
mouseX = 0;
mouseY = 10;
_distance = startDistance;
desiredDistance = _distance;
}
public static void GetComponents()
{
GameObject tempCamera;
GameObject LookAtMain;
GameObject LookAtSecond;
TPCamera camScript;
tempCamera = Camera.main.gameObject;
camScript = tempCamera.GetComponent<TPCamera>();
LookAtMain = GameObject.Find("LookAtMain") as GameObject;
LookAtSecond = GameObject.Find("LookAtSecond") as GameObject;
camScript.LookAtMain = LookAtMain.transform;
camScript.LookAtSecond = LookAtSecond.transform;
}
}