What I mean in my question is that how to make your player rotate automatically when I move my mouse left for example and my whole characters body will rotate and limit its rotation back to a 2D view.
Similar to the game "Rochard" if you guys know it. But I'm having trouble how to figure it out.
This is my Code:
#pragma strict
var spinx : int = 0;
var spiny : int = 0;
var spinz : int = 0;
function Update () {
transform.Rotate(spinx, spiny, spinz);
}
The following script should rotate your object according to mouse position,
using UnityEngine;
using System.Collections;
public class RotateClass : MonoBehaviour {
public float horizontalSpeed = 2.0F;
public float verticalSpeed = 2.0F;
void Update() {
float h = horizontalSpeed * Input.GetAxis("Mouse X");
float v = verticalSpeed * Input.GetAxis("Mouse Y");
transform.Rotate(v, h, 0);
}
}
First, I am really sorry to write it in C#. But I hope it can help you. This script is attached to player gameobject.
private Vector3 MousePositionViewport = Vector3.zero;
private Quaternion DesiredRotation = new Quaternion();
private float RotationSpeed = 15;
void Update () {
MousePositionViewport = Camera.main.ScreenToViewportPoint (Input.mousePosition);
if (MousePositionViewport.x >= 0.6f) {
DesiredRotation = Quaternion.Euler (0, 90, 0);
} else if(MousePositionViewport.x < 0.6f && MousePositionViewport.x > 0.4f){
DesiredRotation = Quaternion.Euler (0, 270, 0);
}else {
DesiredRotation = Quaternion.Euler (0, 180, 0);
}
transform.rotation = Quaternion.Lerp (transform.rotation, DesiredRotation, Time.deltaTime*RotationSpeed);
}
this script should rotate your object acccording to mouse position
using UnityEngine;
using System.Collections;
public class MouseLook : MonoBehaviour {
void Update () {
Vector3 mousePos = new Vector3(Input.mousePosition.x, Input.mousePosition.z, 10);
Vector3 lookPos = Camera.main.ScreenToWorldPoint(mousePos);
lookPos = lookPos - transform.position;
float angle = Mathf.Atan2(lookPos.z, lookPos.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
}
}
You could import the standard player controls package from unity itself and edit the first person controller to your likings. This is what I tend to do when I want a control in my game that can do what you desire.
Related
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraScript : MonoBehaviour
{
[SerializeField] private float sensitivityHor = 9.0f;
[SerializeField] private float sensitivityVert = 9.0f;
[SerializeField] private float minimumVert = -45.0f;
[SerializeField] private float maximumVert = 45.0f;
private float _rotationX = 0;
private Rigidbody PlayerRigidbody;
void Start()
{
PlayerRigidbody = GetComponent<Rigidbody>();
if (PlayerRigidbody != null)
{
PlayerRigidbody.freezeRotation = true;
}
}
void Update()
{
_rotationX -= Input.GetAxis("Mouse Y") * sensitivityVert;
_rotationX = Mathf.Clamp(_rotationX, minimumVert, maximumVert);
float delta = Input.GetAxis("Mouse X") * sensitivityHor;
float rotationY = transform.localEulerAngles.y + delta;
transform.localEulerAngles = new Vector3(_rotationX, rotationY, 0);
}
}
Good evening. I have written a script to rotate the camera by swiping a finger across the screen
(it is on my camera), everything works correctly with one finger, but if you touch with two fingers at the same time, the application will react incorrectly (suddenly change the camera rotation). How can I fix it using Input.GetAxis or what can I use to write a script for multiple touches?
You may use only the first touch for your movement, so that if there is a second nothing happens and change Input.GetAxis("Mouse Y") by Input.GetTouch(0).deltaPosition.y with x and y respectively. Like this:
if (Input.touchCount > 0) {
_rotationX -= Input.GetTouch(0).deltaPosition.y * sensitivityVert;
_rotationX = Mathf.Clamp(_rotationX, minimumVert, maximumVert);
float delta = Input.GetTouch(0).deltaPosition.x * sensitivityHor;
float rotationY = transform.localEulerAngles.y + delta;
transform.localEulerAngles = new Vector3(_rotationX, rotationY, 0);
}
Code not debugged, as its just your code with the substitution.
If handling the first touch acts weird, you can handle the rotation with the middle point maybe. Like this:
//get the touch middle when the second finger touches
if (Input.GetTouch(1).phase == TouchPhase.Began) {
touchMiddle = (Input.GetTouch(0).position +
Input.GetTouch(1).position) / 2;
touchDistSqr = (Input.GetTouch(0).position -
Input.GetTouch(1).position).sqrMagnitude;
return;
}
if (Input.touchCount == 2) {
var deltaMidde = touchMiddle - (Input.GetTouch(0).position + Input.GetTouch(1).position) / 2;
transform.localEulerAngles = new Vector3(deltaMidde.x, deltaMidde.y, 0);
}
All the code in the LateUpdate().
Preferably camera movements needs to be done in the LateUpdate() for the objects that might have moved inside Update to be at their final state for each frame. As per adviced in the documentation.
Not really relevant but note that you can use Vector2 instead of Vector3for the screen operations most of the time.
Also it is very interesting in the Update or LateUpdate operations to have them multiplied by Time.deltaTime so that the movement is frame rate independent.
I'm making a mobile game that uses trajectory to find out the next path from my player. When the player is silent the trajectory works very well, but when the player is moving the trajectory sometimes moves on its own even though it returns to its proper position later, but this is very disturbing.
Here's the script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class PlayerMovement : MonoBehaviour
{
public static PlayerMovement Instance;
Rigidbody2D rb;
Vector3 startPos;
Vector3 endPos;
[HideInInspector] public Vector3 initPos;
[HideInInspector] public Vector3 direction;
public static Vector3 anotherSpeed; // Only for trajectory
float speedMultiplier = 1.5f;
public GameObject trajectoryDot;
GameObject[] trajectoryDots;
public int numbersOfTrajectory;
float trajectoryDotsDistance = 0.001f;
public static float energy = 100f;
public Slider energyBar;
float slowDownFactor = 0.3f;
private void Start()
{
if (!Instance)
Instance = this;
rb = GetComponent<Rigidbody2D>();
trajectoryDots = new GameObject[numbersOfTrajectory];
}
void Update()
{
anotherSpeed = direction;
if (!Pause.isPaused)
{
// Get Start Position
if (Input.GetMouseButtonDown(0))
{
// Instansiate The Trajectory
for (int i = 0; i < numbersOfTrajectory; i++)
{
trajectoryDots[i] = Instantiate(trajectoryDot,gameObject.transform.position, gameObject.transform.rotation);
}
}
// Get Position When Dragging
if (Input.GetMouseButton(0))
{
EnableSlowMotion();
// Get Drag Position
endPos = Camera.main.ScreenToWorldPoint(Input.mousePosition) + new Vector3(0, 0, 10);
startPos = gameObject.transform.position;
// Get The Speed
direction = endPos - startPos;
direction = direction.normalized;
direction = Vector3.Lerp(transform.position, direction, 500 * Time.deltaTime);
direction = direction * 18;
// Update The Trajectory Position
for (int i = 0; i < numbersOfTrajectory; i++)
{
trajectoryDots[i].transform.position = calculatePosition(i * trajectoryDotsDistance);
}
}
// Get Position When Realeasing
if (Input.GetMouseButtonUp(0))
{
DisableSlowMotion();
// enable Gravity
rb.gravityScale = 1f;
// Move The Player
rb.velocity = new Vector2(direction.x * speedMultiplier, direction.y * speedMultiplier);
// Destroy The Trajectory When Player Release
for (int i = 0; i < numbersOfTrajectory; i++)
{
Destroy(trajectoryDots[i]);
}
}
}
CameraZoom();
ControlsChecker();
}
// Calculate The Trajectory Prediction
Vector2 calculatePosition(float elapsedTime)
{
return new Vector2(startPos.x, startPos.y) +
new Vector2(anotherSpeed.x * speedMultiplier, anotherSpeed.y * speedMultiplier) * elapsedTime +
0.5f * Physics2D.gravity * elapsedTime * elapsedTime;
}
// Check Controls Is pull or push
void ControlsChecker()
{
if (PlayerPrefs.GetInt("Controls") == 1)
{
direction = direction;
anotherSpeed = anotherSpeed;
}
else
{
direction = -direction;
anotherSpeed = -anotherSpeed;
}
}
void EnableSlowMotion()
{
Time.timeScale = slowDownFactor;
Time.fixedDeltaTime = 0.02f * Time.timeScale;
}
void DisableSlowMotion()
{
Time.timeScale = 1f;
Time.fixedDeltaTime = 0.02F;
}
}
void CameraZoom()
{
if (Input.GetMouseButton(0))
{
vcam.m_Lens.OrthographicSize += 0.1f;
if (vcam.m_Lens.OrthographicSize >= maxZoom)
{
vcam.m_Lens.OrthographicSize = maxZoom;
}
}
else if (Input.GetMouseButtonUp(0))
{
zoomIn = true;
}
if (zoomIn)
{
vcam.m_Lens.OrthographicSize -= 0.2f;
if (vcam.m_Lens.OrthographicSize <= minZoom)
{
vcam.m_Lens.OrthographicSize = minZoom;
zoomIn = false;
}
}
}
so I get the player's movement direction from the calculation based on the point where I touch and the point when I release touch (dragging). Did I make a mistake in the code that caused my trajectory to vibrate often? I really need help here, thanks in advance.
I have two problems with implementing two Virtual Joysticks in Unity 5: one for player movement (grey color) and the second for camera (orange color) please see the following screenshot:
My problems:
For the Virtual Joystick responsible for player movement, the player object does not rotate in the same direction the Joystick is pressed , it's moving in all directions but not facing the same direction that the Joystick is pressed.
The camera can see through the terrain/ground. How do I prevent that?
The script I'm using from Virtual Joystick :
using UnityEngine; using System.Collections; using UnityEngine.UI; using UnityEngine.EventSystems;
public class VirtualJoystick : MonoBehaviour,IDragHandler,IPointerUpHandler,IPointerDownHandler {
private Image bgImg;
private Image joystickImg;
public Vector3 InputDirection{ set; get;}
// Use this for initialization
void Start () {
bgImg = GetComponent<Image> ();
joystickImg = transform.GetChild (0).GetComponent<Image> ();
InputDirection = Vector3.zero;
}
// Update is called once per frame
//void Update () {
//}
public virtual void OnDrag(PointerEventData ped)
{
Vector2 pos = Vector2.zero;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle
(bgImg.rectTransform,
ped.position,
ped.pressEventCamera,
out pos)) {
pos.x=(pos.x/bgImg.rectTransform.sizeDelta.x);
pos.y=(pos.y/bgImg.rectTransform.sizeDelta.y);
float x=(bgImg.rectTransform.pivot.x==1) ? pos.x*2+1 : pos.x*2-1;
float y=(bgImg.rectTransform.pivot.y==1) ? pos.y*2+1 : pos.y*2-1;
InputDirection=new Vector3(x,0,y);
InputDirection=(InputDirection.magnitude>1) ? InputDirection.normalized : InputDirection;
joystickImg.rectTransform.anchoredPosition=
new Vector3(InputDirection.x*(bgImg.rectTransform.sizeDelta.x/3),InputDirection.z*(bgImg.rectTransform.sizeDelta.y/3));
Debug.Log(InputDirection);
}
}
public virtual void OnPointerDown(PointerEventData ped)
{
OnDrag (ped);
}
public virtual void OnPointerUp(PointerEventData ped)
{
//Here is the problem it just goes to zero so fast so my character also moves so fast...how can i make it so motth
InputDirection =Vector3.zero;
joystickImg.rectTransform.anchoredPosition =Vector3.zero;
}
}
The script to move the player:
using UnityEngine; using System.Collections;
public class Motor : MonoBehaviour {
public float moveSpeed = 5.0f;
public float drag = 0.5f;
public float terminalRotationSpeed = 25.0f;
private Rigidbody controller;
private Transform camtransform;
public VirtualJoystick movejoystick;
private void Start()
{
controller =GetComponent<Rigidbody>();
controller.maxAngularVelocity = terminalRotationSpeed;
controller.drag = drag;
camtransform = Camera.main.transform;
}
private void Update ()
{
Vector3 dir = Vector3.zero;
dir.x = Input.GetAxis ("Horizontal");
dir.z = Input.GetAxis ("Vertical");
if (dir.magnitude > 1)
dir.Normalize ();
if (movejoystick.InputDirection != Vector3.zero) {
dir = movejoystick.InputDirection;
}
Vector3 rotatedDir = camtransform.TransformDirection (dir);
rotatedDir = new Vector3 (rotatedDir.x, 0, rotatedDir.z);
rotatedDir = rotatedDir.normalized * dir.magnitude;
controller.AddForce (dir * moveSpeed);
Quaternion eulerRot = Quaternion.Euler(0.0f, 0.0f, rotatedDir.x);
transform.rotation = Quaternion.Slerp(transform.rotation, eulerRot, Time.deltaTime * 10);
}
}
The script I'm using for the camera:
using UnityEngine;
using System.Collections;
public class FreeCamera :
MonoBehaviour {
public Transform lookAt;
public VirtualJoystick camerajs;
private float distance = 200.0f;
private float currentx = 0.0f;
private float currenty = 0.0f;
private float sensitivityx = 1.0f;
private float sensitivityy = 1.0f;
private void Update()
{
currentx += camerajs.InputDirection.x * sensitivityx;
currenty += camerajs.InputDirection.z * sensitivityy;
}
private void LateUpdate()
{
Vector3 dir = new Vector3(0, 0, -distance);
Quaternion rotation = Quaternion.Euler(currenty, currentx, 0);
transform.position = lookAt.position + rotation * dir;
transform.LookAt(lookAt);
}
}
more screenshots :
For question 1:
The code below first turns according to joystick-x direction and then move forward/backward according to joystick-y. In Motor.Update:
private void Update ()
{
Vector3 dir = Vector3.zero;
dir.x = Input.GetAxis ("Horizontal");
dir.z = Input.GetAxis ("Vertical");
if (dir.magnitude > 1)
dir.Normalize ();
if (movejoystick.InputDirection != Vector3.zero) {
dir = movejoystick.InputDirection;
}
Vector3 rotatedDir = transform.TransformDirection (dir); // world direction of joystick direction
Vector3 newDir = Vector3.RotateTowards(transform.forward, rotatedDir, Time.deltaTime * 10f, 0.0F); // turn towards joystick direction
transform.rotation = Quaternion.LookRotation(newDir); // set the new direction
controller.AddForce (transform.forward * moveSpeed * dir.z); // scale force by joystick up/down
}
I am using a map bigger than the screen I viewing. Therefore I need to be able to pan around that map. I am having a problem with clamping the camera and the map. I want to be able to use the demension of the image as the width and height of the clamp. The problem is the units.
The image is 2144 x 1708
The camera transposition is in single digits (14 x 7) or something like that.
All of the code I am using is below.
private Vector3 mouseOrigin; // Position of cursor when mouse dragging starts
private bool isPanning; // Is the camera being panned?
public bool useBoundary = true;
public Vector2 boundaryMin;
public Vector2 boundaryMax;
public Image map;
private void Start()
{
Camera cam = Camera.main;
float mapRatio = map.rectTransform.rect.width / map.rectTransform.rect.height;
float mapScreenHeight = (1.5f * cam.orthographicSize);
float mapScreenWidth = (3f * mapScreenHeight) * cam.aspect;
boundaryMin = new Vector2(0, 1);
boundaryMax = new Vector2(map.rectTransform.rect.width, map.rectTransform.rect.height);
}
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
mouseOrigin = Input.mousePosition;
isPanning = true;
}
// Disable movements on button release
if (!Input.GetMouseButton(0))
isPanning = false;
if (isPanning)
{
Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition - mouseOrigin);
Vector3 move = new Vector3(pos.x * panSpeed, pos.y * panSpeed, 0);
transform.Translate(move, Space.Self);
BoundaryCheck();
}
}
private void BoundaryCheck()
{
if (!useBoundary)
return;
Vector3 newPos = transform.position;
newPos.x = Mathf.Clamp(newPos.x, boundaryMin.x, boundaryMax.x);
newPos.y = Mathf.Clamp(newPos.y, boundaryMin.y, boundaryMax.y);
transform.position = newPos;
}
}
Any help would be greatly appreciated.
You can do this using Unity UI - Scroll Rect.
Check out Unity UI - Scroll Rect - Introduction
In my opinion you should need to use below script for camera panning, zooming and rotating. You can off any undesirable function. Now according to your question you have to restrict the movement(according to your image border). simply you can restrict the camera movements on differet axis according to your limitations. You should place cubes into the borders of the map and use their positions as the limit of camera movement and panning etc.
using UnityEngine;
using System.Collections;
public class CamMovementManager : MonoBehaviour
{
#region Vars
public float turnSpeed = 1.0f; // Speed of camera turning when mouse moves in along an axis
public float panSpeed = 4.0f; // Speed of the camera when being panned
public float zoomSpeed = 4.0f; // Speed of the camera going back and forth
private Vector3 mouseOrigin; // Position of cursor when mouse dragging starts
private bool isPanning; // Is the camera being panned?
private bool isRotating; // Is the camera being rotated?
private bool isZooming; // Is the camera zooming?
private float pannPosLimit = 300f;
private int fovMin = 15;
private int fovMax = 90;
#endregion Vars
#region UnityEvents
void Update()
{
// Get the left mouse button
if (Input.GetMouseButtonDown(0))
{
// Get mouse origin
mouseOrigin = Input.mousePosition;
isRotating = true;
}
// Get the right mouse button
if (Input.GetMouseButtonDown(1))
{
// Get mouse origin
mouseOrigin = Input.mousePosition;
isPanning = true;
}
// Get the middle mouse button
if (Input.GetMouseButtonDown(2))
{
// Get mouse origin
//mouseOrigin = Input.mousePosition;
//isZooming = true;
}
//changing fov on mouse scroll to zoomIn/out
float fov = Camera.main.fieldOfView;
fov += Input.GetAxis("Mouse ScrollWheel") * 10f;
fov = Mathf.Clamp(fov, fovMin, fovMax);
Camera.main.fieldOfView = fov;//*/
// Disable movements on button release
if (!Input.GetMouseButton(0)) isRotating = false;
if (!Input.GetMouseButton(1)) isPanning = false;
if (!Input.GetMouseButton(2)) isZooming = false;
// Rotate camera along X and Y axis
if (isRotating)
{
Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition - mouseOrigin);
//Debug.Log("rotate pos : " + pos);
transform.RotateAround(transform.position, transform.right, -pos.y * turnSpeed);
transform.RotateAround(transform.position, Vector3.up, pos.x * turnSpeed);
}
// Move the camera on it's XY plane
if (isPanning)
{
if (Input.mousePosition.y > pannPosLimit)
{
Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition - mouseOrigin);
Vector3 move = new Vector3(pos.x * panSpeed, pos.y * panSpeed, 0);
transform.Translate(move, Space.Self);
}
}
// Move the camera linearly along Z axis
if (isZooming)
{
Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition - mouseOrigin);
Vector3 move = pos.y * zoomSpeed * transform.forward;
transform.Translate(move, Space.World);
}
}
#endregion
#region CustomMethods
public void CamRotating()
{
Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition - mouseOrigin);
transform.RotateAround(transform.position, transform.right, -pos.y * turnSpeed);
transform.RotateAround(transform.position, Vector3.up, pos.x * turnSpeed);
}
public void CamPanning()
{
Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition - mouseOrigin);
Vector3 move = new Vector3(pos.x * panSpeed, pos.y * panSpeed, 0);
transform.Translate(move, Space.Self);
}
public void CamZooming()
{
Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition - mouseOrigin);
Vector3 move = pos.y * zoomSpeed * transform.forward;
transform.Translate(move, Space.World);
}
#endregion CustomMethods
}
I want control the transform with mouse just for Y axis as it is moving on X axis by it self.
I use Vector2.MoveTowards to move it on X axis.
The transform must be moved by any touch and drag on the screen. So I wrote my codes in the Update function
My Codes :
using UnityEngine;
using System.Collections;
public class PlayerMovement : MonoBehaviour
{
public Camera playerCamera;
public float speed = 12.0F;
private Vector3 moveDirection = Vector3.zero,Point,last;
void Start()
{
Point = transform.position;
last = transform.position;
if (playerCamera == null)
{
playerCamera = Camera.main;
}
playerCamera.transparencySortMode = TransparencySortMode.Orthographic;
}
void Update(){
if(Input.GetMouseButtonUp(0))
Point = last;
moveDirection.x = transform.position.x+speed;
moveDirection.y = transform.position.y;
if (Input.GetMouseButtonDown(0)) {
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
last = ray.GetPoint (0);
transform.position = new Vector2 (transform.position.x, last.y - Point.y);
}
else
transform.position = Vector2.MoveTowards( transform.position,moveDirection,speed*Time.deltaTime);
//moveDirection.y -= 20.0f * Time.smoothDeltaTime;
//After we move, adjust the camera to follow the player
playerCamera.transform.position = new Vector3(transform.position.x, playerCamera.transform.position.y , playerCamera.transform.position.z);
}
}
How can I solve it?