Reputation: 749
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!
Upvotes: 4
Views: 27382
Reputation: 11
-- 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);
}
}
Upvotes: 1
Reputation: 1
You don't need the CameraController at all, just set the camera's z rotation to -90.
Upvotes: -1
Reputation: 1
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.
Upvotes: 0
Reputation: 575
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.
Upvotes: 14
Reputation: 581
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.
Upvotes: 4