I am trying to move an airplane yoke in the vertical axis. I am using the mouse pointer to move yoke in vertical axis up and down and clamped the value. When I run the script the yoke is positioned some ever and not moving up and down. The yoke is not moving up and down. How to move yoke up and down as shown in the image using below code.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace plane
{
public class IP_AirplaneThrottle_Physical : MonoBehaviour
{
#region Variables
public float maxZOffset = -0.5f;
public float sensitivity = 0.001f;
public float smoothSpeed = 8f;
public bool isHitting = false;
public float wantedDelta;
private Vector3 startPos;
private Vector3 wantedPos;
private Vector2 lastMousePosition;
#endregion
#region Builtin Methods
// Use this for initialization
void Start()
{
//Get the lever starting position
startPos = transform.position;
}
// Update is called once per frame
void Update()
{
HandleRaycast();
HandleInteraction();
}
#endregion
#region Custom Methods
void HandleRaycast()
{
//Build a ray so we can see if we are hitting the lever
Ray curRay = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
//Do our Raycast into the scene
if(Physics.Raycast(curRay, out hit, 1000f))
{
if(hit.transform.GetInstanceID() == this.transform.GetInstanceID())
{
Debug.Log("Hitting the Lever!");
if(Input.GetMouseButtonDown(0))
{
//We are hitting so get the start mouse position
isHitting = true;
lastMousePosition = Input.mousePosition;
print ("123");
}
}
}
//If we let go of the left mouse button then stop everything
if(isHitting && Input.GetMouseButton(0) == false)
{
isHitting = false;
}
}
void HandleInteraction()
{
if(isHitting)
{
//Calculate the delta for Z offset
wantedDelta = (lastMousePosition.y - Input.mousePosition.y) * Time.deltaTime * sensitivity;
startPos.z += wantedDelta;
//make sure we dont go to far
startPos.z = Mathf.Clamp(startPos.z, maxZOffset, 0f);
wantedPos = startPos;
//Get the New Mouse Position every frame while we are holding
lastMousePosition = Input.mousePosition;
}
else
{
//Clear out the Delta value
wantedDelta = 0f;
}
//Move the lever
transform.position = Vector3.Lerp(transform.position, wantedPos, Time.deltaTime * smoothSpeed);
}
#endregion
}
}
Related
Have tried a few things but they didn't seem to work, so I was hoping that you guys could help me.
I've trying to make this demo for a little time now, but I can't seem to get the jumping to work.
When I try to jump while running, I can't. But I can however jump forever when i get up in the air, which is something that I would like to remove from the game.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class movement : MonoBehaviour
{
Rigidbody2D rb2d;
public float moveVelocity = 8f;
public float jumpVelocity = 15f;
public float fallMultiplier = 2.5f;
public float lowJumpMultiplier = 2f;
public const string RIGHT = "right";
public const string LEFT = "left";
public const string UP = "up";
string buttonPressed;
void Start()
{
rb2d = GetComponent<Rigidbody2D>();
}
void Update()
{
if (rb2d.velocity.y < 0)
{
rb2d.velocity += Vector2.up * Physics2D.gravity.y * (fallMultiplier - 1) *
Time.deltaTime;
}
else if (rb2d.velocity.y > 0 && !Input.GetButton ("Jump"))
{
rb2d.velocity += Vector2.up * Physics2D.gravity.y * (lowJumpMultiplier - 1) *
Time.deltaTime;
}
if (Input.GetKey(KeyCode.RightArrow))
{
buttonPressed = RIGHT;
}
else if (Input.GetKey(KeyCode.LeftArrow))
{
buttonPressed = LEFT;
}
else if (Input.GetKey(KeyCode.UpArrow))
{
buttonPressed = UP;
}
else
{
buttonPressed = null;
}
}
private void FixedUpdate()
{
if (buttonPressed == RIGHT)
{
rb2d.velocity = new Vector2(moveVelocity, rb2d.velocity.y);
}
else if (buttonPressed == LEFT)
{
rb2d.velocity = new Vector2(-moveVelocity, rb2d.velocity.y);
}
else if (buttonPressed == UP)
{
rb2d.velocity = Vector2.up * jumpVelocity;
}
else
{
rb2d.velocity = new Vector2(0, rb2d.velocity.y);
}
}
}
I am not sure why you are trying to control the gravity of the player when gravity is already applied to any gameObject with the RigidBody or RigidBody2D component attached to it. It is good that you are reading input in the Update() function and applying the motion inside of the FixedUpdate(). Here is a slight tweak to your current code, let me know how this goes.
Rigidbody2D rb2d;
public float moveVelocity = 8f;
public float jumpVelocity = 15f;
private float horizontalInput = 0.0f;
// did the player just try to jump
private bool justJumped = false;
void Start()
{
rb2d = GetComponent<Rigidbody2D>();
}
void Update()
{
// grab how the player is moving - this value is mapped to your arrow keys
// so horizontal is left / right arrow and Vertical is up/down arrow
// the value is between [-1, 1] respectively
horizontalInput = Input.GetAxis("Horizontal");
// player tried to jump, we are not currently jumping and the player is grounded
if(IsGrounded() && Input.GetKeyDown(KeyCode.UpArrow))
{
justJumped = true;
}
}
private void FixedUpdate()
{
// handle our jump
if(justJumped)
{
// we just applied a jump so do not apply it again
justJumped = false;
// you can either apply the jump by setting velocity, but I would recommend using AddForce instead
rb2d.AddForce(Vector2.up * jumpVelocity);
}
// we are moving in either the left or right direction
if(horizontalInput != 0)
{
// move in the horizontal axis, but keep our Y component of velocity the same in case we jumped
rb2d.velocity = new Vector2 (horizontalInput * moveVelocity, rigidBody.velocity.y);
}
else
{
// just in case we are not moving, assure this by setting the horizontal component of velocity to 0
rb2d.velocity = new Vector2 (0f, rigidBody.velocity.y);
}
}
// determines if this object is currently touching another object that is marked as ground
private bool IsGrounded() {
// our current position (the player)
Vector2 position = transform.position;
// the direction we are going to aim the raycast (down as that is where the ground is)
Vector2 direction = Vector2.down;
// the ground should be close, so check it very close to the player
float distance = 1.0f;
// check if we hit anything that is on the layer of just ground - ignore all other layers
// IMPORTANT:: Make sure to make a Layer and set all of your ground to this layer
RaycastHit2D hit = Physics2D.Raycast(position, direction, distance, LayerMask.GetMask("GroundLayer"));
// we hit a ground collider, so we are grounded
if (hit.collider != null) {
return true;
}
return false;
}
Let me know if this works for you. I changed a few things around such as using GetAxis() instead of using the arrow keys as in Unity, these are the same. I also changed your jump to use an AddForce2D instead of setting velocity. The one addition was I added a IsGrounded() which will detect if whatever object this script is on (I assume it is on your player object) is near or touching objects below them that are marked as GroundLayer. If you have questions comment below.
I am creating a build in Unity 2019.4.12f1 and need to drag an object with Right Mouse button.
My C# skills are very limited, so far but i try.
This scripts is my attempt to be able to rotate a gameobject by holding right mouse button down and dragging ingame.
But it is wrong.
Can anyone help me correct it?ยด
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class mouseM : MonoBehaviour
{
bool dragging = false;
void Start()
{
if (Input.GetMouseButtonDown(1))
{
dragging = true;
}
}
void Update()
{
if (Input.GetMouseButtonDown(1))
{
yourOnMouseDownFunction();
dragging = true;
}
if (Input.GetMouseButtonUp(1))
{
yourOnMouseUpFunction();
dragging = false;
}
if (dragging)
{
yourOnMouseDragFunction();
}
}
}
I understood that You need to Drag Object in 3d World so Here is my Code just create new Script and attach to Object You Want to Drag it
Your Object that You need to Drag it should has a collider
using UnityEngine;
public class DragableObject : MonoBehaviour
{
private Vector3 mOffset;
private float mZCoord;
private void OnMouseDrag()
{
transform.position = GetMouseWorldPos() + mOffset;
}
private void OnMouseDown()
{
mZCoord = Camera.main.WorldToScreenPoint(gameObject.transform.position).z;
mOffset = transform.position - GetMouseWorldPos();
}
private Vector3 GetMouseWorldPos()
{
Vector3 mosePoint = Input.mousePosition;
mosePoint.z = mZCoord;
var result = Camera.main.ScreenToWorldPoint(mosePoint);
return result;
}
}
you can try it by adding it to sphere or cube and if you use custom shape you should insure that the collider is in suitable size or has a meshcollier
Demo
EDIT
using UnityEngine;
public class DragableObject : MonoBehaviour
{
private bool isMouseDragging;
private Vector3 screenPosition;
private Vector3 offset;
private GameObject target;
GameObject ReturnClickedObject(out RaycastHit hit)
{
GameObject targetObject = null;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray.origin, ray.direction * 10, out hit))
{
targetObject = hit.collider.gameObject;
}
return targetObject;
}
void Update()
{
if (Input.GetMouseButtonDown(1))
{
RaycastHit hitInfo;
target = ReturnClickedObject(out hitInfo);
if (target != null)
{
isMouseDragging = true;
Debug.Log("our target position :" + target.transform.position);
//Here we Convert world position to screen position.
screenPosition = Camera.main.WorldToScreenPoint(target.transform.position);
offset = target.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPosition.z));
}
}
if (Input.GetMouseButtonUp(1))
{
isMouseDragging = false;
}
if (isMouseDragging)
{
//tracking mouse position.
Vector3 currentScreenSpace = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPosition.z);
//convert screen position to world position with offset changes.
Vector3 currentPosition = Camera.main.ScreenToWorldPoint(currentScreenSpace) + offset;
//It will update target gameobject's current postion.
target.transform.position = currentPosition;
}
}
}
You could try the Input.GetMouseButton method, this should return a value depending on if the button is held pressed.
This one works too, if someone needs in the future.
This is for rotate though.
Sorry, i dont know why it wont let me post as code, so i post an image.
enter image description here
I had my unity movement working on my computer, however when i try to play on my android it is not moving for me at all. I am sure it is probably a small error i am overlooking but i would be very appreciative of any help! I do not get any errors when i try yo run my code if that is of any assistance! I will supply the code below:
using UnityEngine;
using System.Collections;
//Adding this allows us to access members of the UI namespace including Text.
using UnityEngine.UI;
public class PlayerControler : MonoBehaviour {
public Text countText; //Store a reference to the UI Text component which will display the number of pickups collected.
//public Text winText; //Store a reference to the UI Text component which will display the 'You win' message.
private double count; //Integer to store the number of pickups collected so far.
//Player movement controls
private Vector3 touchPosition; //where your finger touches screen
private Vector3 direction; //direction you drag sprite
private Rigidbody2D rb2d; //Store a reference to the Rigidbody2D component required to use 2D Physics.
public float speed = 10f; //Floating point variable to store the player's movement speed.
// Use this for initialization
void Start()
{
//Get and store a reference to the Rigidbody2D component so that we can access it.
rb2d = GetComponent<Rigidbody2D> ();
//Initialize count to zero.
count = 0;
//Initialze winText to a blank string since we haven't won yet at beginning.
//winText.text = " "; //error here??
//Call our SetCountText function which will update the text with the current value for count.
//SetCountText ();
}
void Update()
{
if (Input.touchCount > 0)
{
Touch touch = Input.GetTouch(0);
touchPosition = Camera.main.ScreenToWorldPoint(touch.position);
touchPosition.z = 0;
direction = (touchPosition - transform.position);
rb2d.velocity = new Vector2(direction.x , direction.y) * speed;
if(touch.phase == TouchPhase.Ended)
{
rb2d.velocity = Vector2.zero;
}
}
}
//OnTriggerEnter2D is called whenever this object overlaps with a trigger collider.
void OnTriggerEnter2D(Collider2D other)
{
//Check the provided Collider2D parameter other to see if it is tagged "PickUp", if it is...
if (other.gameObject.CompareTag ("PickUp"))
{
//... then set the other object we just collided with to inactive.
other.gameObject.SetActive(false);
//Add one to the current value of our count variable.
count = count + 1;
//Update the currently displayed count by calling the SetCountText function.
//SetCountText ();
}
}
Here is my 2D Player Movement Controller.
Code(Character Controller) -
using UnityEngine;
using UnityEngine.Events;
public class CharacterController2D : MonoBehaviour
{
[SerializeField] private float m_JumpForce = 400f; // Amount of force added when the player jumps.
[Range(0, 1)] [SerializeField] private float m_CrouchSpeed = .36f; // Amount of maxSpeed applied to crouching movement. 1 = 100%
[Range(0, .3f)] [SerializeField] private float m_MovementSmoothing = .05f; // How much to smooth out the movement
[SerializeField] private bool m_AirControl = false; // Whether or not a player can steer while jumping;
[SerializeField] private LayerMask m_WhatIsGround; // A mask determining what is ground to the character
[SerializeField] private Transform m_GroundCheck; // A position marking where to check if the player is grounded.
[SerializeField] private Transform m_CeilingCheck; // A position marking where to check for ceilings
[SerializeField] private Collider2D m_CrouchDisableCollider; // A collider that will be disabled when crouching
const float k_GroundedRadius = .2f; // Radius of the overlap circle to determine if grounded
private bool m_Grounded; // Whether or not the player is grounded.
const float k_CeilingRadius = .2f; // Radius of the overlap circle to determine if the player can stand up
private Rigidbody2D m_Rigidbody2D;
private bool m_FacingRight = true; // For determining which way the player is currently facing.
private Vector3 m_Velocity = Vector3.zero;
[Header("Events")]
[Space]
public UnityEvent OnLandEvent;
[System.Serializable]
public class BoolEvent : UnityEvent<bool> { }
public BoolEvent OnCrouchEvent;
private bool m_wasCrouching = false;
private void Awake()
{
m_Rigidbody2D = GetComponent<Rigidbody2D>();
if (OnLandEvent == null)
OnLandEvent = new UnityEvent();
if (OnCrouchEvent == null)
OnCrouchEvent = new BoolEvent();
}
private void FixedUpdate()
{
bool wasGrounded = m_Grounded;
m_Grounded = false;
// The player is grounded if a circlecast to the groundcheck position hits anything designated as ground
// This can be done using layers instead but Sample Assets will not overwrite your project settings.
Collider2D[] colliders = Physics2D.OverlapCircleAll(m_GroundCheck.position, k_GroundedRadius, m_WhatIsGround);
for (int i = 0; i < colliders.Length; i++)
{
if (colliders[i].gameObject != gameObject)
{
m_Grounded = true;
if (!wasGrounded)
OnLandEvent.Invoke();
}
}
}
public void Move(float move, bool crouch, bool jump)
{
// If crouching, check to see if the character can stand up
if (!crouch)
{
// If the character has a ceiling preventing them from standing up, keep them crouching
if (Physics2D.OverlapCircle(m_CeilingCheck.position, k_CeilingRadius, m_WhatIsGround))
{
crouch = true;
}
}
//only control the player if grounded or airControl is turned on
if (m_Grounded || m_AirControl)
{
// If crouching
if (crouch)
{
if (!m_wasCrouching)
{
m_wasCrouching = true;
OnCrouchEvent.Invoke(true);
}
// Reduce the speed by the crouchSpeed multiplier
move *= m_CrouchSpeed;
// Disable one of the colliders when crouching
if (m_CrouchDisableCollider != null)
m_CrouchDisableCollider.enabled = false;
}
else
{
// Enable the collider when not crouching
if (m_CrouchDisableCollider != null)
m_CrouchDisableCollider.enabled = true;
if (m_wasCrouching)
{
m_wasCrouching = false;
OnCrouchEvent.Invoke(false);
}
}
// Move the character by finding the target velocity
Vector3 targetVelocity = new Vector2(move * 10f, m_Rigidbody2D.velocity.y);
// And then smoothing it out and applying it to the character
m_Rigidbody2D.velocity = Vector3.SmoothDamp(m_Rigidbody2D.velocity, targetVelocity, ref m_Velocity, m_MovementSmoothing);
// If the input is moving the player right and the player is facing left...
if (move > 0 && !m_FacingRight)
{
// ... flip the player.
Flip();
}
// Otherwise if the input is moving the player left and the player is facing right...
else if (move < 0 && m_FacingRight)
{
// ... flip the player.
Flip();
}
}
// If the player should jump...
if (m_Grounded && jump)
{
// Add a vertical force to the player.
m_Grounded = false;
m_Rigidbody2D.AddForce(new Vector2(0f, m_JumpForce));
}
}
private void Flip()
{
// Switch the way the player is labelled as facing.
m_FacingRight = !m_FacingRight;
// Multiply the player's x local scale by -1.
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
}
And here is the actual Character Movement Code -
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public CharacterController2D controller;
public float runSpeed = 40f;
float horizontalMove = 0f;
bool jump = false;
private void Update()
{
horizontalMove = Input.GetAxisRaw("Horizontal") * runSpeed;
if(Input.GetButtonDown("Jump"))
{
jump = true;
}
}
private void FixedUpdate()
{
controller.Move(horizontalMove * Time.fixedDeltaTime, false, jump);
jump = false;
}
}
Maybe the movement on android device is too small to be noticed. Try multiplying speed to delta time and then tweak the speed value to reach your desired movement speed.
rb2d.velocity = new Vector2(direction.x , direction.y) * speed * Time.deltaTime;
Make sure the script is attached to the game object with Rigidbody2D component. Also if your computer doesn't support touch, you can use mouse input to have the same result on computer and mobile device.
if (Input.GetMouseButtonUp(0))
{
rb2d.velocity = Vector2.zero;
}
else if (Input.GetMouseButton(0))
{
touchPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
touchPosition.z = 0;
direction = (touchPosition - transform.position);
rb2d.velocity = new Vector2(direction.x, direction.y) * speed * Time.deltaTime;
}
This code is also works on mobile devices.
Try adding Time.deltaTime or increasing the force with Time.deltaTime.
I am making a 2D platfomer and I am using screen space-camera render mode in canvas. Now the background fits inside the screen in every aspect ratio perfectly. But when I make the camera follow the character, the background also comes with it, making the character look like it is not moving.
Code for player movement:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
private Rigidbody2D myRigidbody;
[SerializeField]
private float movementSpeed;
// Use this for initialization
void Start ()
{
myRigidbody = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void FixedUpdate ()
{
float horizontal = Input.GetAxis ("Horizontal");
HandleMovement(horizontal);
}
private void HandleMovement(float horizontal)
{
myRigidbody.velocity = new Vector2 (horizontal * movementSpeed, myRigidbody.velocity.y);
}
}
Here is the camera follow code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraFollow : MonoBehaviour
{
public Transform target;
Vector3 velocity = Vector3.zero;
public float smoothTime = 0.15f;
public bool YMaxEnabled = false;
public float YMaxValue = 0;
public bool YMinEnabled = false;
public float YMinValue = 0;
public bool XMaxEnabled = false;
public float XMaxValue = 0;
public bool XMinEnabled = false;
public float XMinValue = 0;
void FixedUpdate()
{
Vector3 targetPos = target.position;
//vertical
if (YMinEnabled && YMaxEnabled)
{
targetPos.y = Mathf.Clamp (target.position.y, YMinValue, YMaxValue);
}
else if (YMinEnabled)
{
targetPos.y = Mathf.Clamp (target.position.y, YMinValue, target.position.y);
}
else if (YMaxEnabled)
{
targetPos.y = Mathf.Clamp (target.position.y, target.position.y, YMaxValue);
}
//horizontal
if (XMinEnabled && XMaxEnabled)
{
targetPos.x = Mathf.Clamp (target.position.x, XMinValue, XMaxValue);
}
else if (YMinEnabled)
{
targetPos.x = Mathf.Clamp (target.position.x, XMinValue, target.position.x);
}
else if (YMaxEnabled)
{
targetPos.x = Mathf.Clamp (target.position.x, target.position.x, XMaxValue);
}
targetPos.z = transform.position.z;
transform.position = Vector3.SmoothDamp (transform.position, targetPos, ref velocity, smoothTime);
}
}
If you use screen space camera, then the Canvas will move with the camera. I would suggest using Sprite Renderer instead of Canvas panel for level background. If you need to scale the Sprite according to screen, do it from the code. Also, for scrolling the background, you can follow this tutorial:
https://unity3d.com/learn/tutorials/topics/2d-game-creation/2d-scrolling-backgrounds
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?