I am new to game development, i am trying to to change my code to mobile touch. I tried to change the flowing code to make workable for mobile touchscreen unfortunately failed. can you help me how can I make flowing code for mobile?
Here is the code.
Vector2 newPos;
bool canMove = true;
private void Start()
{
rb = GetComponent<Rigidbody2D>();
newPos = transform.position;
}
private void Update()
{
if (canMove)
{
if (Input.GetKeyDown(KeyCode.RightArrow))
{
newPos.x += 1.4f;
transform.position = newPos;
}
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
newPos.x -= 1.4f;
transform.position = newPos;
}
}
if (Input.GetKeyDown(KeyCode.Space) && canMove)
{
rb.AddForce(Vector3.down * speed);
canMove = false;
}
Vector2 clampPos = transform.position;
clampPos.x = Mathf.Clamp(transform.position.x, -2.1f, 2.1f);
transform.position = clampPos;
}
Create a Canvas with a screen wide transparent Image component inside.
Use OnPointerDown and OnDrag event functions to catch finger movement on this image. Just make your class implement IPointerDownHandler and IDragHandler interfaces and use PointerEventData args properties to get delta or current position.
You can use the code below. Add it to the screen wide image and assign your Ridigbody2d and transform in inspector.
public class Movement: MonoBehaviour, IPointerDownHandler, IDragHandler
{
public Rigidbody2d rb;
public float maxSpeed = 10f;
public float sensitivity = 0.1f;
public float xBound = 2.1f;
Vector3 initialFingerPosition;
bool canMove = true;
public void OnPointerDown(PointerEventData pointerEventData)
{
initialFingerPosition = pointerEventData.position;
}
public void OnDrag(PointerEventData data)
{
if(!canMove)
return;
var position = rb.position;
position += data.delta * sensitivity * speed * Time.deltaTime;
position.x = Mathf.Clamp(position.x, -xBound, xBound);
rb.MovePosition(position);
}
}
Related
I've been trying to figure this out for the past few hours and I figure there must be something off about my code making this extra difficult. I'm trying to make a first-person controller with the new input system and stop the camera from going 360 degrees vertically. I have the horizontal rotation applied to the player and the vertical rotation applied to a camera that is a child of said player. This is what I got sorry if it's a CF.
I've Tried Mathf.clamp and euler angles but I can't seem to get anything to work.
using UnityEngine;
using UnityEngine.InputSystem;
public class FirstPersonController : MonoBehaviour
{
public AICOde PlayerControls;
Vector2 moveDirection = Vector2.zero;
public Vector3 jumpForce;
float hlookDirection;
float vlookDirection;
public float isJumping;
public InputAction move;
public InputAction jump;
public InputAction look;
public Rigidbody rb;
public bool isOnGround;
public float moveSpeed;
public float sensitivity;
public Camera playerCamera;
public Quaternion cameraRotation;
private void Awake()
{
PlayerControls = new AICOde();
}
private void Start()
{
playerCamera = gameObject.GetComponentInChildren<Camera>();
Cursor.lockState = CursorLockMode.Locked;
}
private void OnEnable()
{
jump = PlayerControls.Player.Jump;
move = PlayerControls.Player.Move;
look = PlayerControls.Player.Look;
move.Enable();
jump.Enable();
look.Enable();
}
private void OnDisable()
{
move.Disable();
jump.Disable();
look.Disable();
}
private void Update()
{
cameraRotation = playerCamera.transform.rotation;
hlookDirection = look.ReadValue<Vector2>().x;
vlookDirection = look.ReadValue<Vector2>().y;
moveDirection = move.ReadValue<Vector2>();
isJumping = jump.ReadValue<float>();
}
private void FixedUpdate()
{
//MOVE PLAYER
rb.velocity = transform.TransformDirection (new Vector3(moveDirection.x * moveSpeed, rb.velocity.y, moveDirection.y * moveSpeed));
//ROTATE PLAYER WITH MOUSE
gameObject.transform.Rotate(Vector3.up, hlookDirection * sensitivity * Time.deltaTime );
//ROTATE CAMERA WITH MOUSE
playerCamera.transform.Rotate(Vector3.left,vlookDirection * sensitivity * Time.deltaTime);
//JUMP
if (isJumping > 0 && isOnGround == true)
{
rb.AddForce(jumpForce, ForceMode.Impulse);
}
if (isJumping > 0)
{
isOnGround = false;
}
if (isOnGround)
{
moveSpeed = 5f;
}
else
{
moveSpeed = 4f;
}
}
//MAKE SURE PLAYER IS ON GROUND BEFORE JUMPING
private void OnCollisionEnter(Collision collision)
{
if(collision.collider.CompareTag("Ground"))
{
isOnGround = true;
}
else
{
isOnGround = false;
}
}
}
You could track how much you have rotated up or down already. Define a float currentUpDownAngle = 0f; in your FirstPersonController. Then, instead of
//ROTATE CAMERA WITH MOUSE
playerCamera.transform.Rotate(Vector3.left,vlookDirection * sensitivity * Time.deltaTime);
you do
//ROTATE CAMERA WITH MOUSE
float MAX_UPDOWN_ANGLE = 60f; // define a limit (maybe somewhere else)
float change = vlookDirection * sensitivity * Time.deltaTime; // get the wanted change
// check if the change would exceed the maximum, we do it for both directions at once
// if you want another minimum angle, divide the code in two parts
if (Mathf.Abs(currentUpDownAngle + change) > MAX_UPDOWN_ANGLE) { // do we exceed?
float limit = Mathf.Sign(change) * MAX_UPDOWN_ANGLE; // get up or down limit
change = limit - currentUpDownAngle; // get the rest to limit
currentUpDownAngle = limit; // snap to the limit
}
else {
currentUpDownAngle += change; // no limit hit, free change
}
// rotates at most to the limit
playerCamera.transform.Rotate(Vector3.left, change);
I am making a 2D game in Unity. So I used trasform.position += movePos type code to move my player when specific key pressed. I also made some animations. Player is not moving still animation is performing. Everything was working fine before I made the jump animation. But now it isn't working. Can someone suggest me what to do. I hadn't made a repository of code in github so I can't share it.
Here you can watch video what is happening:- https://1drv.ms/v/s!AnUoIDNJEoVSmQylzexBqmA1i8Ur?e=4FhJ5h
and here is my player controls code which is responsible for controls:-
using System.Collections;
using UnityEngine;
public class PlayerControls : MonoBehaviour
{
#region variables
// Private variables
private float speed = 15f;
[SerializeField]
private bool isOnGround;
private Quaternion leftMoveRotate = new Quaternion(0f, 180f, 0f, 1f);
private Quaternion rightMoveRotate = new Quaternion(0f, 0f, 0f, 1f);
// Public Variables
public Animator playerAnimator;
#endregion
private void OnTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("ground"))
{
isOnGround = true;
}
}
private void Update()
{
float horizontalInput = Input.GetAxis("Horizontal");
if (horizontalInput > 0)
{
DInput();
}
if (horizontalInput < 0)
{
AInput();
}
playerAnimator.SetFloat("isRunning", Mathf.Abs(horizontalInput));
if (Input.GetKeyDown(KeyCode.Space) || Input.GetKeyDown(KeyCode.LeftShift))
{
Jump();
}
}
private void Jump()
{
if (isOnGround)
{
transform.position += new Vector3(0f, 4f, 0f); // Jump code
isOnGround = false;
}
}
private void DInput()
{
transform.rotation = rightMoveRotate;
transform.position += new Vector3(0.5f, 0f, 0f) * speed * Time.fixedDeltaTime;
}
private void AInput()
{
transform.rotation = leftMoveRotate;
transform.position -= new Vector3(0.5f, 0f, 0f) * speed * Time.fixedDeltaTime;
}
}
I also have a code of camera following the player and here is that:-
using UnityEngine;
public class CameraFollow : MonoBehaviour
{
public Transform player;
public float offSetX = 5f;
public float offSetY = 2.5f;
private void FixedUpdate() {
Vector3 tempPos = transform.position;
tempPos.x = player.position.x;
tempPos.x += offSetX;
tempPos.y = player.position.y;
tempPos.y += offSetY;
transform.position = tempPos;
}
}
and if I remove jump animation from Animator all control works fine. Here is video you can check:-
https://1drv.ms/v/s!AnUoIDNJEoVSmQ2k_o7Fbs0J5_8d?e=tJlayZ
One thing you might have messed up and is not showing in script, is you recorded transform position change in your animation and animation is messing with position.
Camera rotate by mouse input, How to rotate the move to the default position?
public class CameraOrbit : MonoBehaviour
{
public float turnSpeed = 1.0f;
public Transform player;
private Vector3 offset;
private void Start()
{
offset = new Vector3(0, 2.5f, -5);
}
private void LateUpdate()
{
if (Input.GetMouseButton(0))
{
offset = Quaternion.AngleAxis(Input.GetAxis("Mouse X") * turnSpeed, Vector3.up) * offset;
transform.localPosition = offset;
transform.LookAt(player.position);
}
}
}
This kind of thing moves directly into position and I want to smooth it over.
public void RevertCamera()
{
offset = new Vector3(0, 2.5f, -5);
transform.localPosition = offset;
transform.LookAt(player.position);
}
I have tried multiple variations of this, but none of them seem to work.
the easiest way is to use the camera's transform's RotateAround(...) method:
void LateUpdate
{
if(Input.GetMouseDown(0))
{
float delta = Input.GetAxis("Mouse X") * turnSpeed;
transform.RotateAround(player.position, Vector3.up, delta);
}
}
(taken from: https://docs.unity3d.com/ScriptReference/Transform.RotateAround.html)
Suggestion: I usually set up a camera rig, if I want to control camera movement focused on a certain target.
Though this might be overengineered for a simple RotateAround call.
If you want to achieve smooth transitions. I would advise you to use Slerp on the Quaternion and interpolate between your 2 rotation points.
Slerp Example:
// Interpolates rotation between the rotations "from" and "to"
// (Choose from and to not to be the same as
// the object you attach this script to)
using UnityEngine;
using System.Collections;
public class SlerpExample: MonoBehaviour {
[SerializeField]private Transform from;
[SerializeField]private Transform player;
private bool revertCamera = false;
private float timeCount = 0.0f;
private void Update() {
timeCount = timeCount + Time.deltaTime;
if (revertCamera) {
timeCount = 0.0f;
transform.rotation = Quaternion
.Slerp(from.rotation, player.rotation, timeCount);
if (transform.rotation == player.rotation) {
reverCamera = false;
}
}
}
private void RevertCamera() {
revertCamera = true;
}
}
Slerp
I created an 3dobject and set a game object as target, and added the below code to main camera. I am able to zoom into the 3d object, but im not able to zoom out of it. How to zoom out? i.e to go back to original position.
using System.Collections;
using UnityEngine;
public class zoo22 : MonoBehaviour
{
public float movespeed = 35.0f;
//you need to say how far from the object the camera will stop
public float minimumDistanceFromTarget = 5f;
public GameObject targetobject;
private bool movingtowardstarget = false;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(1))
{
if (movingtowardstarget == true)
{
movingtowardstarget = false;
}
else
{
movingtowardstarget = true;
}
}
if (movingtowardstarget)
{
movetowardstarget(targetobject);
}
}
public void movetowardstarget(GameObject target)
{
if(Vector3.Distance(transform.position, target.transform.position) > minimumDistanceFromTarget) //we move only if we are further than the minimum distance
{
transform.position = Vector3.MoveTowards(transform.position, target.transform.position, movespeed * Time.deltaTime);
} else //otherwise, we stop moving
{
movingtowardstarget = false;
}
}
}
I not got your movingtoward bool but you can handle your zoom easy.
First rotate your camera to look at your object and later apply zoom:
For example to zoom whith the mouse Wheel in a ortho camera you need to handle orthographicSize:
int orthographicSizeMin = 1;
int orthographicSizeMax = 6;
function Update()
{
transform.LookAt(target);
if (Input.GetAxis("Mouse ScrollWheel") > 0) // forward
{
Camera.main.orthographicSize++;
}
if (Input.GetAxis("Mouse ScrollWheel") < 0) // back
{
Camera.main.orthographicSize--;
}
}
Camera.main.orthographicSize = Mathf.Clamp(Camera.main.orthographicSize, orthographicSizeMin, orthographicSizeMax );
For a perspective camera you need to handle field of view:
float minFov = 10f;
float maxFov = 90f;
float sensitivity = 10f;
function Update()
{
transform.LookAt(target);
float fov = Camera.main.fieldOfView;
fov += Input.GetAxis("Mouse ScrollWheel") * sensitivity;
fov = Mathf.Clamp(fov, minFov, maxFov);
Camera.main.fieldOfView = fov;
}
Easiest way imo:
Add object for original position as well:
public GameObject targetobject, originalPosObj;
Then pass it as target:
movetowardstarget(movingtowardstarget ? targetObject : originalPosObj);
you can use the same function to zoom in and zoom out. please check the example below. Enter negative velocity to move backwards.
void Update()
{
if (Input.GetMouseButtonDown(1)) //move backward
movetowardstarget(targetobject, true);
if (Input.GetMouseButtonDown(0)) //move forward
movetowardstarget(targetobject, false);
}
public void movetowardstarget(GameObject target, bool backwards)
{
float dir = backwards?-1.0f:1.0f;
actualDist = Vector3.Distance(transform.position, target.transform.position);
if (Vector3.Distance(transform.position, target.transform.position) > minimumDistanceFromTarget) //we move only if we are further than the minimum distance
{
transform.position = Vector3.MoveTowards(transform.position, target.transform.position, dir*movespeed * Time.deltaTime);
}
else //otherwise, we stop moving
{
movingtowardstarget = false;
}
}
I imagine you will want to do this will the Mouse Wheel.
public class CameraConrol : MonoBehaviour
{
Vector3 centerPosition;//positon of object you want to zoom in and out of
float MaxZoom = 3f;
void Update()
{
//mouse wheel chaned
if (Input.mouseScrollDelta.y !=0)
{
ZoomCamera();
}
}
public void ZoomCamera()
{
Vector3 newPosition = Vector3.MoveTowards(
transform.position, centerPosition, Input.mouseScrollDelta.y);
if(newPosition.y >= (centerPosition.y + MaxZoom ))
{
transform.position = newPosition;
}
}
}
I am messing around in Unity and wanted to make a mechanic where a box would touch another object and then that object would follow the Player.
I have Cube set up like this:
And a Sphere with a Box Collider with same options.
My Player script is thus:
public class Player : MonoBehaviour {
public float speed = 0.0f;
public float moveX = 0.0f;
public float moveY = 0.0f;
public GameObject player;
public GameObject obj;
//public float force = 0.0f;
private bool collided = false;
// Use this for initialization
void Start () {
player = GameObject.FindWithTag ("Player");
}
// Update is called once per frame
void FixedUpdate () {
moveX = Input.GetAxis ("Horizontal");
moveY = Input.GetAxis ("Vertical");
player.GetComponent<Rigidbody> ().velocity = new Vector2 (moveX * speed, moveY * speed);
}
void OnCollisionEnter (Collision col) {
if (col.gameObject == obj) {
collided = true;
}
}
void OnCollisionExit (Collision col) {
if (col.gameObject == obj) {
collided = false;
}
}
void Update () {
if(collided) {
obj.transform.position = (player.transform.position - obj.transform.position)*speed;
}
}
}
What have I yet to do? Hoping someone can nudge me in the right direction.
I will provide you two scripts.
1st Script is FollowTarget. This will follow your target forcely.
2nd Script is SmoothFollow which will follow your target in a smooth movement.
FollowTarget.cs
using System;
using UnityEngine;
public class FollowTarget : MonoBehaviour
{
public Transform target;
public Vector3 offset = new Vector3(0f, 7.5f, 0f);
private void LateUpdate()
{
transform.position = target.position + offset;
}
}
SmoothFollow.cs
using UnityEngine;
public class SmoothFollow : MonoBehaviour
{
// The target we are following
[SerializeField]
private Transform target;
// The distance in the x-z plane to the target
[SerializeField]
private float distance = 10.0f;
// the height we want the camera to be above the target
[SerializeField]
private float height = 5.0f;
[SerializeField]
private float rotationDamping;
[SerializeField]
private float heightDamping;
// Use this for initialization
void Start() { }
// Update is called once per frame
void LateUpdate()
{
// Early out if we don't have a target
if (!target)
return;
// Calculate the current rotation angles
var wantedRotationAngle = target.eulerAngles.y;
var wantedHeight = target.position.y + height;
var currentRotationAngle = transform.eulerAngles.y;
var currentHeight = transform.position.y;
// Damp the rotation around the y-axis
currentRotationAngle = Mathf.LerpAngle(currentRotationAngle, wantedRotationAngle, rotationDamping * Time.deltaTime);
// Damp the height
currentHeight = Mathf.Lerp(currentHeight, wantedHeight, heightDamping * Time.deltaTime);
// Convert the angle into a rotation
var currentRotation = Quaternion.Euler(0, currentRotationAngle, 0);
// Set the position of the camera on the x-z plane to:
// distance meters behind the target
transform.position = target.position;
transform.position -= currentRotation * Vector3.forward * distance;
// Set the height of the camera
transform.position = new Vector3(transform.position.x ,currentHeight , transform.position.z);
// Always look at the target
transform.LookAt(target);
}
}
Just choose one of them and then attach it to the gameObject. Like another box that is suppose to follow.
Remove your Update() function in your script as you don't need it anymore.
Also Remove your OnCollisionExit()
void OnCollisionEnter (Collision col) {
if (col.gameObject == obj) {
// If you choose to use SmoothFollow Uncomment this.
//col.GetComponent<SmoothFollow>().target = this.transform;
// If you choose to use FollowTarget Uncomment this
//col.GetComponent<FollowTarget>().target = this.transform;
}
}