C#/Unity Camera rotation - c#

Im trying to make it so that the camera always follows the ball, but i can only rotate it when i hold down rightclick. although, right now, it only follows the ball when i hold right click aswell. Is there a way to seperate the two?
using UnityEngine;
using System.Collections;
public class Orbit2 : MonoBehaviour {
public Transform target;
public float distance = 5.0f;
public float xSpeed = 120.0f;
public float ySpeed = 120.0f;
public float yMinLimit = -20f;
public float yMaxLimit = 80f;
public float distanceMin = .5f;
public float distanceMax = 15f;
private Rigidbody rigidbody;
float x = 0.0f;
float y = 0.0f;
// Use this for initialization
void Start()
{
Vector3 angles = transform.eulerAngles;
x = angles.y;
y = angles.x;
rigidbody = GetComponent<Rigidbody>();
// Make the rigid body not change rotation
if (rigidbody != null)
{
rigidbody.freezeRotation = true;
}
}
void LateUpdate()
{
if (target
&& Input.GetMouseButton(1))
{
x += Input.GetAxis("Mouse X") * xSpeed * distance * 0.02f;
y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
y = ClampAngle(y, yMinLimit, yMaxLimit);
Quaternion rotation = Quaternion.Euler(y, x, 0);
distance = Mathf.Clamp(distance - Input.GetAxis("Mouse ScrollWheel") * 5, distanceMin, distanceMax);
RaycastHit hit;
if (Physics.Linecast(target.position, transform.position, out hit))
{
distance -= hit.distance;
}
Vector3 negDistance = new Vector3(0.0f, 0.0f, -distance);
Vector3 position = rotation * negDistance + target.position;
transform.rotation = rotation;
transform.position = position;
}
}
public static float ClampAngle(float angle, float min, float max)
{
if (angle < -360F)
angle += 360F;
if (angle > 360F)
angle -= 360F;
return Mathf.Clamp(angle, min, max);
}
}

It looks like you want the rotation to happen only when the right mouse button is held down. If this is true, then remove Input.GetMouseButton(1) from where it is now and then wrap it around transform.rotation = rotation;. It is as simple as that. FYI, you don't even need if (target). That is unnecessary but I leave it as it is.
public Transform target;
public float distance = 5.0f;
public float xSpeed = 120.0f;
public float ySpeed = 120.0f;
public float yMinLimit = -20f;
public float yMaxLimit = 80f;
public float distanceMin = .5f;
public float distanceMax = 15f;
private Rigidbody rigidbody;
float x = 0.0f;
float y = 0.0f;
// Use this for initialization
void Start()
{
Vector3 angles = transform.eulerAngles;
x = angles.y;
y = angles.x;
rigidbody = GetComponent<Rigidbody>();
// Make the rigid body not change rotation
if (rigidbody != null)
{
rigidbody.freezeRotation = true;
}
}
void LateUpdate()
{
if (target)
{
x += Input.GetAxis("Mouse X") * xSpeed * distance * 0.02f;
y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
y = ClampAngle(y, yMinLimit, yMaxLimit);
Quaternion rotation = Quaternion.Euler(y, x, 0);
distance = Mathf.Clamp(distance - Input.GetAxis("Mouse ScrollWheel") * 5, distanceMin, distanceMax);
RaycastHit hit;
if (Physics.Linecast(target.position, transform.position, out hit))
{
distance -= hit.distance;
}
Vector3 negDistance = new Vector3(0.0f, 0.0f, -distance);
Vector3 position = rotation * negDistance + target.position;
//Move Input.GetMouseButton(1) here
if (Input.GetMouseButton(1))
{
transform.rotation = rotation;
}
transform.position = position;
}
}
public static float ClampAngle(float angle, float min, float max)
{
if (angle < -360F)
angle += 360F;
if (angle > 360F)
angle -= 360F;
return Mathf.Clamp(angle, min, max);
}

Related

How do I get my forward movement to match the direction of my camera?

I'm new to game development and I cant seem to make the forward movement of my player to match the direction my camera is facing. I'm in the process of learning how to make simple characters and simple character movement. I've gotten where I can press play and move forward, backwards, left, and right but if i "turn" around with the camera and press w it still moves positive on the Z-axis. Thanks in advance.
Here is my movement script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//My Movement Controller
public class MovementController : MonoBehaviour
{
CharacterController characterController;
public float MovementSpeed =1;
public float Gravity = 9.8f;
private float velocity = 0;
private void Start()
{
characterController = GetComponent<CharacterController>();
}
void Update()
{
// player movement - forward, backward, left, right
float horizontal = Input.GetAxis("Horizontal") * MovementSpeed;
float vertical = Input.GetAxis("Vertical") * MovementSpeed;
characterController.Move((Vector3.right * horizontal + Vector3.forward * vertical) *
Time.deltaTime);
// Gravity
if(characterController.isGrounded)
{
velocity = 0;
}
else
{
velocity -= Gravity * Time.deltaTime;
characterController.Move(new Vector3(0, velocity, 0));
}
}
}
And here is my camera movement script:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[AddComponentMenu("Camera-Control/Smooth Mouse Look")]
public class MouseLook : MonoBehaviour
{
public enum RotationAxes { MouseXAndY = 0, MouseX = 1, MouseY = 2 }
public RotationAxes axes = RotationAxes.MouseXAndY;
public float sensitivityX = 15F;
public float sensitivityY = 15F;
public float minimumX = -360F;
public float maximumX = 360F;
public float minimumY = -60F;
public float maximumY = 60F;
float rotationX = 0F;
float rotationY = 0F;
private List<float> rotArrayX = new List<float>();
float rotAverageX = 0F;
private List<float> rotArrayY = new List<float>();
float rotAverageY = 0F;
public float frameCounter = 20;
Quaternion originalRotation;
void Update ()
{
if (axes == RotationAxes.MouseXAndY)
{
//Resets the average rotation
rotAverageY = 0f;
rotAverageX = 0f;
//Gets rotational input from the mouse
rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
rotationX += Input.GetAxis("Mouse X") * sensitivityX;
//Adds the rotation values to their relative array
rotArrayY.Add(rotationY);
rotArrayX.Add(rotationX);
//If the arrays length is bigger or equal to the value of frameCounter remove the first value
in the array
if (rotArrayY.Count >= frameCounter) {
rotArrayY.RemoveAt(0);
}
if (rotArrayX.Count >= frameCounter) {
rotArrayX.RemoveAt(0);
}
//Adding up all the rotational input values from each array
for(int j = 0; j < rotArrayY.Count; j++) {
rotAverageY += rotArrayY[j];
}
for(int i = 0; i < rotArrayX.Count; i++) {
rotAverageX += rotArrayX[i];
}
//Standard maths to find the average
rotAverageY /= rotArrayY.Count;
rotAverageX /= rotArrayX.Count;
//Clamp the rotation average to be within a specific value range
rotAverageY = ClampAngle (rotAverageY, minimumY, maximumY);
rotAverageX = ClampAngle (rotAverageX, minimumX, maximumX);
//Get the rotation you will be at next as a Quaternion
Quaternion yQuaternion = Quaternion.AngleAxis (rotAverageY, Vector3.left);
Quaternion xQuaternion = Quaternion.AngleAxis (rotAverageX, Vector3.up);
//Rotate
transform.localRotation = originalRotation * xQuaternion * yQuaternion;
}
else if (axes == RotationAxes.MouseX)
{
rotAverageX = 0f;
rotationX += Input.GetAxis("Mouse X") * sensitivityX;
rotArrayX.Add(rotationX);
if (rotArrayX.Count >= frameCounter) {
rotArrayX.RemoveAt(0);
}
for(int i = 0; i < rotArrayX.Count; i++) {
rotAverageX += rotArrayX[i];
}
rotAverageX /= rotArrayX.Count;
rotAverageX = ClampAngle (rotAverageX, minimumX, maximumX);
Quaternion xQuaternion = Quaternion.AngleAxis (rotAverageX, Vector3.up);
transform.localRotation = originalRotation * xQuaternion;
}
else
{
rotAverageY = 0f;
rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
rotArrayY.Add(rotationY);
if (rotArrayY.Count >= frameCounter) {
rotArrayY.RemoveAt(0);
}
for(int j = 0; j < rotArrayY.Count; j++) {
rotAverageY += rotArrayY[j];
}
rotAverageY /= rotArrayY.Count;
rotAverageY = ClampAngle (rotAverageY, minimumY, maximumY);
Quaternion yQuaternion = Quaternion.AngleAxis (rotAverageY, Vector3.left);
transform.localRotation = originalRotation * yQuaternion;
}
}
void Start ()
{
Rigidbody rb = GetComponent<Rigidbody>();
if (rb)
rb.freezeRotation = true;
originalRotation = transform.localRotation;
}
public static float ClampAngle (float angle, float min, float max)
{
angle = angle % 360;
if ((angle >= -360F) && (angle <= 360F)) {
if (angle < -360F) {
angle += 360F;
}
if (angle > 360F) {
angle -= 360F;
}
}
return Mathf.Clamp (angle, min, max);
}
}
The problem is in this line of your movement script:
characterController.Move((Vector3.right * horizontal + Vector3.forward * vertical) *
Time.deltaTime);
You are moving to the right/left and forward/backward of a Vector3, which is always the same, what you want is this:
characterController.Move((transform.right * horizontal + transform.forward * vertical) *
Time.deltaTime);
This way you can move to the right/left and forward/backward of your player current rotation.

Unity3d: rotate camera around center of the screen with middle mouse button pressed

I am working on an RTS game and would like to support the camera to rotate around the current center of the screen on mouse button pressed, just like in any RTS, strategy game.
I tried the MouseOrbitImproved script as shown on the unity wiki (copied below), but it needs a target object used by the camera to rotate around. My problem is that my target is always the current center of the screen.
Any idea how to achieve this, but only while the middle mouse button is pressed?
using UnityEngine;
using System.Collections;
[AddComponentMenu("Camera-Control/Mouse Orbit with zoom")]
public class MouseOrbitImproved : MonoBehaviour {
public Transform target;
public float distance = 5.0f;
public float xSpeed = 120.0f;
public float ySpeed = 120.0f;
public float yMinLimit = -20f;
public float yMaxLimit = 80f;
public float distanceMin = .5f;
public float distanceMax = 15f;
private Rigidbody rigidbody;
float x = 0.0f;
float y = 0.0f;
// Use this for initialization
void Start ()
{
Vector3 angles = transform.eulerAngles;
x = angles.y;
y = angles.x;
rigidbody = GetComponent<Rigidbody>();
// Make the rigid body not change rotation
if (rigidbody != null)
{
rigidbody.freezeRotation = true;
}
}
void LateUpdate ()
{
if (target)
{
x += Input.GetAxis("Mouse X") * xSpeed * distance * 0.02f;
y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
y = ClampAngle(y, yMinLimit, yMaxLimit);
Quaternion rotation = Quaternion.Euler(y, x, 0);
distance = Mathf.Clamp(distance - Input.GetAxis("Mouse ScrollWheel")*5, distanceMin, distanceMax);
RaycastHit hit;
if (Physics.Linecast (target.position, transform.position, out hit))
{
distance -= hit.distance;
}
Vector3 negDistance = new Vector3(0.0f, 0.0f, -distance);
Vector3 position = rotation * negDistance + target.position;
transform.rotation = rotation;
transform.position = position;
}
}
public static float ClampAngle(float angle, float min, float max)
{
if (angle < -360F)
angle += 360F;
if (angle > 360F)
angle -= 360F;
return Mathf.Clamp(angle, min, max);
}
}
In your orbit function, where you determine the object to orbit around, raycast a ray from the center of the screen and orbit around the collision:
public LayerMask groundLayerMask; // mask to choose orbitable layers
...
Ray screenRay = Camera.main.ScreenPointToRay(new Vector3(Screen.width/2f, Screen.height/2f, 0f));`
RaycastHit hitInfo;
Physics.Raycast(screenRay, out hitInfo, Mathf.Infinity, groundLayerMask.value);
Vector3 orbitPosition = hitInfo.point;
You can check if the middle mouse button is pressed with Input.GetMouseButton(2). Before orbiting, check it and only detect mouse input changes if its held down.
In the MouseOrbitImproved code it might look like this in the LateUpdate method:
void LateUpdate ()
{
// Skip mouse input here if middle mouse button is not pressed
if (Input.GetMouseButton(2))
{
x += Input.GetAxis("Mouse X") * xSpeed * distance * 0.02f;
y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
y = ClampAngle(y, yMinLimit, yMaxLimit);
}
Quaternion rotation = Quaternion.Euler(y, x, 0);
distance = Mathf.Clamp(distance - Input.GetAxis("Mouse ScrollWheel")*5, distanceMin, distanceMax);
Ray screenRay = Camera.main.ScreenPointToRay(new Vector3(Screen.width/2f, Screen.height/2f, 0f));`
RaycastHit hitInfo;
Physics.Raycast(screenRay, out hitInfo, Mathf.Infinity, groundLayerMask.value);
Vector3 orbitPosition = hitInfo.point;
Vector3 negDistance = new Vector3(0.0f, 0.0f, -distance);
Vector3 position = rotation * negDistance + orbitPosition ;
transform.rotation = rotation;
transform.position = position;
}
In the class fields, get rid of public Transform target; and add public LayerMask groundLayerMask; and set it in the inspector to only collide with whatever layer your ground is.

Unity 2018 C# - Fbx Running animation scaling with Input?

I have figured out how to get fbx animations working in Unity for my character in my adventure game, but now I wish to have my character's running animation move with its speed of motion being in relation to the input of the control stick on an xbox controller.
In addition, when I add a walking animation in the future I wish to make a threshold for the control stick input so that the character walks when there is minimal input from the control stick and running when there is more input from the control stick. Any advice?
Here is my code.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerCharacterController : MonoBehaviour {
static Animator anim;
public bool walking;
public GameObject playerModel, Hero;
//Transforms
public Transform playerCam, character, centerPoint;
private Vector3 moveDirection;
//character controller declaration
CharacterController player;
//Mouse Rotation
private float rotX, rotY;
//Mouse Y Position
public float mouseYPosition = 1f;
//Mouse Sensitivity
public float Sensitivity = 10f;
//Mouse Zoom
private float zoom;
public float zoomSpeed = 2;
//Clamping Zoom
public float zoomMin = -2f;
public float zoomMax = -10f;
public float rotationSpeed = 5f;
//Move Front Back left & Right
private float moveFB, moveLR;
//Movement Speed
public float Speed = 2f;
//Velocity of Gravity
public float verticalVelocity;
//Jump Distance
public float jumpDist = 5f;
//Multiple Jumps
int jumpTimes;
//To use with Dialogue Manager
public DialogueManager DiagM;
public AudioClip jumpSound;
public AudioClip HurtSound;
AudioSource audioSource;
//knockback
public float knockBackForce;
public float knockBackTime;
private float knockBackCounter;
// Use this for initialization
void Start ()
{
//character controller
player = GameObject.Find("Player").GetComponent<CharacterController> ();
anim = GetComponent<Animator>();
//mouse zoom
zoom = -3;
centerPoint.transform.position = playerCam.transform.position;
centerPoint.transform.parent = null;
audioSource = GetComponent<AudioSource>();
}
// Update is called once per frame
void Update ()
{
//if (DiagM.StartDialogue)
//{ return; }
//Mouse Zoom Input
zoom += Input.GetAxis ("Mouse ScrollWheel") * zoomSpeed;
if (zoom > zoomMin)
zoom = zoomMin;
if (zoom < zoomMax)
zoom = zoomMax;
//Mouse Camera Input
playerCam.transform.localPosition = new Vector3 (0, 0, zoom);
//Mouse Rotation
rotX += Input.GetAxis ("Mouse X") * Sensitivity;
rotY -= Input.GetAxis ("Mouse Y") * Sensitivity;
//Clamp Camera
rotY = Mathf.Clamp (rotY, -60f, 60f);
playerCam.LookAt (centerPoint);
centerPoint.localRotation = Quaternion.Euler (rotY, rotX, 0);
//Movement Speed
if (knockBackCounter <= 0)
{
moveDirection = (transform.forward * Input.GetAxis("Vertical")) + (transform.right * Input.GetAxis("Horizontal"));
moveDirection = moveDirection * Speed;
moveDirection.y = verticalVelocity;
player.Move(moveDirection * Time.deltaTime);
//Movement Rotation
centerPoint.position = new Vector3 (character.position.x, character.position.y + mouseYPosition, character.position.z);
//knockback disable
//Movement Input
if (Input.GetAxis("Vertical") != 0 || Input.GetAxis("Horizontal") != 0)
{
transform.rotation = Quaternion.Euler(0f, centerPoint.rotation.eulerAngles.y, 0f);
Quaternion turnAngle = Quaternion.LookRotation(new Vector3(moveDirection.x, 0f, moveDirection.z));
playerModel.transform.rotation = Quaternion.Slerp(playerModel.transform.rotation, turnAngle, Time.deltaTime * rotationSpeed);
if (player.isGrounded == true)
{
anim.Play("Running");
}
}
else
{
if (player.isGrounded == true)
{ anim.Play("Idle"); }
}
if (player.isGrounded == true)
{
jumpTimes = 0;
verticalVelocity = -Physics.gravity.y * Time.deltaTime;
}
else
{
verticalVelocity += Physics.gravity.y * Time.deltaTime;
}
if (Input.GetButtonDown("Submit"))
{
anim.Play("Hello");
}
if (jumpTimes < 1)
{
if (Input.GetButtonDown("Jump"))
{
verticalVelocity += jumpDist;
anim.Play("Jump");
audioSource.PlayOneShot(jumpSound, 1F);
jumpTimes += 1;
}
}
}
else
{
knockBackCounter -= Time.deltaTime;
}
}
public void Knockback(Vector3 direction)
{
knockBackCounter = knockBackTime;
anim.SetTrigger("isJumping");
audioSource.PlayOneShot(HurtSound, 50F);
moveDirection = direction * knockBackForce;
moveDirection.y = knockBackForce;
}
}

Zoom camera in/out with Mouse Scrollwheel via the transform instead of fov?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MouseOrbit : MonoBehaviour {
public Transform target;
public float distance = 5.0f;
public float xSpeed = 120.0f;
public float ySpeed = 120.0f;
public float yMinLimit = -20f;
public float yMaxLimit = 80f;
public float distanceMin = .5f;
public float distanceMax = 15f;
private Rigidbody rigidbody;
float x = 0.0f;
float y = 0.0f;
float minFov = 15f;
float maxFov = 90f;
float sensitivity = 10f;
// Use this for initialization
void Start()
{
Vector3 angles = transform.eulerAngles;
x = angles.y;
y = angles.x;
rigidbody = GetComponent<Rigidbody>();
// Make the rigid body not change rotation
if (rigidbody != null)
{
rigidbody.freezeRotation = true;
}
}
void Update()
{
// Updating camera distance on every frame
distance = RayCast3.distance3;
//Setting maximum distance so the camera doesnt go too far
if (distance > 2)
{
distance = 2;
}
}
void LateUpdate()
{
if (target)
{
x += Input.GetAxis("Mouse X") * xSpeed * distance * 0.02f;
y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
y = ClampAngle(y, yMinLimit, yMaxLimit);
Quaternion rotation = Quaternion.Euler(y, x, 0);
//distance = Mathf.Clamp(distance - Input.GetAxis("Mouse ScrollWheel") * 5, distanceMin, distanceMax);
//distance += Input.GetAxis("Mouse ScrollWheel") * sensitivity;
float fov = Camera.main.fieldOfView;
fov += Input.GetAxis("Mouse ScrollWheel") * sensitivity;
fov = Mathf.Clamp(fov, minFov, maxFov);
Camera.main.fieldOfView = fov;
RaycastHit hit;
if (Physics.Linecast(target.position, transform.position, out hit))
{
distance -= hit.distance;
}
Vector3 negDistance = new Vector3(0.0f, 0.0f, -distance);
Vector3 position = rotation * negDistance + target.position;
transform.rotation = rotation;
transform.position = position;
}
}
public static float ClampAngle(float angle, float min, float max)
{
if (angle < -360F)
angle += 360F;
if (angle > 360F)
angle -= 360F;
return Mathf.Clamp(angle, min, max);
}
}
Now i'm using fov:
And it's working fine.
float fov = Camera.main.fieldOfView;
fov += Input.GetAxis("Mouse ScrollWheel") * sensitivity;
fov = Mathf.Clamp(fov, minFov, maxFov);
Camera.main.fieldOfView = fov;
But now i want to use the distance variable and not fov.
So i tried first the line:
distance = Mathf.Clamp(distance - Input.GetAxis("Mouse ScrollWheel") * 5, distanceMin, distanceMax);
It didn't work so i tried the line:
distance += Input.GetAxis("Mouse ScrollWheel") * sensitivity;
But in both lines the character is stuttering and it's not zooming in out with the mouse wheel.
It's really simple. Get mouse scroll wheel speed then multiply it by some speed value. You can also multiply it by Time.deltaTime if you want. Finally use transform.Translate to move the camera with that value.
This will move in z-axis:
private float zoomSpeed = 2.0f;
void Update()
{
float scroll = Input.GetAxis("Mouse ScrollWheel");
transform.Translate(0, 0, scroll * zoomSpeed, Space.World);
}
Or where camera is facing:
private float zoomSpeed = 5.0f;
void Update()
{
float scroll = Input.GetAxis("Mouse ScrollWheel");
transform.position += this.transform.forward * scroll * zoomSpeed;
}
You should calculate a delta between your camera point and your target point. Normalize it and multiply it with the scrollwheel delta. Add this on your camera position. I used the camera target as angle to zoom-in.
Pseudo:
var delta = cameraTarget - cameraPosition;
delta.Normalize();
cameraPosition += delta * ScrollWheel.delta * sensitivity;
// you can even move your cameraTarget in the same direction
cameraTarget += delta * ScrollWheel.delta * sensitivity;
You can use the distance instead of calculating a delta.

C# with Unity 3D: How do I make a camera move around an object when user moves mouse

I am trying to make a 3d viewing simulation in Unity 4 where the user can select an object and move their mouse to rotate around it (360 degrees) I have taken many shots to try get it to work, but I fail each time, any help will be appreciated and if it is written in C# that would be great! (But it doesn't have to)
Thanks in advance!
This is a different and interesting way :) (I use it)
(Here, the cube is the target)
1) Create sphere - Name: "Camera Orbit" - Add material: Transparent (Alpha = 0) - As scale as you want - Rotation: (0,0,0.1f)
2) Add the camera as a "child" to Camera Orbit's surface. Position = (0,"y = camera orbit scale",0)
Rotation = (90,0,0)
3) Create empty GameObject - Name: Input Control.
InputControl.cs:
public class InputControl : MonoBehaviour
{
public GameObject cameraOrbit;
public float rotateSpeed = 8f;
void Update()
{
if (Input.GetMouseButton(0))
{
float h = rotateSpeed * Input.GetAxis("Mouse X");
float v = rotateSpeed * Input.GetAxis("Mouse Y");
if (cameraOrbit.transform.eulerAngles.z + v <= 0.1f || cameraOrbit.transform.eulerAngles.z + v >= 179.9f)
v = 0;
cameraOrbit.transform.eulerAngles = new Vector3(cameraOrbit.transform.eulerAngles.x, cameraOrbit.transform.eulerAngles.y + h, cameraOrbit.transform.eulerAngles.z + v);
}
float scrollFactor = Input.GetAxis("Mouse ScrollWheel");
if (scrollFactor != 0)
{
cameraOrbit.transform.localScale = cameraOrbit.transform.localScale * (1f - scrollFactor);
}
}
}
CameraController.cs:
public class CameraController : MonoBehaviour
{
public Transform cameraOrbit;
public Transform target;
void Start()
{
cameraOrbit.position = target.position;
}
void Update()
{
transform.rotation = Quaternion.Euler(transform.rotation.x, transform.rotation.y, 0);
transform.LookAt(target.position);
}
}
4) Add CameraController.cs to Camera.
5) Add InputControl.cs to Input Control.
6) Set public variables in scripts. ("Camera Orbit" and "Target")
That's all. Mouse click and drag: Rotate - Mouse whell: Zoom in-out.
ps. If you want, you can change target as runtime.
The MouseOrbit script do that:
http://wiki.unity3d.com/index.php?title=MouseOrbitImproved#Code_C.23
Just attach this script into your Camera Object, and link the target object in inspector.
-- Use this for the Mouse Press down and drag
-- I modified the code here: http://wiki.unity3d.com/index.php?title=MouseOrbitImproved#Code_C.23
public Transform target;
public float distance = 5.0f;
public float xSpeed = 120.0f;
public float ySpeed = 120.0f;
public float yMinLimit = -20f;
public float yMaxLimit = 80f;
public float distanceMin = .5f;
public float distanceMax = 15f;
private Rigidbody rigidbody;
float x = 0.0f;
float y = 0.0f;
float mouseX = 0f;
float mouseY = 0f;
// Use this for initialization
void Start()
{
Vector3 angles = transform.eulerAngles;
x = angles.y;
y = angles.x;
rigidbody = GetComponent<Rigidbody>();
// Make the rigid body not change rotation
if (rigidbody != null)
{
rigidbody.freezeRotation = true;
}
}
void LateUpdate()
{
if (target)
{
GetMouseButtonDown_XY();
x += mouseX * xSpeed * distance * 0.02f;
y -= mouseY * ySpeed * 0.02f;
y = ClampAngle(y, yMinLimit, yMaxLimit);
Quaternion rotation = Quaternion.Euler(y, x, 0);
distance = Mathf.Clamp(distance - Input.GetAxis("Mouse ScrollWheel") * 5, distanceMin, distanceMax);
RaycastHit hit;
if (Physics.Linecast(target.position, transform.position, out hit))
{
distance -= hit.distance;
}
Vector3 negDistance = new Vector3(0.0f, 0.0f, -distance);
Vector3 position = rotation * negDistance + target.position;
transform.rotation = rotation;
transform.position = position;
}
}
public static float ClampAngle(float angle, float min, float max)
{
if (angle < -360F)
angle += 360F;
if (angle > 360F)
angle -= 360F;
return Mathf.Clamp(angle, min, max);
}
Vector3 mousePosPrev;
void GetMouseButtonDown_XY()
{
if (Input.GetMouseButtonDown(0))
{
mousePosPrev = Camera.main.ScreenToViewportPoint(Input.mousePosition);
}
if (Input.GetMouseButton(0))
{
Vector3 newMousePos = Camera.main.ScreenToViewportPoint(Input.mousePosition);
if (newMousePos.x < mousePosPrev.x)
{
mouseX = -1;
} else if (newMousePos.x > mousePosPrev.x)
{
mouseX = 1;
} else
{
mouseX = -0;
}
if (newMousePos.y < mousePosPrev.y)
{
mouseY = -1;
}
else if (newMousePos.y > mousePosPrev.y)
{
mouseY = 1;
}
else
{
mouseY = -0;
}
mousePosPrev = Camera.main.ScreenToViewportPoint(Input.mousePosition);
}
}
This is perfect. The only change I made is to add a script to the Camera Orbit:
public class FollowPlayer : MonoBehaviour {
public GameObject player;
private Vector3 playerPos;
// Update is called once per frame
void Update () {
if (this.transform.localScale.x <= 1)
{
this.transform.localScale = new Vector3(1, 1, 1);
}
if (this.transform.localScale.x >= 15)
{
this.transform.localScale = new Vector3(15, 15, 15);
}
playerPos = player.transform.position;
this.transform.position = playerPos;
}
}
Then attach your "player" object to the Input Control, and the input control will go where ever the player does, allowing you to track the player, as well as rotate and mouse wheel zoom. Fancy.
The localScale if statements means you can only zoom in and out so far.
The only problem with this script now is that if you zoom out to 15 and then keep trying to zoom out, the camera bounces. I'm sure that's an easy fix, though, I just haven't put the time in yet.
You don't need the CameraController at all, just set the camera's z rotation to -90.

Categories

Resources