Unity3D Character Controller set speed through script? - unity3d

How would I be able to set the speed for going forward and back in the Void FixedUpdate? Or is there a better way for doing this? I need to use the character controller though.
using UnityEngine;
using System.Collections;
public class CharacterControllerz : MonoBehaviour {
public float speed;
private CharacterController playerController;
void Start()
{
playerController = GetComponent<CharacterController>();
}
void Update()
{
}
void FixedUpdate()
{
if (Input.GetKey("right"))
{
playerController.Move (Vector3.forward);
Debug.Log ("RIGHT");
}
if (Input.GetKey("left"))
{
playerController.Move (Vector3.back);
Debug.Log ("LEFT");
}
playerController.Move (Vector3.left);
}
}

public float speed = 5f;
public float jumpStrenght = 8f;
public float gravity = 20f;
private Vector3 moveDirections = new Vector3();
private Vector3 inputs = new Vector3();
void FixedUpdate()
{
CharacterController cc = GetComponent<CharacterController>();
if (cc.isGrounded)
{
if (Input.GetKey("right"))
inputs.z = 1;
if (Input.GetKey("left"))
inputs.z = -1;
if (Input.GetKey("up"))
inputs.y = jumpStrenght;
moveDirections = transform.TransformDirection(inputs.x, 0, inputs.z) * speed;
}
moveDirections.y = inputs.y - gravity;
cc.Move(moveDirections * Time.deltaTime);
}
I think that's what you want but you may have to switch the axis.
Edit: Why is TransformDirection used? Because we want to move the object in a direction which shouldn't be relativ to the object's rotation.

Related

Unity Physics2D.OverlapBox is always returning true

I am trying to do ground detection for a 2d platformer, but my physics check is always returning true. I am reusing code that I have used a many times before:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
[Header("MOVEMENT")]
public float speed;
float inputX;
[Header("JUMPING")]
public float jumpForce;
public Transform feet;
public Vector2 checkSize;
public bool isGrounded;
public LayerMask layers;
public int extraJumps = 1;
int jumpTracker;
private Rigidbody2D rb;
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
inputX = Input.GetAxisRaw("Horizontal");
isGrounded = Physics2D.OverlapBox(feet.position, checkSize, 0f, layers);
if(Input.GetKeyDown(KeyCode.Space))
{
if (isGrounded)
{
rb.velocity = new Vector2(rb.velocity.x, jumpForce);
jumpTracker = extraJumps;
}
else
{
if(jumpTracker > 0)
{
rb.velocity = new Vector2(rb.velocity.x, jumpForce);
jumpTracker--;
}
}
}
}
private void FixedUpdate()
{
rb.velocity = new Vector2(inputX * speed, rb.velocity.y);
}
private void OnDrawGizmos()
{
Gizmos.DrawWireCube(feet.position, checkSize);
}
}
In the scene there is a Tilemap with a composite collider tagged as ground that the player is colliding with.
I have tried everything I can think of and still have no idea what is causing this issue. Any help would be greatly appreciated.

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

The character freezes near the wall unity3d

Please tell me, when I move the character with the joystick, the character will get stuck in a regular wall. What could be the problem?
Below is a video demonstration.
When moving with the buttons, the character does not get stuck.
https://www.youtube.com/watch?v=9SiQzLAq-kU
Thanks in advance)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MovePersonal : MonoBehaviour
{
public float speedMove;
public float jumpPower;
private float gravityForce;
private Vector3 moveVector;
private CharacterController ch_controller;
private Animator ch_animator;
private MobileController mContr;
// Start is called before the first frame update
private void Start()
{
ch_controller = GetComponent<CharacterController>();
ch_animator = GetComponent<Animator>();
mContr = GameObject.FindGameObjectWithTag("joy").GetComponent<MobileController>();
}
// Update is called once per frame
private void Update()
{
CharacterMove();
GamingGravity();
}
private void CharacterMove() {
if (ch_controller.isGrounded) {
moveVector = Vector3.zero;
moveVector.x = mContr.Horizontal() * speedMove;
moveVector.z = mContr.Vertical() * speedMove;
if(Vector3.Angle(Vector3.forward, moveVector)>1f || Vector3.Angle(Vector3.forward, moveVector) == 0) {
Vector3 direct = Vector3.RotateTowards(transform.forward, moveVector, speedMove, 0.0f);
transform.rotation = Quaternion.LookRotation(direct);
}
}
else {
}
moveVector.y = gravityForce;
ch_controller.Move(moveVector * Time.deltaTime);
}
private void GamingGravity() {
if (!ch_controller.isGrounded) gravityForce -=20f * Time.deltaTime;
else gravityForce = -1f;
if(Input.GetKeyDown(KeyCode.Space) && ch_controller.isGrounded) gravityForce = jumpPower;
}
}

How to remove sticking to the edges of the platform in Unity3d?

I'd like to know how I can get rid of wall sticking in my movement code. I believe the reason is that I implemented it via AddForce, however, I don't know how to fix it. I will be grateful for any help.
Attaching the code:
public class PlayerMovement : MonoBehaviour
{
[Header("Movement")]
public float moveSpeed;
public float walkSpeed;
public float sprintSpeed;
public float groundDrag;
public float jumpForce;
public float jumpCooldown;
public float airMultiplier;
[Header("Keybinds")]
public KeyCode sprintKey = KeyCode.LeftShift;
[Header("Ground Check")]
public float playerHeight;
public LayerMask whatIsGround;
bool grounded;
public Transform orientation;
float horizontalInput;
float verticalInput;
Vector3 moveDirection;
Rigidbody rb;
public MovementState state;
public enum MovementState
{
walking,
sprinting,
air
}
private void Start()
{
rb = GetComponent<Rigidbody>();
rb.freezeRotation = true;
}
private void Update()
{
grounded = Physics.Raycast(transform.position, Vector3.down, playerHeight * 0.5f + 0.2f, whatIsGround);
MyInput();
SpeedControl();
StateHandler();
if (grounded)
rb.drag = groundDrag;
else
rb.drag = 0;
}
private void FixedUpdate()
{
MovePlayer();
}
private void MyInput()
{
horizontalInput = Input.GetAxisRaw("Horizontal");
verticalInput = Input.GetAxisRaw("Vertical");
}
private void StateHandler()
{
if(grounded && Input.GetKey(sprintKey))
{
state = MovementState.sprinting;
moveSpeed = sprintSpeed;
}
else if (grounded)
{
state = MovementState.walking;
moveSpeed = walkSpeed;
}
else
{
state = MovementState.air;
}
}
void MovePlayer()
{
moveDirection = orientation.forward * verticalInput + orientation.right * horizontalInput;
if(grounded)
rb.AddForce(moveDirection.normalized * moveSpeed * 10f, ForceMode.Force);
else if(!grounded)
rb.AddForce(moveDirection.normalized * moveSpeed * 10f * airMultiplier, ForceMode.Force);
}
private void SpeedControl()
{
Vector3 flatVel = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
if(flatVel.magnitude > moveSpeed)
{
Vector3 limitedVel = flatVel.normalized * moveSpeed;
rb.velocity = new Vector3(limitedVel.x, rb.velocity.y, limitedVel.z);
}
}
}
I left the sprint in the code, because, perhaps, he also looked at something
Addition:
The error occurs when I walk facing the wall (W). If I change direction, then the walk goes fine. I would like to change it to something like sliding like in most games
Ad:
I mean -
enter image description here
The solution is to set the Friction Combine value to Minimum when using the Physic Material

Problem with my object that does not stop moving

I made a script for moving an object to the position indicated by the mouse click. If I don't choose to click to another location to move towards, I would like to stop my object if it reaches the previously mentioned position. However, the object doesn't stop when reaching the position and it continues moving.
Here is the code I wrote. I would be grateful if somebody knows how to fix this issue.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float moveSpeed;
private Vector3 targetPos;
private Rigidbody2D rb;
private bool isMoving;
private Vector2 direction;
public float changeDirCooldown;
private float changeCool;
private bool canChangeDir;
void Start()
{
rb = GetComponent<Rigidbody2D>();
changeCool=changeDirCooldown;
canChangeDir =true;
}
void Update()
{
if (Input.GetMouseButton(0) && canChangeDir)
{
changeDirCooldown = changeCool;
SetTargetPosition();
}
if (changeDirCooldown<=0)
{
canChangeDir = true;
}
else
{
changeDirCooldown -= Time.deltaTime;
}
}
private void FixedUpdate()
{
if (isMoving)
{
Move();
}
if (this.transform.position == this.targetPos)
{
isMoving = false;
rb.velocity = Vector2.zero;
}
}
private void SetTargetPosition()
{
targetPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
targetPos.z = transform.position.z;
direction = targetPos - this.transform.position;
direction = direction.normalized;
isMoving = true;
}
private void Move()
{
rb.velocity = direction * moveSpeed;
canChangeDir = false;
}
}
It's probabily a problem with float number tolerance. This line
this.transform.position == this.targetPos
will almost never result to true, so instead you should do something like this:
Mathf.Abs(this.transform.position.x - this.targetPos.x) < float.Epsilon &&
Mathf.Abs(this.transform.position.y - this.targetPos.y) < float.Epsilon