How to addforce to mouse location with a player movement script? - unity3d

I have two codes that both work fine by themselves but they don't work together. One code moves the player up, down, left, right. The other code rotates the sprite and will launch the sprite facing the direction of the mouse. I can not get both of these codes to work at the same time. Please could use some help.
1st Script is Movement
public float moveSpeed;
private Rigidbody2D rb;
private Vector2 moveVelocity;
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
Vector2 moveInput = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
moveVelocity = moveInput.normalized * moveSpeed;
}
void FixedUpdate()
{
rb.MovePosition(rb.position + moveVelocity * Time.deltaTime);
}
2nd Script is Launching
// Movement
public float thrust = 10f;
public Rigidbody2D rb;
//Aiming
public Camera cam;
Vector2 mousePos;
void Update()
{
//aiming
mousePos = cam.ScreenToWorldPoint(Input.mousePosition);
}
void FixedUpdate()
{
Move();
//aim
Vector2 lookDirection = mousePos - rb.position;
float angle = Mathf.Atan2(lookDirection.y, lookDirection.x) * Mathf.Rad2Deg;
rb.rotation = angle;
}
void Move()
{
if (Input.GetMouseButtonDown(0))
{
rb.AddRelativeForce(Vector2.right * thrust, ForceMode2D.Impulse);
}
}

Related

Jump like teleporting

I'm working on unity and am trying to give my player character a jump button however when he jump he teleport up not jumping
private float speed = 10f;
private bool canjump = false;
private Rigidbody rb;
private float jump =100f;
private float movementX;
private float movementy;
public bool isJumping;
private float jumpdecay =20f;
public float fallmultipler = 2.5f;
public float lowjumpmultiplier = 2f;
void Start()
{
rb = GetComponent<Rigidbody>();
}
private void OnMove(InputValue movementValue)
{
Vector2 movementVector = movementValue.Get();
movementX = movementVector.x;
}
private void Update()
{
Vector3 movement = new Vector2(movementX, 0);
rb.velocity = movement * speed;
if (Input.GetKeyDown(KeyCode.Space))
{
canjump = true;
}
}
void OnTriggerEnter(Collider collision)
{
if(collision.gameObject.tag == "ground")
{
isJumping = false;
}
}
void OnTriggerExit(Collider collision)
{
isJumping = true;
}
private void FixedUpdate()
{
if (canjump & isJumping == false)
{
rb.velocity = Vector3.up * jump;
canjump = false;
}
}
It's happen because on Update you change your velocity including the y and then every frame your y axis of the velocity vector become 0.
to fix that you should save your y and replace after modify your velocity.
change inside your code in the update method this:
Vector3 movement = new Vector2(movementX, 0);
rb.velocity = movement * speed;
with this:
Vector3 movement = new Vector2(movementX, 0);
float currentVelocity = rb.velocity.y;
rb.velocity = movement * speed;
rb.velocity = new Vector3(rb.velocity.x, currentVelocity, rb.velocity.z);
if it's help you, please mark this answer as the good answer, if not please let me know and I will help you.
You are reseting the y velocity inside of update
Vector3 movement = new Vector2(movementX, 0);
rb.velocity = movement * speed;
Try someting like
rb.velocity = new Vector2(movementX * speed, rb.velocity.y)
rb.velocity.y returns current y velocity, because of that said velocity remains unchanged, allowing for the jump to work normally

Why is my character falling/leaning over on mouse click in unity?

My character using CharacterController seems to be falling over! Is it the rotation that's the issue? I've been hitting my head against the wall for a few days trying to get this solved. any thoughts?
an small vid of what's happening: https://imgur.com/a/AyPvLtm
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
[RequireComponent(typeof(CharacterController))]
public class Player : MonoBehaviour
{
[SerializeField] private float playerSpeed = 10f;
[SerializeField] private float rotationSpeed = 8f;
public float SpeedChangeRate = 10.0f;
private Camera mainCamera;
private Vector3 targetPosition;
private CharacterController characterController;
private Coroutine coroutine;
private int groundLayer;
private void Awake() {
mainCamera = Camera.main;
characterController = GetComponent<CharacterController>();
groundLayer = LayerMask.NameToLayer("Ground");
}
void Update()
{
if (Mouse.current.leftButton.isPressed) Move();
}
private void Move() {
Ray ray = mainCamera.ScreenPointToRay(Mouse.current.position.ReadValue());
Physics.Raycast(ray: ray, hitInfo: out RaycastHit hit);
if (hit.collider && hit.collider.gameObject.layer.CompareTo(groundLayer) == 0) {
if (coroutine != null) StopCoroutine(coroutine);
coroutine = StartCoroutine(PlayerMoveTowards(hit.point));
targetPosition = hit.point;
}
}
private IEnumerator PlayerMoveTowards(Vector3 target) {
while (Vector3.Distance(transform.position, target) > 0.1f) {
Vector3 destination = Vector3.MoveTowards(transform.position, target, playerSpeed * Time.deltaTime);
Vector3 direction = target - transform.position;
Vector3 movement = direction.normalized * playerSpeed * Time.deltaTime;
characterController.Move(movement);
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction.normalized), rotationSpeed * Time.deltaTime);
yield return null;
}
}
}
The reason is that at close distances, the difference between the main player's Target and Pivot point becomes very small and the height will be effective in determining the direction. Just set the direction Y to 0 to solve the problem.
Vector3 direction = target - transform.position;
direction.y = 0;
Figured this out.
It was my capsule collider. I had it set to the X-Axis, causing the collider to be rotated 90 degrees.
So my character would move and then flip to the side. Updating the collider direct to be on the Y-Axis fixed the problem.

Camera keeps rotating

I am trying to make a first-person game in Unity but I keep having issues with my character controller. The player keeps rotating when it collides with objects that have physics (Or rigidbody)
It doesn't rotate when it collides with objects that don't have physics.
It's not my mouse because my MouseX and Y Values aren't changing.
Here is the code for the Player
using System.Collections.Generic;
using UnityEngine;
using Unity.Netcode;
public class PlayerControllerRB : MonoBehaviour
{
public float speed = 10f;
public float jumpHeight = 4.65f;
[SerializeField] private Rigidbody rb;
private PlayerInput playerInput;
private PlayerInput.OnFootActions onFoot;
[SerializeField] private Camera cam;
public float xSensitivity = 8f;
public float ySensitivity = 8f;
private float xRotation;
private float yMovement;
private float hMovement;
[SerializeField] private Transform Feet;
[SerializeField] public LayerMask Ground;
private void Awake()
{
rb = GetComponent<Rigidbody>();
playerInput = new PlayerInput();
onFoot = playerInput.onFoot;
onFoot.Jump.performed += ctx => Jump();
}
private void Start()
{
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
#region
private void OnEnable()
{
playerInput.Enable();
onFoot.Enable();
}
private void OnDisable()
{
playerInput.Disable();
onFoot.Disable();
}
#endregion
private void FixedUpdate()
{
ProcessMove(onFoot.Movement.ReadValue<Vector2>());
}
private void Update()
{
ProcessLook(onFoot.Look.ReadValue<Vector2>());
}
void ProcessMove(Vector2 input)
{
Vector3 MoveDirection = Vector3.zero;
hMovement = input.x;
yMovement = input.y;
MoveDirection = transform.forward * yMovement + transform.right * hMovement;
//MoveDirection.y = rb.velocity.y;
Debug.Log(MoveDirection * speed);
rb.AddForce(MoveDirection * speed, ForceMode.Acceleration);
}
void Jump()
{
Ray ray = new Ray(Feet.position, Vector3.down);
RaycastHit info;
if(Physics.Raycast(ray, out info, 0.3f, Ground))
{
rb.AddForce(Vector3.up * jumpHeight, ForceMode.Impulse);
}
}
void ProcessLook(Vector2 input)
{
float MouseY = input.y;
float MouseX = input.x;
xRotation -= (MouseY * Time.deltaTime) * ySensitivity;
xRotation = Mathf.Clamp(xRotation, -80f, 80f);
cam.transform.localRotation = Quaternion.Euler(xRotation, 0, 0);
transform.Rotate(Vector3.up * (MouseX * Time.deltaTime) * xSensitivity);
}
}
I tried freezing the y rotation but then I get a jittry camera.
Can anyone help me? It would also be nice if you had any recommendations to improve the controller.
Please comment if you need any more information. Sorry if the post is junk, I'm new to Stackoverflow
Well, you said It doesn't rotate when it collides with objects that don't have physics. In order to use the colliders one of them has to have a rigibody component. So if that's the case maybe is the script that is inside the oncollisionenter causing the problems. But I don't see any oncollisionenter script here

cinemachine makes my camera movement laggy in unity

I'm curently using cinemachine to make a third person camera. My player's movements work and i wanted him to look in the direction he is moving but taking in consideration the rotation of the camera. It works when i don't move the camera while moving the player but when i move the camera the rotations of my player are laggy moreover every movement of my camera seems to be laggy too. Sorry for my english i hope it's clear here is my code :
public class ThirdPersonScript : MonoBehaviour
{
[SerializeField] private float speed;
[SerializeField] private float jumpForce;
[SerializeField] private Transform feet;
[SerializeField] private LayerMask floorMask;
[SerializeField] private Transform cam;
private Vector3 direction;
private Rigidbody rb;
private bool canJump;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
direction = new Vector3(Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical"));
direction = Quaternion.AngleAxis(cam.rotation.eulerAngles.y, Vector3.up) * direction;
if (direction.magnitude > 1.0f)
{
direction = direction.normalized;
}
direction *= speed;
canJump = Input.GetKeyDown(KeyCode.Space) ? true : false;
}
void FixedUpdate()
{
if (Physics.CheckSphere(feet.position, 0.1f, floorMask))
{
if (canJump)
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
else
rb.velocity = new Vector3(direction.x, 0, direction.z);
}
else
rb.velocity = new Vector3(direction.x, rb.velocity.y, direction.z);
if (direction != Vector3.zero)
{
Quaternion targetRotation = Quaternion.LookRotation(direction);
targetRotation = Quaternion.RotateTowards(transform.rotation, targetRotation, 1080*Time.fixedDeltaTime);
rb.MoveRotation(targetRotation);
}
}
}
and a screenshot of my cinemachine settings and my hierarchy :
Try change the direction in LateUpdate() but not Update() :
void LateUpdate()
{
direction = new Vector3(Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical"));
direction = Quaternion.AngleAxis(cam.rotation.eulerAngles.y, Vector3.up) * direction;
if (direction.magnitude > 1.0f)
{
direction = direction.normalized;
}
direction *= speed;
canJump = Input.GetKeyDown(KeyCode.Space) ? true : false;
}
LateUpdate is called after all Update functions have been called. This is useful to order script execution. For example a follow camera should always be implemented in LateUpdate because it tracks objects that might have moved inside Update.
https://docs.unity3d.com/ScriptReference/MonoBehaviour.LateUpdate.html

Stop an Object if it reached the transform value

So I have a 2d gameObject that behaves likes a spike trap that springs out of the ground when the character collides on the trigger. I use AddForce to the rigidbody 2D of the gameObject to manipulates its speed when coming out of the ground and I want it to just sticking out of the ground. How can I stop it when it reaches a certain tranform Y value.
Here is my code:
public float speed;
Rigidbody2D rb;
void Start () {
rb = GetComponent<Rigidbody2D>();
}
void Update () {
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.tag == "Player")
{
rb.AddForce(new Vector2(0, speed * Time.time), ForceMode2D.Impulse);
}
}
Certain transform value, or certain transform.position value?
I'll do it like this:
private float threshold = 10f;
private float startPosition = 0;
private RigidBody2D pikeRigidbody;:
private void Start()
{
startPosition = = this.transform.position;
pikeRigidbody = this.GetComponent<RigidBody2D>();
}
private void Update(){
if(this.transform.position.y >= (startPosition.y + threshold))
{
pikeRigidbody.velocity = Vector3.zero;
}
}
And attach the script to the pike object.
Edited to position.y instead of position